You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

99 lines
2.7 KiB

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
};
};