feat: Featured technique card with gradient border and enriched recent-…
- "frontend/src/api/public-client.ts" - "frontend/src/pages/CreatorDetail.tsx" - "frontend/src/App.css" GSD-Task: S03/T02
This commit is contained in:
parent
371494c2f8
commit
ef52ef6967
3 changed files with 126 additions and 18 deletions
|
|
@ -2806,6 +2806,60 @@ a.app-footer__repo:hover {
|
|||
line-height: 1.4;
|
||||
}
|
||||
|
||||
/* ── Creator Featured Technique ─────────────────────────────────────── */
|
||||
|
||||
.creator-featured {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
margin-bottom: 1.25rem;
|
||||
padding: 1.25rem 1.5rem;
|
||||
background: var(--color-bg-surface);
|
||||
border: 1px solid transparent;
|
||||
border-image: linear-gradient(135deg, #22d3ee, #a855f7) 1;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.creator-featured__label {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.creator-featured__title {
|
||||
display: block;
|
||||
font-size: 1.25rem;
|
||||
font-weight: 700;
|
||||
color: var(--color-text);
|
||||
margin-bottom: 0.5rem;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.creator-featured:hover .creator-featured__title {
|
||||
color: var(--color-accent-hover);
|
||||
}
|
||||
|
||||
.creator-featured__summary {
|
||||
font-size: 0.875rem;
|
||||
color: var(--color-text-secondary);
|
||||
line-height: 1.5;
|
||||
margin-bottom: 0.75rem;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.creator-featured__meta {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.creator-featured__moments {
|
||||
font-size: 0.75rem;
|
||||
color: var(--color-text-tertiary);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* ══════════════════════════════════════════════════════════════════════════════
|
||||
TOPICS BROWSE — Card Grid Layout
|
||||
══════════════════════════════════════════════════════════════════════════════ */
|
||||
|
|
|
|||
|
|
@ -178,6 +178,9 @@ export interface CreatorTechniqueItem {
|
|||
title: string;
|
||||
slug: string;
|
||||
topic_category: string;
|
||||
summary: string | null;
|
||||
topic_tags: string[] | null;
|
||||
key_moment_count: number;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import {
|
|||
import CreatorAvatar from "../components/CreatorAvatar";
|
||||
import { SocialIcon } from "../components/SocialIcons";
|
||||
import SortDropdown from "../components/SortDropdown";
|
||||
import TagList from "../components/TagList";
|
||||
import { catSlug } from "../utils/catSlug";
|
||||
import { useDocumentTitle } from "../hooks/useDocumentTitle";
|
||||
import { useSortPreference } from "../hooks/useSortPreference";
|
||||
|
|
@ -184,25 +185,75 @@ export default function CreatorDetail() {
|
|||
{techniques.length === 0 ? (
|
||||
<div className="empty-state">No techniques yet.</div>
|
||||
) : (
|
||||
<div className="creator-techniques__list">
|
||||
{techniques.map((t, i) => (
|
||||
<Link
|
||||
key={t.slug}
|
||||
to={`/techniques/${t.slug}`}
|
||||
className="creator-technique-card card-stagger"
|
||||
style={{ '--stagger-index': i } as React.CSSProperties}
|
||||
>
|
||||
<span className="creator-technique-card__title">
|
||||
{t.title}
|
||||
</span>
|
||||
<span className="creator-technique-card__meta">
|
||||
<span className="badge badge--category">
|
||||
{t.topic_category}
|
||||
<>
|
||||
{/* Featured technique — first in sorted order */}
|
||||
{techniques[0] != null && (() => {
|
||||
const featured = techniques[0];
|
||||
return (
|
||||
<Link
|
||||
to={`/techniques/${featured.slug}`}
|
||||
className="creator-featured"
|
||||
>
|
||||
<span className="creator-featured__label section-heading section-heading--accent">
|
||||
Featured Technique
|
||||
</span>
|
||||
</span>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
<span className="creator-featured__title">
|
||||
{featured.title}
|
||||
</span>
|
||||
{featured.summary && (
|
||||
<p className="creator-featured__summary">
|
||||
{featured.summary}
|
||||
</p>
|
||||
)}
|
||||
<span className="creator-featured__meta">
|
||||
<span className={`badge badge--cat-${catSlug(featured.topic_category)}`}>
|
||||
{featured.topic_category}
|
||||
</span>
|
||||
{featured.topic_tags && featured.topic_tags.length > 0 && (
|
||||
<TagList tags={featured.topic_tags} max={4} pillClass="pill--tag" />
|
||||
)}
|
||||
</span>
|
||||
<span className="creator-featured__moments">
|
||||
{featured.key_moment_count} moment{featured.key_moment_count !== 1 ? "s" : ""}
|
||||
</span>
|
||||
</Link>
|
||||
);
|
||||
})()}
|
||||
|
||||
{/* Remaining techniques — recent-card grid */}
|
||||
{techniques.length > 1 && (
|
||||
<div className="creator-techniques__list">
|
||||
{techniques.slice(1).map((t, i) => (
|
||||
<Link
|
||||
key={t.slug}
|
||||
to={`/techniques/${t.slug}`}
|
||||
className="recent-card card-stagger"
|
||||
style={{ '--stagger-index': i } as React.CSSProperties}
|
||||
>
|
||||
<span className="recent-card__title">
|
||||
{t.title}
|
||||
</span>
|
||||
{t.summary && (
|
||||
<span className="recent-card__summary">
|
||||
{t.summary}
|
||||
</span>
|
||||
)}
|
||||
<span className="recent-card__meta">
|
||||
<span className={`badge badge--cat-${catSlug(t.topic_category)}`}>
|
||||
{t.topic_category}
|
||||
</span>
|
||||
{t.topic_tags && t.topic_tags.length > 0 && (
|
||||
<TagList tags={t.topic_tags} max={3} pillClass="pill--tag" />
|
||||
)}
|
||||
</span>
|
||||
<span className="recent-card__moments">
|
||||
{t.key_moment_count} moment{t.key_moment_count !== 1 ? "s" : ""}
|
||||
</span>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</section>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue