style(social): elevate Profile + GroupDetailView to SaaS Premium
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
98eab26fa6
commit
a51f67a843
8 changed files with 34 additions and 34 deletions
|
|
@ -9,7 +9,7 @@ const meta: Meta<typeof GroupDetailView> = {
|
|||
tags: ['autodocs'],
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<div className="bg-kodo-background min-h-layout-page-sm p-4">
|
||||
<div className="bg-background min-h-layout-page-sm p-4">
|
||||
<Story />
|
||||
</div>
|
||||
),
|
||||
|
|
|
|||
|
|
@ -24,14 +24,14 @@ export const GroupDetailView: React.FC<GroupDetailViewProps> = ({
|
|||
if (loading) {
|
||||
return (
|
||||
<div className="flex justify-center py-24 min-h-layout-page-sm">
|
||||
<Loader2 className="w-10 h-10 text-kodo-steel animate-spin" />
|
||||
<Loader2 className="w-10 h-10 text-muted-foreground animate-spin" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!group) {
|
||||
return (
|
||||
<div className="text-center py-24 text-kodo-content-dim min-h-layout-page-sm">
|
||||
<div className="text-center py-24 text-muted-foreground min-h-layout-page-sm">
|
||||
Group not found
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -20,15 +20,15 @@ export function GroupDetailViewEvents({ events }: GroupDetailViewEventsProps) {
|
|||
variant="default"
|
||||
className="flex items-center gap-6"
|
||||
>
|
||||
<div className="text-center p-4 bg-kodo-slate rounded-lg min-w-20">
|
||||
<div className="text-xs text-kodo-steel uppercase font-bold">
|
||||
<div className="text-center p-4 bg-muted rounded-xl min-w-20">
|
||||
<div className="text-xs text-muted-foreground uppercase font-bold">
|
||||
{month}
|
||||
</div>
|
||||
<div className="text-2xl font-bold text-white">{day}</div>
|
||||
<div className="text-2xl font-bold text-foreground">{day}</div>
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<h3 className="text-lg font-bold text-white">{event.title}</h3>
|
||||
<div className="flex items-center gap-2 text-kodo-content-dim text-sm mt-1">
|
||||
<h3 className="text-lg font-bold text-foreground tracking-tight">{event.title}</h3>
|
||||
<div className="flex items-center gap-2 text-muted-foreground text-sm mt-1">
|
||||
<Users className="w-4 h-4" /> {event.attendees} Attending
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ export function GroupDetailViewHeader({
|
|||
onLeave,
|
||||
}: GroupDetailViewHeaderProps) {
|
||||
return (
|
||||
<div className="relative rounded-2xl overflow-hidden bg-kodo-graphite border border-kodo-steel">
|
||||
<div className="h-64 bg-kodo-ink relative">
|
||||
<div className="relative rounded-2xl overflow-hidden bg-muted border border-border">
|
||||
<div className="h-64 bg-card relative">
|
||||
<img
|
||||
src={group.coverUrl}
|
||||
alt=""
|
||||
|
|
@ -52,7 +52,7 @@ export function GroupDetailViewHeader({
|
|||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="bg-black/50 backdrop-blur text-kodo-red hover:bg-kodo-red/20 border-none"
|
||||
className="bg-black/50 backdrop-blur text-destructive hover:bg-destructive/20 border-none"
|
||||
onClick={onLeave}
|
||||
>
|
||||
<LogOut className="w-4 h-4 mr-2" /> Leave
|
||||
|
|
@ -69,11 +69,11 @@ export function GroupDetailViewHeader({
|
|||
<div className="flex flex-col md:flex-row justify-between items-start gap-4">
|
||||
<div>
|
||||
<div className="flex items-center gap-4 mb-2">
|
||||
<h1 className="text-3xl font-display font-bold text-white">
|
||||
<h1 className="text-3xl font-display font-bold text-foreground tracking-tight">
|
||||
{group.name}
|
||||
</h1>
|
||||
<span
|
||||
className={`px-2 py-0.5 rounded text-xs font-bold uppercase border flex items-center gap-1 ${group.isPrivate ? 'border-kodo-gold text-kodo-gold' : 'border-kodo-cyan text-kodo-cyan'}`}
|
||||
className={`px-2 py-0.5 rounded text-xs font-bold uppercase border flex items-center gap-1 ${group.isPrivate ? 'border-warning text-warning' : 'border-primary text-primary'}`}
|
||||
>
|
||||
{group.isPrivate ? (
|
||||
<Lock className="w-3 h-3" />
|
||||
|
|
@ -83,26 +83,26 @@ export function GroupDetailViewHeader({
|
|||
{group.isPrivate ? 'Private' : 'Public'}
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-kodo-content-dim max-w-2xl leading-relaxed">
|
||||
<p className="text-muted-foreground max-w-2xl leading-relaxed">
|
||||
{group.description}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-6 text-sm text-kodo-content-dim font-mono bg-kodo-ink/50 p-4 rounded-xl border border-kodo-steel/30">
|
||||
<div className="flex gap-6 text-sm text-muted-foreground font-mono bg-card/50 p-4 rounded-xl border border-border">
|
||||
<div className="text-center">
|
||||
<div className="font-bold text-white text-lg">
|
||||
<div className="font-bold text-foreground text-lg">
|
||||
{group.members.toLocaleString()}
|
||||
</div>
|
||||
<div className="text-xs uppercase">Members</div>
|
||||
</div>
|
||||
<div className="w-px bg-kodo-steel/50" />
|
||||
<div className="w-px bg-border" />
|
||||
<div className="text-center">
|
||||
<div className="font-bold text-white text-lg">124</div>
|
||||
<div className="font-bold text-foreground text-lg">124</div>
|
||||
<div className="text-xs uppercase">Posts</div>
|
||||
</div>
|
||||
<div className="w-px bg-kodo-steel/50" />
|
||||
<div className="w-px bg-border" />
|
||||
<div className="text-center">
|
||||
<div className="font-bold text-white text-lg">
|
||||
<div className="font-bold text-foreground text-lg">
|
||||
{group.events.length}
|
||||
</div>
|
||||
<div className="text-xs uppercase">Events</div>
|
||||
|
|
@ -111,13 +111,13 @@ export function GroupDetailViewHeader({
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div className="px-6 md:px-8 border-t border-kodo-steel/50 flex gap-6 overflow-x-auto">
|
||||
<div className="px-6 md:px-8 border-t border-border flex gap-6 overflow-x-auto">
|
||||
{TABS.map((tab) => (
|
||||
<button
|
||||
key={tab}
|
||||
type="button"
|
||||
onClick={() => onTabChange(tab)}
|
||||
className={`py-4 text-sm font-bold uppercase tracking-wider border-b-2 transition-colors ${activeTab === tab ? 'text-white border-kodo-cyan' : 'text-kodo-content-dim border-transparent hover:text-kodo-text-main'}`}
|
||||
className={`py-4 text-sm font-bold uppercase tracking-wider border-b-2 transition-colors duration-[var(--duration-normal)] ${activeTab === tab ? 'text-foreground border-primary' : 'text-muted-foreground border-transparent hover:text-foreground'}`}
|
||||
>
|
||||
{tab}
|
||||
</button>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ export function GroupDetailViewMembers({
|
|||
{membersList.map((member) => (
|
||||
<div
|
||||
key={member.id}
|
||||
className="flex items-center gap-4 p-4 bg-kodo-ink rounded-lg border border-kodo-steel hover:border-kodo-steel/50 transition-colors"
|
||||
className="flex items-center gap-4 p-4 bg-card rounded-xl border border-border hover:border-border transition-colors duration-[var(--duration-normal)]"
|
||||
>
|
||||
<img
|
||||
src={member.avatar}
|
||||
|
|
@ -23,9 +23,9 @@ export function GroupDetailViewMembers({
|
|||
className="w-12 h-12 rounded-full"
|
||||
/>
|
||||
<div className="flex-1">
|
||||
<div className="font-bold text-white">{member.username}</div>
|
||||
<div className="font-bold text-foreground">{member.username}</div>
|
||||
{member.role && (
|
||||
<span className="text-xs bg-kodo-slate px-1.5 py-0.5 rounded text-kodo-content-dim">
|
||||
<span className="text-xs bg-muted px-1.5 py-0.5 rounded text-muted-foreground">
|
||||
{member.role}
|
||||
</span>
|
||||
)}
|
||||
|
|
@ -35,7 +35,7 @@ export function GroupDetailViewMembers({
|
|||
</Button>
|
||||
</div>
|
||||
))}
|
||||
<div className="col-span-full text-center py-8 text-kodo-content-dim text-sm">
|
||||
<div className="col-span-full text-center py-8 text-muted-foreground text-sm">
|
||||
+ {Math.max(0, totalMembers - membersList.length)} others
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,10 +14,10 @@ export function GroupDetailViewSidebar({
|
|||
return (
|
||||
<div className="lg:col-span-4 space-y-6">
|
||||
<Card variant="default">
|
||||
<h3 className="font-bold text-white mb-4 uppercase text-xs tracking-wider">
|
||||
<h3 className="font-bold text-foreground mb-4 uppercase text-xs tracking-wider">
|
||||
About
|
||||
</h3>
|
||||
<p className="text-sm text-kodo-content-dim mb-4">
|
||||
<p className="text-sm text-muted-foreground mb-4">
|
||||
Created Aug 2022
|
||||
<br />
|
||||
Located in Tokyo, JP
|
||||
|
|
@ -26,7 +26,7 @@ export function GroupDetailViewSidebar({
|
|||
{['Synthesizers', 'Hardware', 'Eurorack', 'Music'].map((tag) => (
|
||||
<span
|
||||
key={tag}
|
||||
className="px-2 py-1 bg-kodo-ink border border-kodo-steel rounded text-xs text-kodo-content-dim"
|
||||
className="px-2 py-1 bg-card border border-border rounded-xl text-xs text-muted-foreground"
|
||||
>
|
||||
#{tag}
|
||||
</span>
|
||||
|
|
@ -35,7 +35,7 @@ export function GroupDetailViewSidebar({
|
|||
</Card>
|
||||
|
||||
<Card variant="glass">
|
||||
<h3 className="font-bold text-white mb-4 uppercase text-xs tracking-wider">
|
||||
<h3 className="font-bold text-foreground mb-4 uppercase text-xs tracking-wider">
|
||||
Group Admins
|
||||
</h3>
|
||||
<div className="flex -space-x-2 overflow-hidden mb-4">
|
||||
|
|
@ -44,7 +44,7 @@ export function GroupDetailViewSidebar({
|
|||
key={m.id}
|
||||
src={m.avatar}
|
||||
alt=""
|
||||
className="inline-block h-8 w-8 rounded-full ring-2 ring-kodo-graphite"
|
||||
className="inline-block h-8 w-8 rounded-full ring-2 ring-border"
|
||||
title={m.username}
|
||||
/>
|
||||
))}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { Skeleton } from '@/components/ui/skeleton';
|
|||
export function GroupDetailViewSkeleton() {
|
||||
return (
|
||||
<div className="space-y-6 pb-20">
|
||||
<div className="rounded-2xl overflow-hidden bg-kodo-graphite border border-kodo-steel">
|
||||
<div className="rounded-2xl overflow-hidden bg-muted border border-border">
|
||||
<Skeleton className="h-64 w-full rounded-none" />
|
||||
<div className="p-6 md:p-8">
|
||||
<div className="flex flex-col md:flex-row justify-between gap-4">
|
||||
|
|
@ -18,7 +18,7 @@ export function GroupDetailViewSkeleton() {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="px-6 md:px-8 border-t border-kodo-steel/50 flex gap-6 py-4">
|
||||
<div className="px-6 md:px-8 border-t border-border flex gap-6 py-4">
|
||||
<Skeleton className="h-4 w-16" />
|
||||
<Skeleton className="h-4 w-20" />
|
||||
<Skeleton className="h-4 w-16" />
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ const meta: Meta<typeof UserProfilePage> = {
|
|||
(Story, context) => {
|
||||
const initialEntries = context.parameters.initialEntries ?? ['/u/demo'];
|
||||
return (
|
||||
<div className="bg-kodo-background min-h-screen">
|
||||
<div className="bg-background min-h-screen">
|
||||
<MemoryRouter initialEntries={initialEntries}>
|
||||
<Routes>
|
||||
<Route path="/u/:username" element={<Story />} />
|
||||
|
|
|
|||
Loading…
Reference in a new issue