feat(frontend): micro-interactions — page-enter transition + MetricTile lift

- Add animate-fade-up utility (reduced-motion aware) and a PageTransition
  wrapper; every dashboard view now rises + settles on mount/route change.
- MetricTile gains a subtle hover lift (-translate-y) + ring-focus glow.
- Theme toggle and command palette (⌘K) already existed and persist; no-op.
This commit is contained in:
asepharyana
2026-08-18 09:50:52 +07:00
parent d78d7a0181
commit 95f2903067
11 changed files with 72 additions and 12 deletions
@@ -1,7 +1,12 @@
import { PageTransition } from "@/components/shared";
import { AnalysisView } from "./view";
export const dynamic = "force-dynamic";
export default function AnalysisPage() {
return <AnalysisView />;
return (
<PageTransition>
<AnalysisView />
</PageTransition>
);
}
@@ -1,3 +1,4 @@
import { PageTransition } from "@/components/shared";
import { getActivity, getDashboardStats } from "@/lib/api/server";
import { DashboardView } from "./view";
@@ -14,5 +15,9 @@ export default async function DashboardPage() {
} catch {
// Backend unavailable — client hooks will surface the error state.
}
return <DashboardView initialStats={stats} initialActivity={activity} />;
return (
<PageTransition>
<DashboardView initialStats={stats} initialActivity={activity} />
</PageTransition>
);
}
@@ -1,3 +1,4 @@
import { PageTransition } from "@/components/shared";
import { getMediaStatus } from "@/lib/api/server";
import { MediaView } from "./view";
@@ -10,5 +11,9 @@ export default async function MediaPage() {
} catch {
/* client hooks surface errors */
}
return <MediaView initialStatus={status} />;
return (
<PageTransition>
<MediaView initialStatus={status} />
</PageTransition>
);
}
@@ -1,3 +1,4 @@
import { PageTransition } from "@/components/shared";
import { getConfig, getGuilds } from "@/lib/api/server";
import { MessagesView } from "./view";
@@ -12,9 +13,11 @@ export default async function MessagesPage() {
/* client hooks surface errors */
}
return (
<MessagesView
initialGuilds={guilds}
initialGuildId={config?.monitorGuildId ?? null}
/>
<PageTransition>
<MessagesView
initialGuilds={guilds}
initialGuildId={config?.monitorGuildId ?? null}
/>
</PageTransition>
);
}
@@ -1,3 +1,4 @@
import { PageTransition } from "@/components/shared";
import { getModerationActions, getModerationStats } from "@/lib/api/server";
import { ModerationView } from "./view";
@@ -14,5 +15,9 @@ export default async function ModerationPage() {
} catch {
/* client hooks surface errors */
}
return <ModerationView initialStats={stats} initialActions={actions} />;
return (
<PageTransition>
<ModerationView initialStats={stats} initialActions={actions} />
</PageTransition>
);
}
@@ -1,3 +1,4 @@
import { PageTransition } from "@/components/shared";
import { getRecordings } from "@/lib/api/server";
import { RecordingsView } from "./view";
@@ -12,5 +13,9 @@ export default async function RecordingsPage() {
} catch {
/* client hooks surface errors */
}
return <RecordingsView initialItems={recordings?.items} />;
return (
<PageTransition>
<RecordingsView initialItems={recordings?.items} />
</PageTransition>
);
}
@@ -1,3 +1,4 @@
import { PageTransition } from "@/components/shared";
import { getGuilds, getVoiceStatus } from "@/lib/api/server";
import { VoiceView } from "./view";
@@ -11,5 +12,9 @@ export default async function VoicePage() {
} catch {
/* client hooks surface errors */
}
return <VoiceView initialStatus={status} initialGuilds={guilds} />;
return (
<PageTransition>
<VoiceView initialStatus={status} initialGuilds={guilds} />
</PageTransition>
);
}