-
-
Notifications
You must be signed in to change notification settings - Fork 2
Feat: Integrate Auth (supabase) + UI user pages #25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 17 commits
e3eb38c
f1a05c3
7e6030a
9d0fd70
4a81b33
2b08271
d5393af
40e2ff4
c6363f7
cb23602
e88a273
3e4a65c
6857a94
4fdcaf6
c6bcb4f
2bdb1e3
80bd37d
c339ad4
8d0e7c2
2af814c
c788a05
17ef619
ad64840
834ba74
cc9f366
9d4f148
403798b
1b5b179
f92579d
f12afcc
55ccb5c
587f7c8
97262a4
105b831
767e442
f45ad50
c4280b2
4cea79c
7eb356c
7aea44b
78dabd4
3b1b4d2
1ef59eb
e9031a7
5ab6549
3ffcd52
0cec3e6
34b163f
fd77dbb
ab1ff30
da13352
988e7c0
5bf4c38
38cf584
a63f178
4a682de
f79204d
df73c6b
3dd0ca3
2bccec8
361a567
685ade3
985e546
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -42,5 +42,4 @@ yarn-debug.log* | |
| yarn-error.log* | ||
| .pnpm-debug.log* | ||
|
|
||
| .cursor/mcp.json | ||
|
|
||
| .cursor | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,6 @@ | ||
| # For turbo builds, prefixes with NEXT_PUBLIC_ are automatically considered to force a rebuild | ||
| NEXT_PUBLIC_POSTHOG_KEY= | ||
| NEXT_PUBLIC_POSTHOG_HOST= | ||
| NEXT_PUBLIC_POSTHOG_HOST= | ||
| NEXT_PUBLIC_SUPABASE_URL= | ||
| # Make sure to enable RLS and policies to use this key in client | ||
| NEXT_PUBLIC_SUPABASE_ANON_KEY= |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| import { createClient } from "@/lib/supabase/server"; | ||
| import { NextResponse } from "next/server"; | ||
|
|
||
| export async function GET(request: Request) { | ||
| const { searchParams, origin } = new URL(request.url); | ||
| const code = searchParams.get("code"); | ||
| const next = searchParams.get("next") ?? "/"; | ||
|
|
||
alexmarqs marked this conversation as resolved.
Show resolved
Hide resolved
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if (code) { | ||
| const supabase = await createClient(); | ||
| const { error } = await supabase.auth.exchangeCodeForSession(code); | ||
|
|
||
| if (error) { | ||
| console.error("Error exchanging code for session:", error); | ||
| return NextResponse.redirect(`${origin}/auth/auth-code-error`); | ||
| } | ||
| } | ||
|
|
||
| return NextResponse.redirect(`${origin}${next}`); | ||
| } | ||
alexmarqs marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| import { createAdminClient, createClient } from "@/lib/supabase/server"; | ||
| import { NextResponse } from "next/server"; | ||
|
|
||
| export async function POST() { | ||
| try { | ||
| const supabase = await createClient(); | ||
alexmarqs marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| const { data } = await supabase.auth.getClaims(); | ||
|
|
||
| const user = data?.claims; | ||
|
|
||
| if (!user) { | ||
| return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); | ||
| } | ||
|
|
||
| const supabaseAdmin = await createAdminClient(); | ||
|
|
||
| try { | ||
| const { data: files, error: listError } = await supabaseAdmin.storage | ||
| .from("avatars") | ||
| .list(user.sub); | ||
|
|
||
| if (!listError && files && files.length > 0) { | ||
| const pathsToRemove = files.map((f) => `${user.sub}/${f.name}`); | ||
| await supabaseAdmin.storage.from("avatars").remove(pathsToRemove); | ||
| } | ||
| } catch {} | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
|
||
| const { error } = await supabaseAdmin.auth.admin.deleteUser(user.sub); | ||
|
|
||
| if (error) { | ||
| return NextResponse.json({ error: error.message }, { status: 400 }); | ||
| } | ||
|
|
||
| return new Response(null, { status: 204 }); | ||
| } catch (err: unknown) { | ||
| return NextResponse.json( | ||
| { error: err instanceof Error ? err.message : "Internal server error" }, | ||
| { status: 500 }, | ||
| ); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,77 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { GithubLogin } from "@/components/GithubLogin"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { GoHomeLoginButton } from "@/components/GoHomeLoginButton"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { RetroContainer } from "@/components/ui/retro-container"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| APP_URL, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| defaultMetadata, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| defaultOpenGraphMetadata, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| defaultTwitterMetadata, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } from "@/lib/metadata"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import Image from "next/image"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import type { Metadata } from "next/types"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { Suspense } from "react"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import logo from "../../../public/assets/images/logo.png"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const title = "Login | Tech Companies Portugal"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const description = | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "Sign in to your account and join the Portuguese tech community. Access company profiles, discover career opportunities, and stay updated with the latest tech companies in Portugal."; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const keywords = | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "login, sign in, Portuguese tech community, tech companies Portugal, careers, account access"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export const metadata: Metadata = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ...defaultMetadata, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| title, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| keywords, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| alternates: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| canonical: `${APP_URL}/login`, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| openGraph: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ...defaultOpenGraphMetadata, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| title, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| url: `${APP_URL}/login`, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| images: [`api/og?title=${title}&description=${description}`], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| twitter: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ...defaultTwitterMetadata, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| title, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| images: [`api/og?title=${title}&description=${description}`], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+22
to
+43
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use absolute URLs for OpenGraph and Twitter images. Lines 35 and 41 use relative paths for social media images. OpenGraph and Twitter Card specifications require absolute URLs for images to ensure proper rendering when shared on social platforms. Apply this diff to fix the image URLs: openGraph: {
...defaultOpenGraphMetadata,
title,
description,
url: `${APP_URL}/login`,
- images: [`api/og?title=${title}&description=${description}`],
+ images: [`${APP_URL}/api/og?title=${title}&description=${description}`],
},
twitter: {
...defaultTwitterMetadata,
title,
description,
- images: [`api/og?title=${title}&description=${description}`],
+ images: [`${APP_URL}/api/og?title=${title}&description=${description}`],
},📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export default function LoginPage() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="bg-transparent flex-1 flex items-center justify-center p-4"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="w-full max-w-md space-y-6"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Suspense fallback={null}> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <GoHomeLoginButton /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </Suspense> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <RetroContainer className="p-6"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="space-y-4"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="flex items-center justify-center"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Image | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| src={logo} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| alt="Tech Companies Portugal Logo" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| width={50} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| height={50} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="text-center"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <p className="text-muted-foreground"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Join the community and be up to date with the latest tech | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| companies in Portugal. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </p> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="space-y-3"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <GithubLogin /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {/* <GoogleLogin /> */} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </RetroContainer> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| import { Settings } from "@/components/settings"; | ||
|
|
||
| export default function SettingsPage() { | ||
| // let's keep this page here for SSR, possibly to prefech some data on the server side, suspense queries etc. | ||
|
|
||
| return ( | ||
| <> | ||
| <Settings /> | ||
| </> | ||
| ); | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.