25852
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
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
|
||||
};
|
||||
};
|
Loading…
Reference in new issue