Style: Refactor logo paths and continue debugging site settings save/upload errors

This commit is contained in:
Zahirul Iman 2025-05-27 11:23:05 +08:00
parent 4913d345de
commit f0298accb3
9 changed files with 115 additions and 54 deletions

View File

@ -14,13 +14,13 @@ const refreshPage = () => {
const loadingLogoSrc = computed(() => { const loadingLogoSrc = computed(() => {
if (siteSettingsLoading.value) { if (siteSettingsLoading.value) {
return '/assets/img/logo/corradAF-logo.svg'; // Default fallback during loading state return '/img/logo/corradAF-logo.svg'; // Default fallback during loading state
} }
const logoUrl = siteSettings.value?.siteLoadingLogo; const logoUrl = siteSettings.value?.siteLoadingLogo;
if (logoUrl && logoUrl.trim() !== '') { if (logoUrl && logoUrl.trim() !== '') {
return logoUrl; // Use logo from settings if available and not empty return logoUrl; // Use logo from settings if available and not empty
} }
return '/assets/img/logo/corradAF-logo.svg'; // Ultimate fallback if no logo is set in settings return '/img/logo/corradAF-logo.svg'; // Ultimate fallback if no logo is set in settings
}); });
// Get site name with fallback // Get site name with fallback
@ -42,7 +42,7 @@ const getSiteName = () => {
:src="loadingLogoSrc" :src="loadingLogoSrc"
:alt="getSiteName()" :alt="getSiteName()"
class="max-w-[180px] max-h-[60px] object-contain" class="max-w-[180px] max-h-[60px] object-contain"
@error="$event.target.src = '/assets/img/logo/corradAF-logo.svg'" @error="$event.target.src = '/img/logo/corradAF-logo.svg'"
/> />
</div> </div>

View File

@ -73,9 +73,8 @@ onMounted(() => {
// Load site settings on mount and ensure they're properly populated // Load site settings on mount and ensure they're properly populated
const { loadSiteSettings } = useSiteSettings(); const { loadSiteSettings } = useSiteSettings();
loadSiteSettings().then(() => { loadSiteSettings().then(() => {
// Force reactivity update after loading
nextTick(() => { nextTick(() => {
console.log('Site settings loaded:', siteSettings.value); console.log('[Header.vue] Site settings loaded. Name:', siteSettings.value?.siteName, 'ShowInHeader:', siteSettings.value?.showSiteNameInHeader, 'Logo:', siteSettings.value?.siteLogo);
}); });
}); });
}); });
@ -86,7 +85,7 @@ const currentLogo = computed(() => {
if (logoUrl && logoUrl.trim() !== '') { if (logoUrl && logoUrl.trim() !== '') {
return logoUrl; // Use logo from settings if available and not empty return logoUrl; // Use logo from settings if available and not empty
} }
return '/assets/img/logo/corradAF-logo.svg'; // Ultimate fallback return '/img/logo/corradAF-logo.svg'; // Ultimate fallback
}); });
</script> </script>
@ -105,7 +104,7 @@ const currentLogo = computed(() => {
:src="currentLogo" :src="currentLogo"
:alt="siteSettings?.value?.siteName || 'Site Logo'" :alt="siteSettings?.value?.siteName || 'Site Logo'"
class="h-8 block" class="h-8 block"
@error="$event.target.src = '/assets/img/logo/corradAF-logo.svg'" @error="$event.target.src = '/img/logo/corradAF-logo.svg'"
/> />
<span v-if="siteSettings?.value?.siteName" <span v-if="siteSettings?.value?.siteName"
class="text-lg font-semibold" class="text-lg font-semibold"
@ -122,7 +121,7 @@ const currentLogo = computed(() => {
:src="currentLogo" :src="currentLogo"
:alt="siteSettings?.value?.siteName || 'Site Logo'" :alt="siteSettings?.value?.siteName || 'Site Logo'"
class="h-8 block" class="h-8 block"
@error="$event.target.src = '/assets/img/logo/corradAF-logo.svg'" @error="$event.target.src = '/img/logo/corradAF-logo.svg'"
/> />
<span v-if="siteSettings?.value?.siteName && siteSettings?.value?.showSiteNameInHeader" <span v-if="siteSettings?.value?.siteName && siteSettings?.value?.showSiteNameInHeader"
class="text-lg font-semibold" class="text-lg font-semibold"

View File

@ -6,10 +6,17 @@ import RSItem from "~/components/layouts/sidemenu/Item.vue";
const { siteSettings } = useSiteSettings(); const { siteSettings } = useSiteSettings();
// Add computed to ensure logo reactivity // Add computed to ensure logo reactivity
const currentLogo = computed(() => { const logoToShow = computed(() => {
return siteSettings.value.siteLogo && siteSettings.value.siteLogo.trim() !== '' // Always try to use the siteLogo from settings first
? siteSettings.value.siteLogo if (siteSettings.value?.siteLogo && siteSettings.value.siteLogo.trim() !== '') {
: '/assets/img/logo/logo-imigresen.svg'; return siteSettings.value.siteLogo;
}
// Fallback to default logo if siteLogo is not set
return '/img/logo/corradAF-logo.svg';
});
const siteNameToShow = computed(() => {
return siteSettings.value.siteName || 'Jabatan Imigresen Malaysia';
}); });
// const menuItem = Menu; // const menuItem = Menu;
@ -20,6 +27,10 @@ const props = defineProps({
default: () => Menu, default: () => Menu,
required: false, required: false,
}, },
sidebarToggle: {
type: Boolean,
default: false,
},
}); });
onMounted(() => { onMounted(() => {
@ -44,17 +55,25 @@ onMounted(() => {
<div class="py-2 px-4 bg-[rgb(var(--header))]"> <div class="py-2 px-4 bg-[rgb(var(--header))]">
<nuxt-link to="/"> <nuxt-link to="/">
<div class="flex flex-auto gap-3 justify-center items-center h-[48px]"> <div class="flex flex-auto gap-3 justify-center items-center h-[48px]">
<img <div
:src="currentLogo" class="app-logo text-center h-20 flex justify-center items-center gap-3 px-4"
:alt="siteSettings.siteName || 'Site Logo'" >
class="h-8 block" <nuxt-link to="/" class="flex items-center justify-center">
@error="$event.target.src = '/assets/img/logo/logo-imigresen.svg'" <img
/> :src="logoToShow"
<span v-if="siteSettings.showSiteNameInHeader" class="logo h-8"
class="text-xs" alt="logo"
:style="{ fontSize: Math.max(10, (siteSettings.siteNameFontSize || 18) * 0.65) + 'px' }"> @error="$event.target.src = '/img/logo/corradAF-logo.svg'"
{{ siteSettings.siteName || 'Jabatan Imigresen Malaysia' }} />
</span> <div
v-if="siteSettings.value?.showSiteNameInHeader && siteSettings.value?.siteName"
class="title-text app-title font-semibold text-xl ml-3"
:style="{ fontSize: (siteSettings.value?.siteNameFontSize || 18) + 'px' }"
>
{{ siteNameToShow }}
</div>
</nuxt-link>
</div>
</div> </div>
</nuxt-link> </nuxt-link>
</div> </div>

View File

@ -289,24 +289,45 @@ export const useSiteSettings = () => {
// Update site settings // Update site settings
const updateSiteSettings = async (newSettings) => { const updateSiteSettings = async (newSettings) => {
console.log("[useSiteSettings] updateSiteSettings called with:", JSON.parse(JSON.stringify(newSettings)));
try { try {
const response = await $fetch("/api/devtool/config/site-settings", { const response = await $fetch("/api/devtool/config/site-settings", {
method: "POST", method: "POST",
body: newSettings, body: newSettings,
}); });
console.log("[useSiteSettings] API response received:", JSON.parse(JSON.stringify(response)));
if (response && response.data) { if (response && response.data) {
// Update siteSettings with the full response from the API to ensure it reflects the saved state
siteSettings.value = { ...siteSettings.value, ...response.data }; siteSettings.value = { ...siteSettings.value, ...response.data };
applyThemeSettings(); applyThemeSettings();
updateGlobalMeta(); updateGlobalMeta();
return { success: true, data: response.data }; // Return the actual settings data console.log("[useSiteSettings] Returning success from updateSiteSettings.");
return { success: true, data: response.data };
} }
// Handle cases where response or response.data might be missing, though API should ensure structure
return { success: false, data: response }; let errorMessage = "Update operation failed: No data returned from server.";
if (response && typeof response === 'object' && response !== null && 'message' in response) {
errorMessage = response.message;
} else if (response) {
errorMessage = "Update operation failed: Unexpected server response format on success.";
} else if (response === undefined) {
errorMessage = "Update failed: Server returned no content (e.g. 204). Treating as failure as data is expected for settings.";
console.log("[useSiteSettings] Returning failure (204 or undefined response) from updateSiteSettings.");
return { success: false, error: { message: errorMessage, details: response } };
}
console.log("[useSiteSettings] Returning failure (general case) from updateSiteSettings:", errorMessage);
return { success: false, error: { message: errorMessage, details: response } };
} catch (error) { } catch (error) {
console.error("Error updating site settings:", error); console.error("[useSiteSettings] Error in updateSiteSettings catch block:", error);
return { success: false, error }; let detailedMessage = "An unexpected error occurred during update.";
if (error.data && error.data.message) {
detailedMessage = error.data.message;
} else if (error.message) {
detailedMessage = error.message;
}
console.log("[useSiteSettings] Returning failure (catch block) from updateSiteSettings:", detailedMessage);
return { success: false, error: { message: detailedMessage, details: error } };
} }
}; };
@ -329,7 +350,7 @@ export const useSiteSettings = () => {
}; };
return { return {
siteSettings: readonly(siteSettings), siteSettings,
loading: readonly(loading), loading: readonly(loading),
loadSiteSettings, loadSiteSettings,
updateSiteSettings, updateSiteSettings,

View File

@ -154,20 +154,42 @@ const saveSettings = async () => {
saving.value = true; saving.value = true;
try { try {
console.log("[SiteSettingsPage] Calling updateSiteSettings with:", JSON.parse(JSON.stringify(settings.value)));
const result = await updateSiteSettings(settings.value); const result = await updateSiteSettings(settings.value);
console.log("[SiteSettingsPage] Received result from updateSiteSettings:", JSON.parse(JSON.stringify(result)));
if (result.success) { if (result && result.success) {
originalSettings.value = { ...settings.value }; originalSettings.value = { ...settings.value };
$toast.success("Settings saved successfully"); $toast.success("Settings saved successfully");
// Apply changes // Apply changes
applyChanges(); // applyChanges(); // Temporarily commented out to isolate the error source
} else { console.log("[SiteSettingsPage] applyChanges() was skipped for testing.");
$toast.error("Failed to save settings"); } else {
// Check if result or result.error is undefined before accessing properties
let errorMsg = "Failed to save settings. Please check console for details.";
if (result && result.error && result.error.message) {
errorMsg = result.error.message;
} else if (result === undefined) {
errorMsg = "Failed to save settings: No response from update operation.";
console.error("[SiteSettingsPage] 'result' from updateSiteSettings was undefined.");
}
$toast.error(errorMsg);
if (result && result.error && result.error.details) {
console.error("[SiteSettingsPage] Save settings error details:", result.error.details);
} else if (result === undefined) {
// Already logged above
} else if (result && !result.error) {
console.error("[SiteSettingsPage] Save settings failed, but no 'error' object in result:", JSON.parse(JSON.stringify(result)));
}
} }
} catch (error) { } catch (error) {
console.error("Error saving settings:", error); // This catch block is for unexpected errors during the saveSettings execution itself,
$toast.error("Failed to save settings"); // or if updateSiteSettings somehow re-throws an error not caught by its own try-catch.
console.error("Critical error saving settings:", error);
$toast.error("A critical error occurred. Failed to save settings.");
} finally { } finally {
saving.value = false; saving.value = false;
} }
@ -320,11 +342,11 @@ const hasChanges = computed(() => {
// Get current logo paths // Get current logo paths
const getCurrentLogo = () => { const getCurrentLogo = () => {
return settings.value.siteLogo || siteSettings.value.siteLogo || '/assets/img/logo/logo-imigresen.svg'; return settings.value.siteLogo || siteSettings.value.siteLogo || '/img/logo/corradAF-logo.svg';
}; };
const getCurrentLoadingLogo = () => { const getCurrentLoadingLogo = () => {
return settings.value.siteLoadingLogo || siteSettings.value.siteLoadingLogo || '/assets/img/logo/corradAF-logo.svg'; return settings.value.siteLoadingLogo || siteSettings.value.siteLoadingLogo || '/img/logo/corradAF-logo.svg';
}; };
const getCurrentFavicon = () => { const getCurrentFavicon = () => {
@ -332,7 +354,7 @@ const getCurrentFavicon = () => {
}; };
const getCurrentLoginLogo = () => { const getCurrentLoginLogo = () => {
return settings.value.siteLoginLogo || siteSettings.value.siteLoginLogo || '/assets/img/logo/corradAF-logo.svg'; return settings.value.siteLoginLogo || siteSettings.value.siteLoginLogo || '/img/logo/corradAF-logo.svg';
}; };
// Apply Google Font // Apply Google Font
@ -562,7 +584,7 @@ watch(() => settings.value.showSiteNameInHeader, (newValue) => {
:src="getCurrentLogo()" :src="getCurrentLogo()"
alt="Current Logo" alt="Current Logo"
class="max-w-full max-h-full object-contain" class="max-w-full max-h-full object-contain"
@error="$event.target.src = '/assets/img/logo/logo-imigresen.svg'" @error="$event.target.src = '/img/logo/corradAF-logo.svg'"
/> />
</div> </div>
</div> </div>
@ -601,7 +623,7 @@ watch(() => settings.value.showSiteNameInHeader, (newValue) => {
:src="getCurrentLoadingLogo()" :src="getCurrentLoadingLogo()"
alt="Current Loading Logo" alt="Current Loading Logo"
class="max-w-full max-h-full object-contain" class="max-w-full max-h-full object-contain"
@error="$event.target.src = '/assets/img/logo/corradAF-logo.svg'" @error="$event.target.src = '/img/logo/corradAF-logo.svg'"
/> />
</div> </div>
</div> </div>
@ -640,7 +662,7 @@ watch(() => settings.value.showSiteNameInHeader, (newValue) => {
:src="getCurrentLoginLogo()" :src="getCurrentLoginLogo()"
alt="Current Login Logo" alt="Current Login Logo"
class="max-w-full max-h-full object-contain" class="max-w-full max-h-full object-contain"
@error="$event.target.src = '/assets/img/logo/corradAF-logo.svg'" @error="$event.target.src = '/img/logo/corradAF-logo.svg'"
/> />
</div> </div>
</div> </div>
@ -977,7 +999,7 @@ watch(() => settings.value.showSiteNameInHeader, (newValue) => {
:src="getCurrentLogo()" :src="getCurrentLogo()"
alt="Logo Preview" alt="Logo Preview"
class="w-10 h-10 object-contain" class="w-10 h-10 object-contain"
@error="$event.target.src = '/assets/img/logo/logo-imigresen.svg'" @error="$event.target.src = '/img/logo/corradAF-logo.svg'"
/> />
<span v-if="settings.showSiteNameInHeader" <span v-if="settings.showSiteNameInHeader"
class="font-semibold" class="font-semibold"
@ -995,7 +1017,7 @@ watch(() => settings.value.showSiteNameInHeader, (newValue) => {
:src="getCurrentLoadingLogo()" :src="getCurrentLoadingLogo()"
alt="Loading Logo Preview" alt="Loading Logo Preview"
class="w-20 h-20 object-contain" class="w-20 h-20 object-contain"
@error="$event.target.src = '/assets/img/logo/corradAF-logo.svg'" @error="$event.target.src = '/img/logo/corradAF-logo.svg'"
/> />
</div> </div>
</div> </div>
@ -1008,7 +1030,7 @@ watch(() => settings.value.showSiteNameInHeader, (newValue) => {
:src="getCurrentLoginLogo()" :src="getCurrentLoginLogo()"
alt="Login Logo Preview" alt="Login Logo Preview"
class="w-20 h-20 object-contain" class="w-20 h-20 object-contain"
@error="$event.target.src = '/assets/img/logo/corradAF-logo.svg'" @error="$event.target.src = '/img/logo/corradAF-logo.svg'"
/> />
</div> </div>
</div> </div>

View File

@ -12,9 +12,9 @@ const email = ref("");
// Get login logo with fallback // Get login logo with fallback
const getLoginLogo = () => { const getLoginLogo = () => {
if (siteSettingsLoading.value) { if (siteSettingsLoading.value) {
return '/assets/img/logo/corradAF-logo.svg'; return '/img/logo/corradAF-logo.svg';
} }
return siteSettings.value?.siteLoginLogo || '/assets/img/logo/corradAF-logo.svg'; return siteSettings.value?.siteLoginLogo || '/img/logo/corradAF-logo.svg';
}; };
// Get site name with fallback // Get site name with fallback
@ -44,7 +44,7 @@ const changePassword = () => {
:src="getLoginLogo()" :src="getLoginLogo()"
:alt="getSiteName()" :alt="getSiteName()"
class="max-w-[180px] max-h-[60px] object-contain" class="max-w-[180px] max-h-[60px] object-contain"
@error="$event.target.src = '/assets/img/logo/corradAF-logo.svg'" @error="$event.target.src = '/img/logo/corradAF-logo.svg'"
/> />
</div> </div>
<h2 class="mt-4 text-2xl font-bold text-gray-700"> <h2 class="mt-4 text-2xl font-bold text-gray-700">

View File

@ -19,9 +19,9 @@ const togglePasswordVisibility = ref(false);
// Get login logo with fallback // Get login logo with fallback
const getLoginLogo = () => { const getLoginLogo = () => {
if (siteSettingsLoading.value) { if (siteSettingsLoading.value) {
return '/assets/img/logo/corradAF-logo.svg'; return '/img/logo/corradAF-logo.svg';
} }
return siteSettings.value?.siteLoginLogo || '/assets/img/logo/corradAF-logo.svg'; return siteSettings.value?.siteLoginLogo || '/img/logo/corradAF-logo.svg';
}; };
// Get site name with fallback // Get site name with fallback
@ -98,7 +98,7 @@ const handleLoadCallback = (response) => {
:src="getLoginLogo()" :src="getLoginLogo()"
:alt="getSiteName()" :alt="getSiteName()"
class="max-w-[180px] max-h-[60px] object-contain" class="max-w-[180px] max-h-[60px] object-contain"
@error="$event.target.src = '/assets/img/logo/corradAF-logo.svg'" @error="$event.target.src = '/img/logo/corradAF-logo.svg'"
/> />
</div> </div>
<p class="text-slate-500 text-lg mb-6">Log masuk ke akaun anda</p> <p class="text-slate-500 text-lg mb-6">Log masuk ke akaun anda</p>

View File

@ -36,9 +36,9 @@ const handleRecaptcha = (response) => {
// Get login logo with fallback // Get login logo with fallback
const getLoginLogo = () => { const getLoginLogo = () => {
if (siteSettingsLoading.value) { if (siteSettingsLoading.value) {
return '/assets/img/logo/corradAF-logo.svg'; return '/img/logo/corradAF-logo.svg';
} }
return siteSettings.value?.siteLoginLogo || '/assets/img/logo/corradAF-logo.svg'; return siteSettings.value?.siteLoginLogo || '/img/logo/corradAF-logo.svg';
}; };
// Get site name with fallback // Get site name with fallback
@ -62,7 +62,7 @@ const getSiteName = () => {
:src="getLoginLogo()" :src="getLoginLogo()"
:alt="getSiteName()" :alt="getSiteName()"
class="max-w-[180px] max-h-[60px] object-contain" class="max-w-[180px] max-h-[60px] object-contain"
@error="$event.target.src = '/assets/img/logo/corradAF-logo.svg'" @error="$event.target.src = '/img/logo/corradAF-logo.svg'"
/> />
</div> </div>
<h2 class="mt-4 text-2xl font-bold text-gray-700">Daftar Akaun</h2> <h2 class="mt-4 text-2xl font-bold text-gray-700">Daftar Akaun</h2>

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB