25852
continuous-integration/drone/push Build is failing Details

master
37b7 3 weeks ago
parent b0db5d01f0
commit b363f5c29c

@ -1,8 +0,0 @@
import { DEFAULT_IMAGES } from "~/config/paths";
export const handleIconError = (payload: string | Event) => {
if (payload instanceof Event) {
const target = payload.target as HTMLImageElement;
target.src = DEFAULT_IMAGES.ICON;
}
};

@ -1,3 +0,0 @@
export const handleError = () => {
clearError({ redirect: window.location.pathname })
}

@ -1,16 +0,0 @@
import { DEFAULT_IMAGES } from "~/config/paths";
export const handleLightboxImageError = (event: Event): void => {
const target = event.target as HTMLImageElement;
target.src = DEFAULT_IMAGES.PROJECT;
};
export const handleImageError = (event: Event): void => {
const target = event.target as HTMLImageElement;
target.src = DEFAULT_IMAGES.PROJECT;
};
export const handleIconError = (event: Event): void => {
const target = event.target as HTMLImageElement;
target.src = DEFAULT_IMAGES.ICON;
};

@ -1,99 +0,0 @@
import { ref, onMounted, onUnmounted } from 'vue';
import { handleImageError, handleIconError, handleLightboxImageError } from '~/assets/ts/error/handle';
import { TEXTS } from '~/config/content';
import { PATHS } from '~/config/paths';
import { projects } from '~/config/projects';
import type { Project } from '~/types/project';
export const useProjectDetail = (id: number) => {
const { $theme } = useNuxtApp();
const showLightbox = ref(false);
const currentImageIndex = ref(0);
const processedImages = ref<string[]>([]);
const currentProject = ref<Project | null>(null);
currentProject.value = projects.find((project) => project.id === id) || null;
const openLightbox = (index: number): void => {
currentImageIndex.value = index;
showLightbox.value = true;
};
const closeLightbox = (): void => {
showLightbox.value = false;
};
const nextImage = (): void => {
if (!processedImages.value.length) return;
currentImageIndex.value = (currentImageIndex.value + 1) % processedImages.value.length;
};
const prevImage = (): void => {
if (!processedImages.value.length) return;
currentImageIndex.value = (currentImageIndex.value - 1 + processedImages.value.length) % processedImages.value.length;
};
const handleKeyDown = (event: KeyboardEvent): void => {
if (!showLightbox.value) return;
switch (event.key) {
case 'Escape':
closeLightbox();
break;
case 'ArrowLeft':
prevImage();
break;
case 'ArrowRight':
nextImage();
break;
}
};
onMounted(async () => {
window.addEventListener('keydown', handleKeyDown);
});
onUnmounted(() => {
window.removeEventListener('keydown', handleKeyDown);
});
const getIconPath = (iconType: keyof typeof PATHS.ICONS) => {
return $theme.isDark.value
? PATHS.ICONS[iconType]?.DARK
: PATHS.ICONS[iconType]?.LIGHT;
};
const projectResources = computed(() => ({
github: currentProject.value?.github ? {
icon: getIconPath('GITHUB'),
label: TEXTS.PROJECTS.RESOURCES.GITHUB
} : null,
demo: currentProject.value?.demo ? {
icon: getIconPath('DEMO'),
label: TEXTS.PROJECTS.RESOURCES.DEMO
} : null,
documentation: currentProject.value?.documentation ? {
icon: getIconPath('DOCUMENTATION'),
label: TEXTS.PROJECTS.RESOURCES.DOCUMENTATION
} : null,
youtube: currentProject.value?.youtube ? {
icon: getIconPath('YOUTUBE'),
label: TEXTS.PROJECTS.RESOURCES.YOUTUBE
} : null
}));
return {
currentProject,
projectResources,
showLightbox,
currentImageIndex,
openLightbox,
closeLightbox,
nextImage,
prevImage,
handleImageError,
handleIconError,
handleLightboxImageError
};
};

@ -1,48 +0,0 @@
import { ref } from 'vue';
const THEME_KEY = 'theme';
const THEMES = {
LIGHT: 'light',
DARK: 'dark'
} as const;
const isDark = ref(false);
let initialized = false;
const setTheme = (theme: typeof THEMES[keyof typeof THEMES]) => {
if (process.client) {
document.documentElement.setAttribute('data-theme', theme);
localStorage.setItem(THEME_KEY, theme);
isDark.value = theme === THEMES.DARK;
}
};
const initializeTheme = () => {
if (process.client && !initialized) {
const savedTheme = localStorage.getItem(THEME_KEY) as typeof THEMES[keyof typeof THEMES] | null;
const prefersDark = window.matchMedia?.('(prefers-color-scheme: dark)').matches;
const theme = savedTheme || (prefersDark ? THEMES.DARK : THEMES.LIGHT);
setTheme(theme);
window.matchMedia?.('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
if (!localStorage.getItem(THEME_KEY)) {
setTheme(e.matches ? THEMES.DARK : THEMES.LIGHT);
}
});
initialized = true;
}
};
const toggleTheme = () => {
setTheme(isDark.value ? THEMES.LIGHT : THEMES.DARK);
};
export const useTheme = () => {
if (process.client) {
initializeTheme();
}
return {
isDark,
toggleTheme
};
};

@ -21,8 +21,14 @@
<script setup lang="ts">
import { TEXTS } from '~/config/content';
import { PATHS } from '~/config/paths';
import { handleIconError } from '~/assets/ts/components/footer';
import { PATHS , DEFAULT_IMAGES} from '~/config/paths';
export const handleIconError = (payload: string | Event) => {
if (payload instanceof Event) {
const target = payload.target as HTMLImageElement;
target.src = DEFAULT_IMAGES.ICON;
}
};
const { $theme } = useNuxtApp();
const currentYear = new Date().getFullYear();

@ -22,10 +22,13 @@
</template>
<script setup lang="ts">
import { handleError } from '~/assets/ts/error/error'
import type { ErrorProps } from '~/types/error';
import { navigationItems } from '~/config/navigation';
const handleError = () => {
clearError({ redirect: window.location.pathname })
}
definePageMeta({
layout: 'default'
})

@ -30,7 +30,7 @@ export default defineNuxtConfig({
}
],
},
buildAssetsDir: '/containers/matheothierry-portfolio_nuxt/_nuxt/',
buildAssetsDir: '/_nuxt/',
},
routeRules: {
@ -77,4 +77,4 @@ export default defineNuxtConfig({
basePath: process.env.BASE_PATH || ''
}
}
})
})

@ -78,11 +78,120 @@
</template>
<script setup lang="ts">
import { ref, computed } from 'vue';
import { useProjectDetail } from '~/assets/ts/project/useProjectDetail';
import { TEXTS } from '~/config/content';
import { ref,computed, onMounted, onUnmounted } from 'vue';
import { navigationItems } from '~/config/navigation';
import { DEFAULT_IMAGES, PATHS } from '~/config/paths';
import { TEXTS } from '~/config/content';
import { PATHS , DEFAULT_IMAGES} from '~/config/paths';
import { projects } from '~/config/projects';
import type { Project } from '~/types/project';
export const handleLightboxImageError = (event: Event): void => {
const target = event.target as HTMLImageElement;
target.src = DEFAULT_IMAGES.PROJECT;
};
export const handleImageError = (event: Event): void => {
const target = event.target as HTMLImageElement;
target.src = DEFAULT_IMAGES.PROJECT;
};
export const handleIconError = (event: Event): void => {
const target = event.target as HTMLImageElement;
target.src = DEFAULT_IMAGES.ICON;
};
export const useProjectDetail = (id: number) => {
const { $theme } = useNuxtApp();
const showLightbox = ref(false);
const currentImageIndex = ref(0);
const processedImages = ref<string[]>([]);
const currentProject = ref<Project | null>(null);
currentProject.value = projects.find((project) => project.id === id) || null;
const openLightbox = (index: number): void => {
currentImageIndex.value = index;
showLightbox.value = true;
};
const closeLightbox = (): void => {
showLightbox.value = false;
};
const nextImage = (): void => {
if (!processedImages.value.length) return;
currentImageIndex.value = (currentImageIndex.value + 1) % processedImages.value.length;
};
const prevImage = (): void => {
if (!processedImages.value.length) return;
currentImageIndex.value = (currentImageIndex.value - 1 + processedImages.value.length) % processedImages.value.length;
};
const handleKeyDown = (event: KeyboardEvent): void => {
if (!showLightbox.value) return;
switch (event.key) {
case 'Escape':
closeLightbox();
break;
case 'ArrowLeft':
prevImage();
break;
case 'ArrowRight':
nextImage();
break;
}
};
onMounted(async () => {
window.addEventListener('keydown', handleKeyDown);
});
onUnmounted(() => {
window.removeEventListener('keydown', handleKeyDown);
});
const getIconPath = (iconType: keyof typeof PATHS.ICONS) => {
return $theme.isDark.value
? PATHS.ICONS[iconType]?.DARK
: PATHS.ICONS[iconType]?.LIGHT;
};
const projectResources = computed(() => ({
github: currentProject.value?.github ? {
icon: getIconPath('GITHUB'),
label: TEXTS.PROJECTS.RESOURCES.GITHUB
} : null,
demo: currentProject.value?.demo ? {
icon: getIconPath('DEMO'),
label: TEXTS.PROJECTS.RESOURCES.DEMO
} : null,
documentation: currentProject.value?.documentation ? {
icon: getIconPath('DOCUMENTATION'),
label: TEXTS.PROJECTS.RESOURCES.DOCUMENTATION
} : null,
youtube: currentProject.value?.youtube ? {
icon: getIconPath('YOUTUBE'),
label: TEXTS.PROJECTS.RESOURCES.YOUTUBE
} : null
}));
return {
currentProject,
projectResources,
showLightbox,
currentImageIndex,
openLightbox,
closeLightbox,
nextImage,
prevImage,
handleImageError,
handleIconError,
handleLightboxImageError
};
};
const route = useRoute();
const projectId = Number(route.params.id);
@ -91,8 +200,6 @@ const projectsPath = navigationItems.find((item) => item.finder === 'projects')?
const {
currentProject,
handleImageError,
handleIconError,
showLightbox,
currentImageIndex,
openLightbox,

@ -1,4 +1,51 @@
import { useTheme } from '~/assets/ts/useTheme';
import { ref } from 'vue';
const THEME_KEY = 'theme';
const THEMES = {
LIGHT: 'light',
DARK: 'dark'
} as const;
const isDark = ref(false);
let initialized = false;
const setTheme = (theme: typeof THEMES[keyof typeof THEMES]) => {
if (process.client) {
document.documentElement.setAttribute('data-theme', theme);
localStorage.setItem(THEME_KEY, theme);
isDark.value = theme === THEMES.DARK;
}
};
const initializeTheme = () => {
if (process.client && !initialized) {
const savedTheme = localStorage.getItem(THEME_KEY) as typeof THEMES[keyof typeof THEMES] | null;
const prefersDark = window.matchMedia?.('(prefers-color-scheme: dark)').matches;
const theme = savedTheme || (prefersDark ? THEMES.DARK : THEMES.LIGHT);
setTheme(theme);
window.matchMedia?.('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
if (!localStorage.getItem(THEME_KEY)) {
setTheme(e.matches ? THEMES.DARK : THEMES.LIGHT);
}
});
initialized = true;
}
};
const toggleTheme = () => {
setTheme(isDark.value ? THEMES.LIGHT : THEMES.DARK);
};
export const useTheme = () => {
if (process.client) {
initializeTheme();
}
return {
isDark,
toggleTheme
};
};
export default defineNuxtPlugin((nuxtApp) => {
const { isDark, toggleTheme } = useTheme();

Loading…
Cancel
Save