From 650f8dc719831fee7cf212254c473b1b8267998b Mon Sep 17 00:00:00 2001 From: "diana.dolgolyova" Date: Fri, 20 Mar 2026 14:08:50 +0300 Subject: [PATCH] feat: add short description for team carousel cards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add shortDescription field to TeamMember type - DB migration #11: add short_description column to team_members - Admin editor: separate "Краткое описание (для карточки)" and "Полное описание" - Carousel shows shortDescription with line-clamp-3, falls back to description - Full description shown in "Подробнее" profile view Co-Authored-By: Claude Opus 4.6 (1M context) --- src/app/admin/team/[id]/page.tsx | 12 +++++++++++- .../sections/team/TeamMemberInfo.tsx | 4 ++-- src/lib/db.ts | 19 +++++++++++++++++-- src/types/content.ts | 1 + 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/app/admin/team/[id]/page.tsx b/src/app/admin/team/[id]/page.tsx index 3d69706..9307b64 100644 --- a/src/app/admin/team/[id]/page.tsx +++ b/src/app/admin/team/[id]/page.tsx @@ -20,6 +20,7 @@ interface MemberForm { role: string; image: string; instagram: string; + shortDescription: string; description: string; experience: string[]; victories: VictoryItem[]; @@ -36,6 +37,7 @@ export default function TeamMemberEditorPage() { role: "", image: "/images/team/placeholder.webp", instagram: "", + shortDescription: "", description: "", experience: [], victories: [], @@ -116,6 +118,7 @@ export default function TeamMemberEditorPage() { role: member.role, image: member.image, instagram: username, + shortDescription: member.shortDescription || "", description: member.description || "", experience: member.experience || [], victories: member.victories || [], @@ -302,7 +305,14 @@ export default function TeamMemberEditorPage() { )} setData({ ...data, shortDescription: v })} + rows={2} + placeholder="1-2 предложения для карусели" + /> + setData({ ...data, description: v })} rows={6} diff --git a/src/components/sections/team/TeamMemberInfo.tsx b/src/components/sections/team/TeamMemberInfo.tsx index 78fd618..f837fc9 100644 --- a/src/components/sections/team/TeamMemberInfo.tsx +++ b/src/components/sections/team/TeamMemberInfo.tsx @@ -31,9 +31,9 @@ export function TeamMemberInfo({ members, activeIndex, onSelect, onOpenBio }: Te )} - {member.description && ( + {(member.shortDescription || member.description) && (

- {member.description} + {member.shortDescription || member.description}

)} diff --git a/src/lib/db.ts b/src/lib/db.ts index 935a69f..162d57b 100644 --- a/src/lib/db.ts +++ b/src/lib/db.ts @@ -219,6 +219,16 @@ const migrations: Migration[] = [ } }, }, + { + version: 11, + name: "add_team_short_description", + up: (db) => { + const cols = db.prepare("PRAGMA table_info(team_members)").all() as { name: string }[]; + if (!cols.some((c) => c.name === "short_description")) { + db.exec("ALTER TABLE team_members ADD COLUMN short_description TEXT"); + } + }, + }, ]; function runMigrations(db: Database.Database) { @@ -278,6 +288,7 @@ interface TeamMemberRow { role: string; image: string; instagram: string | null; + short_description: string | null; description: string | null; experience: string | null; victories: string | null; @@ -327,6 +338,7 @@ export function getTeamMembers(): (TeamMember & { id: number })[] { role: r.role, image: r.image, instagram: r.instagram ?? undefined, + shortDescription: r.short_description ?? undefined, description: r.description ?? undefined, experience: parseJsonArray(r.experience), victories: parseVictories(r.victories), @@ -348,6 +360,7 @@ export function getTeamMember( role: r.role, image: r.image, instagram: r.instagram ?? undefined, + shortDescription: r.short_description ?? undefined, description: r.description ?? undefined, experience: parseJsonArray(r.experience), victories: parseVictories(r.victories), @@ -364,14 +377,15 @@ export function createTeamMember( .get() as { max: number }; const result = db .prepare( - `INSERT INTO team_members (name, role, image, instagram, description, experience, victories, education, sort_order) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)` + `INSERT INTO team_members (name, role, image, instagram, short_description, description, experience, victories, education, sort_order) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` ) .run( data.name, data.role, data.image, data.instagram ?? null, + data.shortDescription ?? null, data.description ?? null, data.experience?.length ? JSON.stringify(data.experience) : null, data.victories?.length ? JSON.stringify(data.victories) : null, @@ -393,6 +407,7 @@ export function updateTeamMember( if (data.role !== undefined) { fields.push("role = ?"); values.push(data.role); } if (data.image !== undefined) { fields.push("image = ?"); values.push(data.image); } if (data.instagram !== undefined) { fields.push("instagram = ?"); values.push(data.instagram || null); } + if (data.shortDescription !== undefined) { fields.push("short_description = ?"); values.push(data.shortDescription || null); } if (data.description !== undefined) { fields.push("description = ?"); values.push(data.description || null); } if (data.experience !== undefined) { fields.push("experience = ?"); values.push(data.experience?.length ? JSON.stringify(data.experience) : null); } if (data.victories !== undefined) { fields.push("victories = ?"); values.push(data.victories?.length ? JSON.stringify(data.victories) : null); } diff --git a/src/types/content.ts b/src/types/content.ts index 81f149d..eeb7fdd 100644 --- a/src/types/content.ts +++ b/src/types/content.ts @@ -29,6 +29,7 @@ export interface TeamMember { role: string; image: string; instagram?: string; + shortDescription?: string; description?: string; experience?: string[]; victories?: VictoryItem[];