Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions app/login/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { redirect } from "next/navigation";
import { auth, signIn } from "@/lib/auth";
import { Button } from "@/components/ui/button";
import {
PageHeader,
HeroBand,
PageShell,
UtilityCard,
} from "@/components/layout/AppChrome";
Expand Down Expand Up @@ -44,9 +44,8 @@ export default async function LoginPage({ searchParams }: LoginPageProps) {
}

return (
<PageShell width="narrow" surface="parchment">
<PageHeader
align="center"
<>
<HeroBand
eyebrow="SNU Google only"
title="뮤런"
description={
Expand All @@ -57,6 +56,8 @@ export default async function LoginPage({ searchParams }: LoginPageProps) {
}
/>

<PageShell width="narrow" surface="parchment">

<UtilityCard className="flex flex-col gap-5">
{errorMessage ? (
<div
Expand All @@ -77,6 +78,7 @@ export default async function LoginPage({ searchParams }: LoginPageProps) {
<p className="mt-6 text-center font-text text-xs leading-none tracking-[-0.12px] text-apple-muted-48">
첫 로그인 후 관리자 승인이 필요합니다.
</p>
</PageShell>
</PageShell>
</>
);
}
85 changes: 67 additions & 18 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { redirect } from "next/navigation";
import { auth, signOut } from "@/lib/auth";
import { Button } from "@/components/ui/button";
import {
PageHeader,
HeroBand,
PageShell,
UtilityCard,
} from "@/components/layout/AppChrome";
Expand All @@ -22,25 +22,60 @@ export default async function HomePage() {
}

return (
<PageShell width="narrow" surface="parchment">
<PageHeader
align="center"
<>
<HeroBand
eyebrow="Animu Running Archive"
title="뮤런"
description={<>안녕하세요, {session.user.name}. 오늘의 러닝 기록을 남겨요.</>}
/>

<UtilityCard className="flex flex-col gap-3">
<Button asChild size="lg" className="w-full">
<Link href="/sessions/new">새 세션 만들기</Link>
</Button>
<Button asChild variant="outline" size="lg" className="w-full">
<Link href="/sessions">전체 아카이브</Link>
</Button>
<Button asChild variant="secondary" size="lg" className="w-full">
<Link href="/me">내 기록</Link>
</Button>
</UtilityCard>
actions={
<>
<Button asChild size="lg">
<Link href="/sessions/new">새 세션 만들기</Link>
</Button>
<Button asChild variant="outline" size="lg" className="border-white bg-transparent text-white">
<Link href="/sessions">아카이브 보기</Link>
</Button>
</>
}
>
<div className="grid gap-px overflow-hidden rounded-[18px] border border-white/10 bg-white/10 sm:grid-cols-3">
<HeroStat label="Surface" value="Parchment" />
<HeroStat label="Accent" value="Action Blue" />
<HeroStat label="Rhythm" value="Run log" />
</div>
</HeroBand>

<PageShell width="content" surface="parchment">

<div className="grid gap-4 md:grid-cols-3">
<UtilityCard className="flex flex-col gap-4">
<span className="font-display text-[28px] font-semibold leading-[1.14] tracking-[0.196px]">Create</span>
<p className="font-text text-sm leading-[1.43] tracking-[-0.224px] text-apple-muted-48">
오늘의 세션을 만들고 사진과 기록을 이어 붙입니다.
</p>
<Button asChild className="mt-auto w-full">
<Link href="/sessions/new">새 세션</Link>
</Button>
</UtilityCard>
<UtilityCard className="flex flex-col gap-4">
<span className="font-display text-[28px] font-semibold leading-[1.14] tracking-[0.196px]">Archive</span>
<p className="font-text text-sm leading-[1.43] tracking-[-0.224px] text-apple-muted-48">
날짜, 장소, 멤버로 지난 러닝의 맥락을 다시 찾습니다.
</p>
<Button asChild variant="outline" className="mt-auto w-full">
<Link href="/sessions">전체 아카이브</Link>
</Button>
</UtilityCard>
<UtilityCard className="flex flex-col gap-4">
<span className="font-display text-[28px] font-semibold leading-[1.14] tracking-[0.196px]">Me</span>
<p className="font-text text-sm leading-[1.43] tracking-[-0.224px] text-apple-muted-48">
누적 거리와 페이스 흐름을 한 화면에서 확인합니다.
</p>
<Button asChild variant="secondary" className="mt-auto w-full">
<Link href="/me">내 기록</Link>
</Button>
</UtilityCard>
</div>

<div className="mt-8 flex items-center justify-center gap-5 font-text text-sm leading-[1.29] tracking-[-0.224px]">
{session.user.role === "ADMIN" && (
Expand All @@ -54,6 +89,20 @@ export default async function HomePage() {
</Button>
</form>
</div>
</PageShell>
</PageShell>
</>
);
}

function HeroStat({ label, value }: { label: string; value: string }) {
return (
<div className="bg-white/[0.03] p-5">
<span className="block font-text text-xs uppercase leading-none tracking-[-0.12px] text-apple-body-muted">
{label}
</span>
<span className="mt-2 block font-display text-[21px] font-semibold leading-[1.19] tracking-[0.231px] text-white">
{value}
</span>
</div>
);
}
12 changes: 7 additions & 5 deletions app/pending/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { requireUser } from "@/lib/guard";
import { signOut } from "@/lib/auth";
import { Button } from "@/components/ui/button";
import {
PageHeader,
HeroBand,
PageShell,
UtilityCard,
} from "@/components/layout/AppChrome";
Expand All @@ -19,9 +19,8 @@ export default async function PendingPage() {
}

return (
<PageShell width="narrow" surface="parchment">
<PageHeader
align="center"
<>
<HeroBand
eyebrow="Approval required"
title="승인 대기 중"
description={
Expand All @@ -32,6 +31,8 @@ export default async function PendingPage() {
}
/>

<PageShell width="narrow" surface="parchment">

<UtilityCard className="flex flex-col gap-5 text-center">
<p className="font-text text-sm leading-[1.43] tracking-[-0.224px] text-apple-muted-48">
단톡방에 운영진에게 가입 요청을 보냈다고 알려주세요.
Expand All @@ -42,6 +43,7 @@ export default async function PendingPage() {
</Button>
</form>
</UtilityCard>
</PageShell>
</PageShell>
</>
);
}
39 changes: 20 additions & 19 deletions app/runners/_components/MemberView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
import type { MemberStats } from "@/lib/members";
import {
BackLink,
PageHeader,
HeroBand,
PageShell,
SectionLabel,
SubNav,
Expand All @@ -29,25 +29,26 @@ export function MemberView({ stats, isSelf }: Props) {
<SubNav title={isSelf ? "내 기록" : "러너 기록"}>
<BackLink href="/sessions">아카이브</BackLink>
</SubNav>
<HeroBand
eyebrow={
<>
{isSelf ? "My running" : "Runner"} · 가입 {formatDate(stats.joinedAt)}
</>
}
title={
<>
{stats.name}
{stats.role === "ADMIN" && (
<span className="ml-3 align-middle rounded-full border border-white/20 px-3 py-1 font-text text-xs font-normal leading-none tracking-[-0.12px] text-white/80">
ADMIN
</span>
)}
</>
}
description="거리, 페이스, 최근 참여 기록을 한 화면에서 확인합니다."
/>

<PageShell width="content" surface="parchment">
<PageHeader
eyebrow={
<>
{isSelf ? "My running" : "Runner"} · 가입 {formatDate(stats.joinedAt)}
</>
}
title={
<>
{stats.name}
{stats.role === "ADMIN" && (
<span className="ml-3 align-middle rounded-full bg-apple-canvas px-3 py-1 font-text text-xs font-normal leading-none tracking-[-0.12px] text-apple-primary">
ADMIN
</span>
)}
</>
}
description="거리, 페이스, 최근 참여 기록을 한 화면에서 확인합니다."
/>

<section className="mb-8 grid gap-4 sm:grid-cols-3">
<Kpi
Expand Down
30 changes: 19 additions & 11 deletions app/sessions/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Button } from "@/components/ui/button";
import { requireApproved } from "@/lib/guard";
import {
BackLink,
PageHeader,
HeroBand,
PageShell,
SectionLabel,
SubNav,
Expand Down Expand Up @@ -98,19 +98,27 @@ export default async function SessionDetailPage({ params }: PageProps) {
<>
<SubNav title="세션">
<BackLink href="/sessions">아카이브</BackLink>
{isHostOrAdmin && (
<Button asChild variant="outline" size="sm">
<Link href={`/sessions/${sessionRow.id}/edit`}>세션 수정</Link>
</Button>
)}
</SubNav>

<HeroBand
eyebrow={formatDateHeader(sessionRow.date)}
title={sessionRow.location}
description={metaLine}
actions={
isHostOrAdmin ? (
<Button
asChild
variant="outline"
size="lg"
className="border-white bg-transparent text-white"
>
<Link href={`/sessions/${sessionRow.id}/edit`}>세션 수정</Link>
</Button>
) : null
}
/>

<PageShell width="content" surface="parchment">
<PageHeader
eyebrow={formatDateHeader(sessionRow.date)}
title={sessionRow.location}
description={metaLine}
/>

<PhotoSection
sessionId={sessionRow.id}
Expand Down
43 changes: 37 additions & 6 deletions app/sessions/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
type SessionArchiveSearchParams,
} from "@/lib/session-filters";
import {
PageHeader,
HeroBand,
PageShell,
SubNav,
UtilityCard,
Expand Down Expand Up @@ -51,12 +51,20 @@ export default async function SessionsArchivePage({ searchParams }: PageProps) {
</Button>
</SubNav>

<HeroBand
eyebrow="Sessions"
title="러닝 아카이브"
description="날짜, 장소, 참여 멤버로 세션을 찾아보세요."
actions={
<Button asChild size="lg">
<Link href="/sessions/new">새 세션 만들기</Link>
</Button>
}
>
<ArchiveSummary />
</HeroBand>

<PageShell width="content" surface="parchment">
<PageHeader
eyebrow="Sessions"
title="러닝 아카이브"
description="날짜, 장소, 참여 멤버로 애니뮤 러닝 세션을 찾아보세요."
/>

<FilterBar
q={filters.q ?? ""}
Expand Down Expand Up @@ -113,3 +121,26 @@ function EmptyFilterResult() {
</UtilityCard>
);
}

function ArchiveSummary() {
return (
<div className="grid gap-px overflow-hidden rounded-[18px] border border-white/10 bg-white/10 sm:grid-cols-3">
<SummaryCell label="Surface" value="Dark tile" />
<SummaryCell label="Flow" value="Filter first" />
<SummaryCell label="Focus" value="Action Blue" />
</div>
);
}

function SummaryCell({ label, value }: { label: string; value: string }) {
return (
<div className="bg-white/[0.03] p-5">
<span className="block font-text text-xs uppercase leading-none tracking-[-0.12px] text-apple-body-muted">
{label}
</span>
<span className="mt-2 block font-display text-[21px] font-semibold leading-[1.19] tracking-[0.231px] text-white">
{value}
</span>
</div>
);
}
Loading
Loading