This commit is contained in:
2026-02-05 01:04:43 +04:00
parent d2890f8a74
commit 865f7b5315
8 changed files with 53 additions and 6 deletions

View File

@@ -40,7 +40,7 @@ collections:
- { label: "Image", name: "image", widget: "image", required: false } - { label: "Image", name: "image", widget: "image", required: false }
- { label: "Category", name: "category", widget: "select", options: ["actual","history","other"] } - { label: "Category", name: "category", widget: "select", options: ["actual","history","other"] }
- { label: "Tech Stack", name: "techStack", widget: "list", default: [] } - { label: "Tech Stack", name: "techStack", widget: "list", default: [] }
- { label: "Status", name: "status", widget: "select", options: ["completed","in-progress","planned"] } - { label: "Status", name: "status", widget: "select", options: ["completed","in-progress","planned","paused"] }
- { label: "Live Demo", name: "liveDemo", widget: "string", required: false } - { label: "Live Demo", name: "liveDemo", widget: "string", required: false }
- { label: "Source Code", name: "sourceCode", widget: "string", required: false } - { label: "Source Code", name: "sourceCode", widget: "string", required: false }
- { label: "Start Date", name: "startDate", widget: "datetime" } - { label: "Start Date", name: "startDate", widget: "datetime" }

View File

@@ -11,7 +11,7 @@ export interface Props {
image?: string; image?: string;
category: string; category: string;
techStack: string[]; techStack: string[];
status: "completed" | "in-progress" | "planned"; status: "completed" | "in-progress" | "planned" | "paused";
demoUrl?: string; demoUrl?: string;
sourceUrl?: string; sourceUrl?: string;
startDate: string; startDate: string;
@@ -40,6 +40,8 @@ const getStatusStyle = (status: string) => {
return "bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400"; return "bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400";
case "planned": case "planned":
return "bg-gray-100 text-gray-700 dark:bg-gray-900/30 dark:text-gray-400"; return "bg-gray-100 text-gray-700 dark:bg-gray-900/30 dark:text-gray-400";
case "paused":
return "bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-400";
default: default:
return "bg-gray-100 text-gray-700 dark:bg-gray-900/30 dark:text-gray-400"; return "bg-gray-100 text-gray-700 dark:bg-gray-900/30 dark:text-gray-400";
} }
@@ -54,6 +56,8 @@ const getStatusText = (status: string) => {
return i18n(I18nKey.projectsInProgress); return i18n(I18nKey.projectsInProgress);
case "planned": case "planned":
return i18n(I18nKey.projectsPlanned); return i18n(I18nKey.projectsPlanned);
case "paused":
return i18n(I18nKey.projectsPaused);
default: default:
return status; return status;
} }

View File

@@ -81,12 +81,14 @@ enum I18nKey {
projectStatusCompleted = "projectStatusCompleted", projectStatusCompleted = "projectStatusCompleted",
projectStatusInProgress = "projectStatusInProgress", projectStatusInProgress = "projectStatusInProgress",
projectStatusPlanned = "projectStatusPlanned", projectStatusPlanned = "projectStatusPlanned",
projectStatusPaused = "projectStatusPaused",
projectsTotal = "projectsTotal", projectsTotal = "projectsTotal",
projectsCompleted = "projectsCompleted", projectsCompleted = "projectsCompleted",
projectsInProgress = "projectsInProgress", projectsInProgress = "projectsInProgress",
projectsTechStack = "projectsTechStack", projectsTechStack = "projectsTechStack",
projectsFeatured = "projectsFeatured", projectsFeatured = "projectsFeatured",
projectsPlanned = "projectsPlanned", projectsPlanned = "projectsPlanned",
projectsPaused = "projectsPaused",
projectsDemo = "projectsDemo", projectsDemo = "projectsDemo",
projectsSource = "projectsSource", projectsSource = "projectsSource",

View File

@@ -85,12 +85,14 @@ export const en: Translation = {
[Key.projectStatusCompleted]: "Completed", [Key.projectStatusCompleted]: "Completed",
[Key.projectStatusInProgress]: "In Progress", [Key.projectStatusInProgress]: "In Progress",
[Key.projectStatusPlanned]: "Planned", [Key.projectStatusPlanned]: "Planned",
[Key.projectStatusPaused]: "Paused",
[Key.projectsTotal]: "Total Projects", [Key.projectsTotal]: "Total Projects",
[Key.projectsCompleted]: "Completed", [Key.projectsCompleted]: "Completed",
[Key.projectsInProgress]: "In Progress", [Key.projectsInProgress]: "In Progress",
[Key.projectsTechStack]: "Tech Stack Statistics", [Key.projectsTechStack]: "Tech Stack Statistics",
[Key.projectsFeatured]: "Featured Projects", [Key.projectsFeatured]: "Featured Projects",
[Key.projectsPlanned]: "Planned", [Key.projectsPlanned]: "Planned",
[Key.projectsPaused]: "Paused",
[Key.projectsDemo]: "Live Demo", [Key.projectsDemo]: "Live Demo",
[Key.projectsSource]: "Source Code", [Key.projectsSource]: "Source Code",

View File

@@ -85,12 +85,14 @@ export const ja: Translation = {
[Key.projectStatusCompleted]: "完了", [Key.projectStatusCompleted]: "完了",
[Key.projectStatusInProgress]: "進行中", [Key.projectStatusInProgress]: "進行中",
[Key.projectStatusPlanned]: "予定", [Key.projectStatusPlanned]: "予定",
[Key.projectStatusPaused]: "一時停止",
[Key.projectsTotal]: "プロジェクト合計", [Key.projectsTotal]: "プロジェクト合計",
[Key.projectsCompleted]: "完了", [Key.projectsCompleted]: "完了",
[Key.projectsInProgress]: "進行中", [Key.projectsInProgress]: "進行中",
[Key.projectsTechStack]: "技術スタック統計", [Key.projectsTechStack]: "技術スタック統計",
[Key.projectsFeatured]: "注目プロジェクト", [Key.projectsFeatured]: "注目プロジェクト",
[Key.projectsPlanned]: "予定", [Key.projectsPlanned]: "予定",
[Key.projectsPaused]: "一時停止",
[Key.projectsDemo]: "ライブデモ", [Key.projectsDemo]: "ライブデモ",
[Key.projectsSource]: "ソースコード", [Key.projectsSource]: "ソースコード",

View File

@@ -84,12 +84,14 @@ export const ru: Translation = {
[Key.projectStatusCompleted]: "Завершён", [Key.projectStatusCompleted]: "Завершён",
[Key.projectStatusInProgress]: "В разработке", [Key.projectStatusInProgress]: "В разработке",
[Key.projectStatusPlanned]: "Запланирован", [Key.projectStatusPlanned]: "Запланирован",
[Key.projectStatusPaused]: "Приостановлен",
[Key.projectsTotal]: "Всего проектов", [Key.projectsTotal]: "Всего проектов",
[Key.projectsCompleted]: "Завершён", [Key.projectsCompleted]: "Завершён",
[Key.projectsInProgress]: "В разработке", [Key.projectsInProgress]: "В разработке",
[Key.projectsTechStack]: "Статистика технологий", [Key.projectsTechStack]: "Статистика технологий",
[Key.projectsFeatured]: "Сейчас я работаю над этим", [Key.projectsFeatured]: "Сейчас я работаю над этим",
[Key.projectsPlanned]: "Запланированных", [Key.projectsPlanned]: "Запланированных",
[Key.projectsPaused]: "Приостановлен",
[Key.projectsDemo]: "Демо", [Key.projectsDemo]: "Демо",
[Key.projectsSource]: "Исходный код", [Key.projectsSource]: "Исходный код",

View File

@@ -85,12 +85,14 @@ export const zh: Translation = {
[Key.projectStatusCompleted]: "已完成", [Key.projectStatusCompleted]: "已完成",
[Key.projectStatusInProgress]: "进行中", [Key.projectStatusInProgress]: "进行中",
[Key.projectStatusPlanned]: "计划中", [Key.projectStatusPlanned]: "计划中",
[Key.projectStatusPaused]: "已暂停",
[Key.projectsTotal]: "项目总数", [Key.projectsTotal]: "项目总数",
[Key.projectsCompleted]: "已完成", [Key.projectsCompleted]: "已完成",
[Key.projectsInProgress]: "进行中", [Key.projectsInProgress]: "进行中",
[Key.projectsTechStack]: "技术栈统计", [Key.projectsTechStack]: "技术栈统计",
[Key.projectsFeatured]: "精选项目", [Key.projectsFeatured]: "精选项目",
[Key.projectsPlanned]: "计划中", [Key.projectsPlanned]: "计划中",
[Key.projectsPaused]: "已暂停",
[Key.projectsDemo]: "在线演示", [Key.projectsDemo]: "在线演示",
[Key.projectsSource]: "源代码", [Key.projectsSource]: "源代码",

View File

@@ -9,7 +9,7 @@ export interface Project {
image: string; image: string;
category: "actual" | "history" | "other"; category: "actual" | "history" | "other";
techStack: string[]; techStack: string[];
status: "completed" | "in-progress" | "planned"; status: "completed" | "in-progress" | "planned" | "paused";
demoUrl?: string; demoUrl?: string;
sourceUrl?: string; sourceUrl?: string;
startDate: string; startDate: string;
@@ -38,12 +38,14 @@ export const getProjectStats = () => {
(p) => p.status === "in-progress", (p) => p.status === "in-progress",
).length; ).length;
const planned = projectsData.filter((p) => p.status === "planned").length; const planned = projectsData.filter((p) => p.status === "planned").length;
const paused = projectsData.filter((p) => p.status === "paused").length;
return { return {
total, total,
byStatus: { byStatus: {
completed, completed,
inProgress, inProgress,
planned, planned,
paused,
}, },
}; };
}; };
@@ -71,9 +73,40 @@ export const getFeaturedProjects = () => {
// Get all tech stacks // Get all tech stacks
export const getAllTechStack = () => { export const getAllTechStack = () => {
const techSet = new Set<string>(); // Создаем Map для хранения информации о каждой технологии
const techMap = new Map<string, { count: number; latestProjectDate: number }>();
// Подсчитываем упоминания и находим самую свежую дату проекта для каждой технологии
projectsData.forEach((project) => { projectsData.forEach((project) => {
project.techStack.forEach((tech) => techSet.add(tech)); const projectDate = new Date(project.startDate).getTime();
project.techStack.forEach((tech) => {
const existing = techMap.get(tech);
if (existing) {
existing.count++;
// Обновляем дату, если текущий проект свежее
if (projectDate > existing.latestProjectDate) {
existing.latestProjectDate = projectDate;
}
} else {
techMap.set(tech, { count: 1, latestProjectDate: projectDate });
}
});
}); });
return Array.from(techSet).sort();
// Преобразуем Map в массив и сортируем
// Сначала по количеству упоминаний (по убыванию), затем по дате самого свежего проекта (по убыванию)
return Array.from(techMap.entries())
.sort((a, b) => {
const [techA, dataA] = a;
const [techB, dataB] = b;
// Сначала сортируем по количеству упоминаний (по убыванию)
if (dataB.count !== dataA.count) {
return dataB.count - dataA.count;
}
// Если количество одинаковое, сортируем по дате самого свежего проекта (по убыванию)
return dataB.latestProjectDate - dataA.latestProjectDate;
})
.map(([tech]) => tech); // Возвращаем только названия технологий
}; };