Skip to content

Commit

Permalink
Merge pull request #7 from renegadevi/development
Browse files Browse the repository at this point in the history
big update, packages on latest, boilerplate v2.0
  • Loading branch information
renegadevi authored Dec 26, 2024
2 parents 4035265 + 0a3108e commit a002224
Show file tree
Hide file tree
Showing 22 changed files with 449 additions and 423 deletions.
Binary file modified .github/screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 29 additions & 6 deletions app.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
<script setup lang="ts">
const { locale, t } = useI18n();
const isLoading = ref(true);
if (import.meta.client) {
const storedLanguage = localStorage.getItem("nuxt-lang");
if (storedLanguage && storedLanguage !== "en-US") {
locale.value = storedLanguage;
}
}
onMounted(() => {
// Remove loading state after initial render
nextTick(() => {
isLoading.value = false;
});
});
useHead({
htmlAttrs: {
lang: locale,
Expand All @@ -12,11 +28,18 @@ useHead({
},
});
</script>

<template>
<NuxtLayout>
<div>
<CookieBanner />
<NuxtPage />
</div>
</NuxtLayout>
<div class="relative">
<div
v-if="isLoading"
class="fixed inset-0 z-50 flex items-center justify-center bg-white transition-opacity duration-300 dark:bg-gray-900"
></div>
<NuxtLayout>
<div>
<CookieBanner />
<NuxtPage />
</div>
</NuxtLayout>
</div>
</template>
6 changes: 3 additions & 3 deletions assets/css/cookiecontrol.css
Original file line number Diff line number Diff line change
Expand Up @@ -144,19 +144,19 @@
transform: translate3d(0, -50%, 0);
}
.cookieControl__ModalContentInner h3 {
@apply mt-3 text-sm;
@apply mt-3 text-sm dark:text-white;
}
.cookieControl__ModalContentInner h3:first-child {
@apply block text-2xl font-medium;
}
.cookieControl__ModalContentInner p {
@apply mb-5 mt-6 border-b pb-5 text-sm;
@apply mb-5 mt-6 border-b pb-5 text-sm ;
}
.cookieControl__ModalContentInner p a {
@apply border-b font-bold;
}
.cookieControl__ModalContentInner {
@apply max-h-[90vh] overflow-y-scroll md:max-h-[80vh];
@apply max-h-[90vh] overflow-y-scroll md:max-h-[80vh] dark:text-white;
}
.cookieControl__ModalContentInner ul li {
@apply relative my-3 rounded-md p-5;
Expand Down
2 changes: 1 addition & 1 deletion assets/css/tailwind.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
}
}
html {
@apply bg-slate-100;
@apply bg-white;
}
html.dark {
@apply bg-slate-900;
Expand Down
5 changes: 4 additions & 1 deletion components/global/CookieBanner.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<script setup lang="ts">
const { locale } = useI18n();
type LocaleCode = typeof locale.value extends `${infer Code}-${string}` ? Code : never;
const currentLocale = computed(() => locale.value.slice(0, 2) as LocaleCode)
/* Example to watch for a cookie being accepted */
/*
const {
Expand All @@ -26,7 +29,7 @@ watch(
</script>
<template>
<div>
<CookieControl :locale="locale.slice(0, 2)">
<CookieControl :locale="currentLocale">
<template #bar>
<h3>{{ $t("cookies.bar.title") }}</h3>
<p>{{ $t("cookies.bar.description") }}</p>
Expand Down
98 changes: 66 additions & 32 deletions components/global/LanguageSelector.vue
Original file line number Diff line number Diff line change
@@ -1,41 +1,75 @@
<script setup lang="ts">
const { locale } = useI18n();
const { locale, t } = useI18n();
const isOpen = ref(false);
const dropdownRef = ref<HTMLElement | null>(null);
// update local storage upon language change
const toggleLocale = () => {
localStorage.setItem("nuxt-lang", locale.value);
};
// check for stored language on initial load.
// Get initial language from localStorage or default to 'en-US'
onMounted(() => {
const storedLanguage = localStorage.getItem("nuxt-lang");
if (storedLanguage) {
locale.value = storedLanguage;
const savedLang = localStorage.getItem('nuxt-lang');
if (savedLang) {
locale.value = savedLang;
document.documentElement.dir = t('locale.dir');
}
document.addEventListener('click', (event: MouseEvent) => {
const target = event.target as Node;
if (dropdownRef.value && !dropdownRef.value.contains(target)) {
isOpen.value = false;
}
});
});
const setLanguage = (language: string) => {
locale.value = language;
// Save to localStorage
localStorage.setItem('nuxt-lang', language);
isOpen.value = false;
document.documentElement.dir = t('locale.dir');
};
</script>


<template>
<form>
<label for="languages" aria-label="icon">
<Icon name="prime:language" size="1.5em" />
</label>
<select
id="languages"
v-model="$i18n.locale"
aria-label="language"
class="bg-transparent"
@change="toggleLocale"
<div class="w-auto" ref="dropdownRef">
<button
@click="isOpen = !isOpen"
class="flex items-center gap-2 rounded-lg p-2 px-4 text-gray-600 dark:text-white"
:class="[
{ 'flex-row-reverse': t('locale.dir') === 'rtl' },
isOpen ? 'bg-gray-100 dark:bg-slate-700' : 'hover:bg-gray-100 dark:hover:bg-slate-700'
]"
>

<Icon name="ph:translate" size="1.25em" />
<span>{{ $t("locale." + $i18n.locale) }}</span>
<Icon
name="ph:caret-down"
class="h-4 w-4 transition-all duration-200"
:class="{ 'rotate-180': isOpen }"
/>
</button>

<div
v-if="isOpen"
class="absolute mt-1 min-w-32 rounded-lg bg-white shadow-lg border border-gray-100 dark:bg-slate-700 dark:border-slate-700 right-0"
>
<option
v-for="language in $i18n.availableLocales"
:key="language"
:aria-label="$t('locale.' + language)"
:value="language"
:selected="$i18n.locale === language"
class="dark:bg-slate-800"
>
{{ $t("locale." + language) }}
</option>
</select>
</form>
<ul>
<li
v-for="language in $i18n.availableLocales"
:key="language"
:class="[
'px-4 py-2 cursor-pointer rounded-md m-1 hover:bg-gray-100 text-gray-600 dark:text-white dark:hover:bg-slate-600',
{ 'bg-gray-100 dark:bg-slate-600 ': $i18n.locale === language },
{ 'text-right': t('locale.dir') === 'rtl' }
]"
@click="() => setLanguage(language)"
>
{{ $t("locale." + language) }}
</li>

</ul>
</div>

</div>

</template>
54 changes: 23 additions & 31 deletions components/global/ThemeSwitcher.vue
Original file line number Diff line number Diff line change
@@ -1,33 +1,25 @@
<script setup>
const colorMode = useColorMode();
const themeConfig = {
dark: { next: 'system', icon: 'ph:moon' },
system: { next: 'light', icon: 'ph:sun-horizon' },
light: { next: 'dark', icon: 'ph:sun' }
};
const name = ref(null);
const toggleColorMode = () => {
const { next } = themeConfig[colorMode.preference];
Object.assign(colorMode, { preference: next, value: next });
name.value = themeConfig[next].icon;
};
onMounted(() => {
name.value = themeConfig[colorMode.preference].icon;
});
</script>
<template>
<form>
<label for="themes"><Icon name="gg:dark-mode" size="1.5em" /></label>
<select
id="themes"
v-model="$colorMode.preference"
aria-label="themes"
class="border-1 border-l-3 mx-1 inline-block border-gray-900 bg-inherit text-sm"
>
<option
class="dark:bg-slate-800"
value="system"
:aria-label="$t('themes.system')"
>
{{ $t("themes.system") }}
</option>
<option
class="dark:bg-slate-800"
value="light"
:aria-label="$t('themes.light')"
>
{{ $t("themes.light") }}
</option>
<option
class="dark:bg-slate-800"
value="dark"
:aria-label="$t('themes.dark')"
>
{{ $t("themes.dark") }}
</option>
</select>
</form>
<ClientOnly>
<button v-bind="$attrs" class="cursor-pointer flex w-10 h-10" @click="toggleColorMode" aria-label="Toggle color modes">
<Icon :name size="24" />
</button>
</ClientOnly>
</template>
46 changes: 19 additions & 27 deletions error.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,25 @@
defineProps({ error: { type: Object, default: null } });
</script>
<template>
<div
class="h-screen bg-slate-100 p-20 text-slate-900 dark:bg-slate-900 dark:text-white"
>
<div
class="mx-auto w-auto max-w-md rounded-2xl bg-white p-6 text-center shadow-xl dark:bg-slate-800"
>
<div
class="relative flex flex-col justify-center gap-y-4 sm:h-40 sm:gap-y-5"
>
<p class="mb-[-1em] font-semibold text-slate-500 dark:text-slate-400">
{{ error.statusCode }}
</p>
<h1 class="text-xl font-medium">
<template v-if="error.statusCode == 404">
{{ $t("error.page-not-found") }}
</template>
<template v-else>
{{ error.message }}
</template>
</h1>
<button
class="mx-auto mt-3 w-[10rem] rounded-lg border border-slate-200 bg-gray-50 p-4 py-2.5 text-gray-700 hover:cursor-pointer hover:border-slate-200 hover:bg-slate-100 dark:border-gray-700 dark:bg-slate-800 dark:text-white dark:hover:bg-slate-700"
@click="clearError({ redirect: '/' })"
>
{{ $t("error.return") }}
</button>
</div>
<div class="p-20 text-slate-900 dark:bg-slate-900 dark:text-white">
<div class="relative flex flex-col justify-center gap-y-4 sm:h-40 sm:gap-y-5 text-center">
<p class="mb-[-1em] font-semibold text-slate-500 dark:text-slate-300">
{{ error.statusCode }}
</p>
<h1 class="text-xl font-medium">
<template v-if="error.statusCode == 404">
{{ $t("error.page-not-found") }}
</template>
<template v-else>
{{ error.message }}
</template>
</h1>
<button
class="mx-auto mt-3 flex align-middle items-center gap-2 justify-center rounded-lg bg-gray-200 py-2.5 px-5 text-gray-700 hover:cursor-pointer hover:bg-gray-100 dark:bg-slate-800 dark:text-white dark:hover:bg-slate-700"
@click="clearError({ redirect: '/' })"
><Icon name="ph:arrow-left-bold" />
{{ $t("error.return") }}
</button>
</div>
</div>
</template>
15 changes: 11 additions & 4 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
// @ts-check
import withNuxt from './.nuxt/eslint.config.mjs'
import nuxtConfig from './.nuxt/eslint.config.mjs'
const baseConfig = Array.isArray(nuxtConfig) ? nuxtConfig : [nuxtConfig]

export default withNuxt(
// Your custom configs here
)
export default [
...baseConfig,
{
files: ['**/*.{js,ts,vue}'],
rules: {
// custom rules here
}
}
]
52 changes: 31 additions & 21 deletions i18n.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,34 @@ import en from "./locales/en-US.json";
import fr from "./locales/fr-FR.json";
import ar from "./locales/ar-AR.json";

export default defineI18nConfig(() => ({
legacy: false,
langDir: "./locales",
messages: { "en-US": en, "fr-FR": fr, "ar-AR": ar },
baseUrl: import.meta.env.VITE_BASE_URL,
locales: [
{
code: "en",
iso: "en-US",
isCatchallLocale: true,
},
{
code: "fr",
iso: "fr-FR",
},
{
code: "ar",
iso: "ar-AR",
},
],
}));
export default defineI18nConfig(() => {
const config = useRuntimeConfig()

return {
legacy: false,
langDir: "./locales",
messages: { "en-US": en, "fr-FR": fr, "ar-AR": ar },
baseUrl: config.public.baseUrl,
locales: [
{
code: "en",
iso: "en-US",
isCatchallLocale: true,
},
{
code: "fr",
iso: "fr-FR",
},
{
code: "ar",
iso: "ar-AR",
},
],
detectBrowserLanguage: {
useCookie: true,
cookieKey: 'nuxt-lang',
redirectOn: 'root'
}
}
})

Loading

0 comments on commit a002224

Please sign in to comment.