Skip to content

Commit 5b9f4cd

Browse files
committed
feat(ui): unify dashboard animations and FontAwesome icons
1 parent 5866a0c commit 5b9f4cd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+4377
-1296
lines changed

app/(auth)/login/page.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import Link from "next/link";
22
import Image from "next/image";
33
import LoginForm from "@/app/components/auth/LoginForm";
44
import { Metadata } from "next";
5+
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
6+
import { faChevronLeft } from "@fortawesome/free-solid-svg-icons";
57

68
export const metadata: Metadata = {
79
title: "Login - DevPulse",
@@ -63,7 +65,15 @@ export default async function Login(props: {
6365
: undefined;
6466

6567
return (
66-
<div className="min-h-screen flex bg-[#0a0a1a] text-white">
68+
<div className="min-h-screen flex bg-[#0a0a1a] text-white relative">
69+
<Link
70+
href="/"
71+
className="absolute top-5 left-5 sm:top-6 sm:left-6 z-40 inline-flex items-center gap-2 text-sm text-gray-400 hover:text-white transition-colors"
72+
>
73+
<FontAwesomeIcon icon={faChevronLeft} className="w-4 h-4" />
74+
Back
75+
</Link>
76+
6777
{/* Left Side - Visual / Branding */}
6878
<div className="hidden lg:flex lg:w-1/2 relative flex-col justify-between p-12 md:p-16 xl:p-24 border-r border-white/5 bg-gradient-to-br from-[#0a0a1a] to-[#0a0a1a] overflow-hidden">
6979
{/* Background elements */}

app/(auth)/signup/page.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import Link from "next/link";
22
import Image from "next/image";
33
import SignupForm from "@/app/components/auth/SignupForm";
44
import { Metadata } from "next";
5+
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
6+
import { faChevronLeft } from "@fortawesome/free-solid-svg-icons";
57

68
export const metadata: Metadata = {
79
title: "Sign Up - DevPulse",
@@ -50,7 +52,15 @@ export default async function Signup(props: {
5052
: undefined;
5153

5254
return (
53-
<div className="min-h-screen flex bg-[#0a0a1a] text-white">
55+
<div className="min-h-screen flex bg-[#0a0a1a] text-white relative">
56+
<Link
57+
href="/"
58+
className="absolute top-5 left-5 sm:top-6 sm:left-6 z-40 inline-flex items-center gap-2 text-sm text-gray-400 hover:text-white transition-colors"
59+
>
60+
<FontAwesomeIcon icon={faChevronLeft} className="w-4 h-4" />
61+
Back
62+
</Link>
63+
5464
{/* Left Side - Visual / Branding */}
5565
<div className="hidden lg:flex lg:w-1/2 relative flex-col justify-between p-12 md:p-16 xl:p-24 border-r border-white/5 bg-gradient-to-br from-[#0a0a1a] to-[#0a0a1a] overflow-hidden">
5666
{/* Background elements */}

app/(public)/join/[code]/JoinButton.tsx

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ import { createClient } from "../../../lib/supabase/client";
55
import { useRouter } from "next/navigation";
66
import { toast } from "react-toastify";
77
import Link from "next/link";
8+
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
9+
import {
10+
faArrowRightToBracket,
11+
faCheck,
12+
faSpinner,
13+
faUserPlus,
14+
} from "@fortawesome/free-solid-svg-icons";
815

916
export default function JoinButton({
1017
code,
@@ -26,9 +33,7 @@ export default function JoinButton({
2633
href={`/leaderboard/${leaderboardSlug}`}
2734
className="btn-primary inline-flex items-center justify-center gap-2 w-full py-4 text-sm font-bold rounded-xl shadow-lg shadow-indigo-500/20"
2835
>
29-
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
30-
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
31-
</svg>
36+
<FontAwesomeIcon icon={faCheck} className="w-5 h-5" />
3237
<span className="sm:hidden">View</span>
3338
<span className="hidden sm:inline">View Leaderboard</span>
3439
</Link>
@@ -42,9 +47,7 @@ export default function JoinButton({
4247
href={`/login?redirect=${encodeURIComponent(`/join?id=${code}`)}`}
4348
className="btn-primary inline-flex items-center justify-center gap-2 w-full py-4 text-sm font-bold rounded-xl shadow-lg shadow-indigo-500/20"
4449
>
45-
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
46-
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M11 16l-4-4m0 0l4-4m-4 4h14m-5 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h7a3 3 0 013 3v1" />
47-
</svg>
50+
<FontAwesomeIcon icon={faArrowRightToBracket} className="w-5 h-5" />
4851
Log In to Join
4952
</Link>
5053
<p className="text-xs text-gray-500">
@@ -112,17 +115,12 @@ export default function JoinButton({
112115
>
113116
{joining ? (
114117
<>
115-
<svg className="w-5 h-5 animate-spin" fill="none" viewBox="0 0 24 24">
116-
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
117-
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
118-
</svg>
118+
<FontAwesomeIcon icon={faSpinner} className="w-5 h-5 animate-spin" />
119119
Joining...
120120
</>
121121
) : (
122122
<>
123-
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
124-
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M18 9v3m0 0v3m0-3h3m-3 0h-3m-2-5a4 4 0 11-8 0 4 4 0 018 0zM3 20a6 6 0 0112 0v1H3v-1z" />
125-
</svg>
123+
<FontAwesomeIcon icon={faUserPlus} className="w-5 h-5" />
126124
Accept Invite &amp; Join
127125
</>
128126
)}

app/(public)/join/page.tsx

Lines changed: 17 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@ import JoinButton from "./[code]/JoinButton";
44
import Footer from "@/app/components/layout/Footer";
55
import Image from "next/image";
66
import Link from "next/link";
7+
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
8+
import {
9+
faCircleInfo,
10+
faCircleXmark,
11+
faRankingStar,
12+
faUsers,
13+
} from "@fortawesome/free-solid-svg-icons";
714

815
type Props = {
916
searchParams: Promise<{ id?: string }>;
@@ -82,19 +89,10 @@ export default async function JoinPage({ searchParams }: Props) {
8289
<div className="min-h-screen flex items-center justify-center bg-[#0a0a1a] text-white grid-bg">
8390
<div className="glass-card p-10 text-center max-w-md mx-auto">
8491
<div className="w-16 h-16 rounded-full bg-indigo-500/10 border border-indigo-500/20 flex items-center justify-center mx-auto mb-5">
85-
<svg
92+
<FontAwesomeIcon
93+
icon={faCircleInfo}
8694
className="w-8 h-8 text-indigo-400"
87-
fill="none"
88-
viewBox="0 0 24 24"
89-
stroke="currentColor"
90-
>
91-
<path
92-
strokeLinecap="round"
93-
strokeLinejoin="round"
94-
strokeWidth={2}
95-
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
96-
/>
97-
</svg>
95+
/>
9896
</div>
9997
<h1 className="text-xl font-bold text-white mb-2">
10098
Join a Leaderboard
@@ -118,19 +116,10 @@ export default async function JoinPage({ searchParams }: Props) {
118116
<div className="min-h-screen flex items-center justify-center bg-[#0a0a1a] text-white grid-bg">
119117
<div className="glass-card p-10 text-center max-w-md mx-auto">
120118
<div className="w-16 h-16 rounded-full bg-red-500/10 border border-red-500/20 flex items-center justify-center mx-auto mb-5">
121-
<svg
119+
<FontAwesomeIcon
120+
icon={faCircleXmark}
122121
className="w-8 h-8 text-red-400"
123-
fill="none"
124-
viewBox="0 0 24 24"
125-
stroke="currentColor"
126-
>
127-
<path
128-
strokeLinecap="round"
129-
strokeLinejoin="round"
130-
strokeWidth={2}
131-
d="M6 18L18 6M6 6l12 12"
132-
/>
133-
</svg>
122+
/>
134123
</div>
135124
<h1 className="text-xl font-bold text-white mb-2">
136125
Invite Not Found
@@ -195,37 +184,16 @@ export default async function JoinPage({ searchParams }: Props) {
195184

196185
<div className="flex items-center justify-center gap-6 mt-6 mb-8">
197186
<div className="flex items-center gap-2 text-gray-400 text-sm">
198-
<svg
199-
className="w-4 h-4 text-indigo-400"
200-
fill="none"
201-
viewBox="0 0 24 24"
202-
stroke="currentColor"
203-
>
204-
<path
205-
strokeLinecap="round"
206-
strokeLinejoin="round"
207-
strokeWidth={2}
208-
d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0z"
209-
/>
210-
</svg>
187+
<FontAwesomeIcon icon={faUsers} className="w-4 h-4 text-indigo-400" />
211188
<span>
212189
{memberCount} {memberCount === 1 ? "member" : "members"}
213190
</span>
214191
</div>
215192
<div className="flex items-center gap-2 text-gray-400 text-sm">
216-
<svg
193+
<FontAwesomeIcon
194+
icon={faRankingStar}
217195
className="w-4 h-4 text-purple-400"
218-
fill="none"
219-
viewBox="0 0 24 24"
220-
stroke="currentColor"
221-
>
222-
<path
223-
strokeLinecap="round"
224-
strokeLinejoin="round"
225-
strokeWidth={2}
226-
d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"
227-
/>
228-
</svg>
196+
/>
229197
<span>Leaderboard</span>
230198
</div>
231199
</div>

app/(public)/leaderboard/page.tsx

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import CTA from "@/app/components/layout/CTA";
55
import Image from "next/image";
66
import { Metadata } from "next";
77
import { getUserWithProfile } from "@/app/lib/supabase/help/user";
8+
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
9+
import { faArrowRight } from "@fortawesome/free-solid-svg-icons";
810

911
export const metadata: Metadata = {
1012
title: "Leaderboards - DevPulse",
@@ -109,19 +111,7 @@ export default async function Leaderboards() {
109111
</div>
110112
<span className="text-gray-500 text-sm group-hover:text-indigo-400 transition flex items-center gap-2">
111113
View{" "}
112-
<svg
113-
xmlns="http://www.w3.org/2000/svg"
114-
fill="none"
115-
viewBox="0 0 24 24"
116-
strokeWidth={1.5}
117-
stroke="currentColor"
118-
>
119-
<path
120-
strokeLinecap="round"
121-
strokeLinejoin="round"
122-
d="M13.5 4.5L21 12m0 0l-7.5 7.5M21 12H3"
123-
/>
124-
</svg>
114+
<FontAwesomeIcon icon={faArrowRight} className="w-4 h-4" />
125115
</span>
126116
</a>
127117
),

app/(user)/dashboard/settings/page.tsx

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,61 @@
11
import { Metadata } from "next";
22
import UserProfile from "@/app/components/dashboard/Settings/Profile";
33
import ResetPassword from "@/app/components/dashboard/Settings/ResetPassword";
4+
import WakaTimeKey from "@/app/components/dashboard/Settings/WakaTimeKey";
45
import { getUserWithProfile } from "@/app/lib/supabase/help/user";
56
import { redirect } from "next/navigation";
67

78
export const metadata: Metadata = {
89
title: "Settings - DevPulse",
910
};
1011

11-
export default async function LeaderboardsPage() {
12-
const { user } = await getUserWithProfile();
12+
export default async function SettingsPage() {
13+
const { user, profile } = await getUserWithProfile();
1314
if (!user) return redirect("/login?from=/dashboard/settings");
1415

16+
const hasWakaKey = Boolean(profile?.wakatime_api_key);
17+
const maskedWakaKey = profile?.wakatime_api_key
18+
? `${profile.wakatime_api_key.slice(0, 8)}...${profile.wakatime_api_key.slice(-4)}`
19+
: null;
20+
1521
return (
16-
<div className="p-6 md:p-8 space-y-6">
17-
<div>
18-
<h1 className="text-2xl font-bold text-white">Settings</h1>
19-
<p className="text-sm text-gray-600">
20-
Manage your account settings and including your WakaTime API key.
21-
</p>
22+
<div className="p-4 md:p-6 space-y-4 max-w-7xl mx-auto">
23+
<div className="glass-card p-4 md:p-5 border-t-4 border-indigo-500/50">
24+
<div className="flex flex-col md:flex-row md:items-center justify-between gap-4">
25+
<div>
26+
<h1 className="text-xl md:text-2xl font-bold text-white tracking-tight">
27+
Account Settings
28+
</h1>
29+
<p className="text-xs md:text-sm text-gray-400 mt-1">
30+
Manage profile details, WakaTime connection, and account security.
31+
</p>
32+
</div>
33+
34+
<div className="flex items-center gap-2 text-[11px] uppercase tracking-wider">
35+
<span
36+
className={`px-2 py-1 rounded-full border font-semibold ${
37+
hasWakaKey
38+
? "border-emerald-500/30 bg-emerald-500/10 text-emerald-300"
39+
: "border-amber-500/30 bg-amber-500/10 text-amber-300"
40+
}`}
41+
>
42+
{hasWakaKey ? "WakaTime Connected" : "WakaTime Not Connected"}
43+
</span>
44+
</div>
45+
</div>
2246
</div>
2347

2448
{user && (
25-
<>
26-
<UserProfile user={user} />
27-
<ResetPassword user={user} />
28-
</>
49+
<div className="grid grid-cols-1 xl:grid-cols-3 gap-4 items-start">
50+
<div className="xl:col-span-2 space-y-4">
51+
<UserProfile user={user} />
52+
<WakaTimeKey hasKey={hasWakaKey} maskedKey={maskedWakaKey} />
53+
</div>
54+
55+
<div className="xl:col-span-1">
56+
<ResetPassword user={user} />
57+
</div>
58+
</div>
2959
)}
3060
</div>
3161
);

0 commit comments

Comments
 (0)