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.
90 lines
2.3 KiB
90 lines
2.3 KiB
import { ref, onMounted, computed } from 'vue';
|
|
import { useRouter } from 'vue-router';
|
|
import type { Project } from '~/types/project';
|
|
import {
|
|
projects,
|
|
truncateDescription,
|
|
processProjectImage,
|
|
processProjectResources,
|
|
handleImageError,
|
|
handleIconError,
|
|
} from "~/assets/ts/pages/projects";
|
|
import { TEXTS } from '~/config/content';
|
|
import { DEFAULT_IMAGES } from '~/config/paths';
|
|
|
|
interface ProjectResource {
|
|
url: string;
|
|
icon: string;
|
|
}
|
|
|
|
interface ProcessedResources {
|
|
github?: ProjectResource;
|
|
demo?: ProjectResource;
|
|
}
|
|
|
|
export const useProjects = () => {
|
|
const router = useRouter();
|
|
const projectImages = ref<Record<number, string>>({});
|
|
const projectResources = ref<Record<number, ProcessedResources>>({});
|
|
const isLoading = ref(true);
|
|
const error = ref<string | null>(null);
|
|
|
|
const filteredProjects = computed(() => {
|
|
return projects;
|
|
});
|
|
|
|
const loadProjectResources = async () => {
|
|
try {
|
|
const loadPromises = projects.map(async (project: Project) => {
|
|
try {
|
|
const [image, resources] = await Promise.all([
|
|
processProjectImage(project),
|
|
processProjectResources(project)
|
|
]);
|
|
|
|
projectImages.value[project.id] = image;
|
|
projectResources.value[project.id] = resources;
|
|
} catch (error) {
|
|
console.error('Error loading resources for project ${project.id}:', error);
|
|
projectImages.value[project.id] = DEFAULT_IMAGES.PROJECT;
|
|
projectResources.value[project.id] = {};
|
|
}
|
|
});
|
|
|
|
await Promise.all(loadPromises);
|
|
} catch (error) {
|
|
console.error('Error loading project resources:', error);
|
|
} finally {
|
|
isLoading.value = false;
|
|
}
|
|
};
|
|
|
|
const getProjectStatus = (status: Project['status']) => {
|
|
switch (status) {
|
|
case 'completed':
|
|
return TEXTS.PROJECTS.STATUS.COMPLETED;
|
|
case 'in-progress':
|
|
return TEXTS.PROJECTS.STATUS.IN_PROGRESS;
|
|
case 'planned':
|
|
return TEXTS.PROJECTS.STATUS.PLANNED;
|
|
default:
|
|
return status;
|
|
}
|
|
};
|
|
|
|
onMounted(() => {
|
|
loadProjectResources();
|
|
});
|
|
|
|
return {
|
|
projects: filteredProjects,
|
|
projectImages,
|
|
projectResources,
|
|
isLoading,
|
|
error,
|
|
truncateDescription,
|
|
handleImageError,
|
|
handleIconError,
|
|
getProjectStatus
|
|
};
|
|
}; |