PluginProbe
Hostinger Tools / 3.0.79
Hostinger Tools v3.0.79
3.0.79 3.0.78 3.0.77 3.0.76 3.0.75 3.0.74 3.0.73 3.0.72 3.0.71 3.0.70 3.0.69 3.0.68 3.0.67 3.0.66 1.8.1 1.8.2 1.8.3 1.9.1 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 All 110 releases
hostinger / vue-frontend / src / views / HostingerTools.vue

HostingerTools.vue in Hostinger Tools 3.0.79, at vue-frontend/src/views/HostingerTools.vue

520 lines 13.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <script lang="ts" setup>
2 import { storeToRefs } from "pinia";
3 import { computed, ref } from "vue";
4
5 import Button from "@/components/Button/Button.vue";
6 import SectionCard from "@/components/HostingerTools/SectionCard.vue";
7 import ToolVersionCard from "@/components/HostingerTools/ToolVersionCard.vue";
8 import Icon from "@/components/Icon/Icon.vue";
9 import { useModal } from "@/composables";
10 import { useGeneralStoreData, useSettingsStore } from "@/stores";
11 import {
12 ModalName,
13 SectionItem,
14 ToggleableSettingsData
15 } from "@/types";
16 import { SECTION_ID } from "@/types/models/components/sectionCardModels";
17 import {
18 getAssetSource,
19 getBaseUrl,
20 isNewerVerison,
21 kebabToCamel,
22 translate
23 } from "@/utils/helpers";
24 import {toast} from "vue3-toastify";
25
26 const { fetchSettingsData, updateSettingsData, regenerateByPassCode, clearCache } =
27 useSettingsStore();
28
29 const { settingsData } = storeToRefs(useSettingsStore());
30 const {
31 siteUrl,
32 llmstxtFileUrl,
33 llmstxtFileUserGenerated
34 } = useGeneralStoreData();
35
36 const WORDPRESS_UPDATE_LINK = getBaseUrl(location.href) + "update-core.php";
37
38 const isPageLoading = ref(false);
39
40 const HOSTINGER_FREE_DOMAINS = /hostingersite\.com|hostinger\.dev/;
41
42 const llmMasterToggle = ref(false);
43
44 const isClearingCache = ref(false);
45
46 const isLLMSSectionDisabled = computed(
47 () => isFreeDomain.value || !isHostingerPlatform.value
48 );
49
50 const maintenanceSection = computed(() => [
51 {
52 id: SECTION_ID.MAINTENANCE_MODE,
53 title: translate("hostinger_tools_maintenance_mode"),
54 description: translate("hostinger_tools_disable_public_access"),
55 isVisible: true,
56 toggleValue: settingsData.value?.maintenanceMode
57 },
58 {
59 id: SECTION_ID.BYPASS_LINK,
60 title: translate("hostinger_tools_bypass_link"),
61 description: translate("hostinger_tools_skip_link_maintenance_mode"),
62 isVisible: true,
63 sideButton: {
64 text: translate("hostinger_tools_reset_link"),
65 onClick: () => {
66 openModal(
67 ModalName.ByPassLinkResetModal,
68 {
69 data: {
70 onConfirm: () => regenerateByPassCode()
71 }
72 },
73 { isLG: true }
74 );
75 }
76 },
77 copyLink: settingsData.value?.bypassCode
78 ? `${siteUrl}/?bypass_code=${settingsData.value.bypassCode}`
79 : undefined
80 }
81 ]);
82
83 const isCacheSectionDisabled = computed(() => !isHostingerPlatform.value);
84
85 const performanceSection = computed(() => [
86 {
87 id: SECTION_ID.CLEAR_CACHE,
88 title: translate("hostinger_tools_clear_cache"),
89 description: translate("hostinger_tools_clear_cache_description"),
90 isVisible: true,
91 sideButton: {
92 text: translate("hostinger_tools_clear_cache_cta"),
93 isLoading: isClearingCache.value,
94 isDisabled: isCacheSectionDisabled.value,
95 onClick: onClearCache
96 }
97 }
98 ]);
99
100 const securitySection = computed(() =>
101 [
102 {
103 id: SECTION_ID.DISABLE_XML_RPC,
104 title: translate("hostinger_tools_disable_xml_rpc"),
105 description: translate("hostinger_tools_xml_rpc_description"),
106 isVisible: true,
107 toggleValue: settingsData.value?.disableXmlRpc
108 },
109 {
110 id: SECTION_ID.DISABLE_AUTHENTICATION_PASSWORD,
111 title: translate("hostinger_tools_disable_authentication_password"),
112 description: translate(
113 "hostinger_tools_authentication_password_description"
114 ),
115 isVisible: true,
116 toggleValue: settingsData.value?.disableAuthenticationPassword
117 }
118 ].filter((item) => item.isVisible)
119 );
120
121 const redirectsSection = computed(() => {
122 const allItems = [
123 {
124 id: SECTION_ID.FORCE_HTTPS,
125 title: translate("hostinger_tools_force_https"),
126 description: translate("hostinger_tools_force_https_description"),
127 isVisible: true,
128 toggleValue: settingsData.value?.forceHttps
129 },
130 {
131 id: SECTION_ID.FORCE_WWW,
132 title: translate("hostinger_tools_force_www"),
133 description: !settingsData.value?.isEligibleWwwRedirect
134 ? translate(
135 "hostinger_tools_force_www_description_not_available"
136 )
137 : translate("hostinger_tools_force_www_description"),
138 isVisible: !!settingsData.value?.isEligibleWwwRedirect,
139 toggleValue: settingsData.value?.forceWww
140 }
141 ];
142
143 return allItems.filter((item) => item.isVisible);
144 });
145
146 const llmsSection = computed(() => {
147 const allItems = [
148 {
149 id: SECTION_ID.ENABLE_LLMS_TXT,
150 title: translate("hostinger_tools_enable_llms_txt"),
151 description: translate("hostinger_tools_llms_txt_description"),
152 isVisible: true,
153 toggleValue: settingsData.value?.enableLlmsTxt,
154 learnMoreLink: "https://www.hostinger.com/support/how-to-enable-llms-txt-on-your-website/",
155 sideButtons: [
156 {
157 id: "hostinger_tools_llms_txt_llmstxt",
158 text: translate("hostinger_tools_llms_txt_llmstxt"),
159 isDisabled: !settingsData.value?.enableLlmsTxt,
160 to:
161 settingsData.value?.enableLlmsTxt &&
162 llmMasterToggle.value
163 ? llmstxtFileUrl
164 : undefined,
165 variant: "outline" as const
166 },
167 {
168 id: "hostinger_tools_llms_txt_check_validity",
169 text: translate("hostinger_tools_llms_txt_check_validity"),
170 isDisabled: !settingsData.value?.enableLlmsTxt,
171 to:
172 settingsData.value?.enableLlmsTxt &&
173 llmMasterToggle.value
174 ? `https://llmstxtvalidator.org/?url=${llmstxtFileUrl}`
175 : undefined,
176 variant: "outline" as const
177 }
178 ]
179 },
180 {
181 id: SECTION_ID.OPTIN_MCP,
182 title: translate("hostinger_tools_optin_mcp"),
183 description: translate("hostinger_tools_optin_mcp_description"),
184 isVisible: true,
185 toggleValue: settingsData.value?.optinMcp,
186 learnMoreLink:
187 "https://support.hostinger.com/en/articles/11729400-ai-agent-access-smart-ai-discovery",
188 sideButtons: [{
189 id: "hostinger_tools_optin_mcp_copy_agent_url",
190 text: translate("hostinger_tools_copy_agent_url"),
191 isDisabled: !settingsData.value?.optinMcp,
192 onClick: copyAgentUrl,
193 variant: "outline" as const
194 }],
195 }
196 ];
197
198 return allItems.filter((item) => item.isVisible);
199 });
200
201 const llmsSectionHeaderToggle = computed(() => {
202 const visibleItems = llmsSection.value.filter((item) => item.isVisible);
203 if (visibleItems.length <= 1) return undefined;
204
205 return {
206 value: llmMasterToggle.value,
207 onToggle: async (value: boolean) => {
208 llmMasterToggle.value = value;
209
210 if (!settingsData.value) return;
211
212 const updatedSettings = {
213 ...settingsData.value,
214 enableLlmsTxt: value,
215 optinMcp: value
216 };
217
218 const success = await updateSettingsData(updatedSettings);
219
220 if (success && settingsData.value) {
221 settingsData.value.enableLlmsTxt = value;
222 settingsData.value.optinMcp = value;
223 }
224 }
225 };
226 });
227
228 const { openModal } = useModal();
229
230 const isWordPressUpdateDisplayed = computed(() => {
231 if (!settingsData.value) {
232 return false;
233 }
234
235 return isNewerVerison({
236 currentVersion: settingsData.value.currentWpVersion,
237 newVersion: settingsData.value.newestWpVersion
238 });
239 });
240
241 const isPhpUpdateDisplayed = computed(() => {
242 if (!settingsData.value) {
243 return false;
244 }
245
246 return isNewerVerison({
247 currentVersion: settingsData.value.phpVersion,
248 newVersion: "8.2" // Hardcoded for now
249 });
250 });
251
252 const isHostingerPlatform = computed(
253 () => parseInt(hostinger_tools_data.hplatform) > 0
254 );
255
256 const isFreeDomain = computed(() =>
257 HOSTINGER_FREE_DOMAINS.test(String(siteUrl))
258 );
259
260 const createUpdateButton = (onClick: () => void) => ({
261 text: translate("hostinger_tools_update"),
262 onClick
263 });
264
265 const resellerLocale = computed(() => {
266 const { pluginUrl } = useGeneralStoreData();
267
268 return pluginUrl.match(/^[^/]+/)?.[0] || "hostinger.com";
269 });
270
271 const connectDomainUrl = computed(() => {
272 if (!isHostingerPlatform.value) return undefined;
273
274 const domain = location.host;
275
276 return `https://auth.${resellerLocale.value}/login?section=website-dashboard&domain=${domain}`;
277 });
278
279 const phpVersionCard = computed(() => ({
280 title: translate("hostinger_tools_php_version"),
281 toolImageSrc: getAssetSource("images/icons/icon-php.svg"),
282 version: settingsData.value?.phpVersion,
283 actionButton:
284 isHostingerPlatform.value && isPhpUpdateDisplayed.value
285 ? createUpdateButton(() => {
286 window.open(
287 `https://auth.${resellerLocale.value}/login?r=/section/php-configuration/domain/${location.host}`,
288 "_blank"
289 );
290 })
291 : undefined
292 }));
293
294 const wordPressVersionCard = computed(() => ({
295 title: translate("hostinger_tools_wordpress_version"),
296 toolImageSrc: getAssetSource("images/icons/icon-wordpress-light.svg"),
297 version: settingsData.value?.currentWpVersion,
298 actionButton: isWordPressUpdateDisplayed.value
299 ? createUpdateButton(() => {
300 window.location.href = WORDPRESS_UPDATE_LINK;
301 })
302 : undefined
303 }));
304
305 const onSaveSection = (value: boolean, item: SectionItem) => {
306 const isTurnedOn = value === false;
307
308 if (item.id === SECTION_ID.DISABLE_XML_RPC && isTurnedOn) {
309 openModal(
310 ModalName.XmlSecurityModal,
311 {
312 data: {
313 onConfirm: () => {
314 onUpdateSettings(value, item);
315 }
316 }
317 },
318 { isLG: true }
319 );
320
321 return;
322 }
323
324 onUpdateSettings(value, item);
325 };
326
327 const onSaveLLmsSection = async (isEnabled: boolean, item: SectionItem) => {
328 const updateSetting = async () => {
329 await onUpdateSettings(isEnabled, item);
330
331 // Update the master toggle state based on current settings
332 llmMasterToggle.value = !!(
333 settingsData.value?.enableLlmsTxt || settingsData.value?.optinMcp
334 );
335 };
336
337 if (
338 llmstxtFileUserGenerated &&
339 isEnabled &&
340 item.id === SECTION_ID.ENABLE_LLMS_TXT
341 ) {
342 openModal(
343 ModalName.EnableLlmsTxtModal,
344 {
345 data: {
346 onConfirm: () => {
347 updateSetting();
348 }
349 }
350 },
351 { isLG: true }
352 );
353
354 return;
355 }
356
357 await updateSetting();
358 };
359
360 const onUpdateSettings = async (value: boolean, item: SectionItem) => {
361 if (!settingsData.value) return;
362
363 const id = kebabToCamel(item.id) as keyof ToggleableSettingsData;
364
365 const updatedSettings = {
366 ...settingsData.value,
367 [id]: value
368 };
369
370 const success = await updateSettingsData(updatedSettings);
371
372 if (success && settingsData.value) {
373 settingsData.value[id] = value;
374 }
375 };
376
377 const onClearCache = async () => {
378 if (isClearingCache.value) return;
379
380 isClearingCache.value = true;
381 await clearCache();
382 isClearingCache.value = false;
383 };
384
385 const copyAgentUrl = () => {
386 const domain = location.host;
387 const agentUrl = `websites-agents.hostinger.com/${domain}/mcp`;
388 navigator.clipboard.writeText(agentUrl);
389 toast.success(translate("hostinger_tools_copied_successfully"));
390 };
391
392 (async () => {
393 isPageLoading.value = true;
394 await fetchSettingsData();
395 isPageLoading.value = false;
396
397 llmMasterToggle.value = !!(
398 settingsData.value?.enableLlmsTxt || settingsData.value?.optinMcp
399 );
400 })();
401 </script>
402
403 <template>
404 <div v-if="settingsData">
405 <div class="hostinger-tools__tool-version-cards">
406 <ToolVersionCard
407 :is-loading="isPageLoading"
408 v-bind="wordPressVersionCard"
409 class="h-mr-16"
410 />
411 <ToolVersionCard
412 :is-loading="isPageLoading"
413 v-bind="phpVersionCard"
414 />
415 </div>
416 <div>
417 <SectionCard
418 :is-loading="isPageLoading"
419 :title="translate('hostinger_tools_llms')"
420 :section-items="llmsSection"
421 :is-disabled="isLLMSSectionDisabled"
422 :header-toggle="llmsSectionHeaderToggle"
423 :warning="
424 !isLLMSSectionDisabled && llmstxtFileUserGenerated
425 ? translate(
426 'hostinger_tools_llms_txt_external_file_found',
427 )
428 : ''
429 "
430 @save-section="onSaveLLmsSection"
431 >
432 <template
433 v-if="isLLMSSectionDisabled"
434 #snackbar
435 >
436 <div
437 class="hostinger-notice d-flex align-items-center w-100 h-mb-16"
438 >
439 <Icon
440 name="icon-info"
441 color="gray-dark"
442 />
443 <p class="text-body-3">
444 {{
445 translate(
446 "hostinger_tools_free_domain_llm_unavailable",
447 )
448 }}
449 </p>
450 <Button
451 v-if="connectDomainUrl"
452 size="small"
453 variant="text"
454 color="primary"
455 class="h-ml-8"
456 :to="connectDomainUrl"
457 target="_blank"
458 >
459 {{
460 translate("hostinger_tools_connect_domain_cta")
461 }}
462 </Button>
463 </div>
464 </template>
465 </SectionCard>
466
467 <SectionCard
468 :is-loading="isPageLoading"
469 :title="translate('hostinger_tools_maintenance')"
470 :section-items="maintenanceSection"
471 @save-section="onSaveSection"
472 />
473
474 <SectionCard
475 :is-loading="isPageLoading"
476 :title="translate('hostinger_tools_security')"
477 :section-items="securitySection"
478 @save-section="onSaveSection"
479 />
480
481 <SectionCard
482 :is-loading="isPageLoading"
483 :title="translate('hostinger_tools_redirects')"
484 :section-items="redirectsSection"
485 @save-section="onSaveSection"
486 />
487
488 <SectionCard
489 :is-loading="isPageLoading"
490 :title="translate('hostinger_tools_performance')"
491 :section-items="performanceSection"
492 :is-disabled="isCacheSectionDisabled"
493 />
494 </div>
495 </div>
496 </template>
497
498 <style lang="scss">
499 .hostinger-tools {
500 &__tool-version-cards {
501 display: flex;
502 width: 100%;
503
504 @media (max-width: 590px) {
505 flex-direction: column;
506 }
507 }
508 }
509
510 .hostinger-notice {
511 background: var(--gray-light);
512 color: var(--gray-dark);
513 border: 1px solid var(--gray-border);
514 border-radius: 12px;
515 padding: 12px 16px;
516 font-size: var(--font-size-sm);
517 gap: 1em;
518 }
519 </style>
520