-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
9,916 additions
and
12,504 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,86 @@ | ||
import type { LoaderFunction } from "@remix-run/cloudflare"; | ||
import type { ActionFunction, LoaderFunction } from "@remix-run/cloudflare"; | ||
import { json } from "@remix-run/cloudflare"; | ||
import { getSession } from "~/auth.server"; | ||
import { getSession, getSupabase } from "~/auth.server"; | ||
import type { AuthUser } from "@supabase/supabase-js"; | ||
import { useLoaderData } from "@remix-run/react"; | ||
import { Typography } from "@supabase/ui"; | ||
import { Form, useLoaderData } from "@remix-run/react"; | ||
import { Button, Input, Loading, Typography } from "@supabase/ui"; | ||
import { useTransition } from "@remix-run/react"; | ||
import type { definitions } from "~/types/supabase"; | ||
|
||
type UserProfile = { | ||
authUser: AuthUser; | ||
user: definitions["users"] | null; | ||
}; | ||
|
||
export const action: ActionFunction = async ({ request, context }) => { | ||
const session = await getSession(context, request); | ||
const supabase = await getSupabase(context, session); | ||
const formData = await request.formData(); | ||
const { error } = await supabase.from("users").upsert({ | ||
id: session.user?.id, | ||
email: session.user?.email, | ||
full_name: formData.get("fullname"), | ||
display_name: formData.get("displayname"), | ||
}); | ||
if (error) throw error; | ||
return {}; | ||
}; | ||
|
||
export const loader: LoaderFunction = async ({ request, context }) => { | ||
const session = await getSession(context, request) | ||
const session = await getSession(context, request); | ||
const supabase = await getSupabase(context, session); | ||
const { data, error } = await supabase | ||
.from<definitions["users"]>("users") | ||
.select("id,email,full_name,display_name") | ||
.eq("id", session.user?.id || "") | ||
.maybeSingle(); | ||
|
||
if (!session.user) throw new Response("No user found", { status: 401 }) | ||
if (error) throw error; | ||
|
||
return json<AuthUser>(session.user) | ||
} | ||
return json<UserProfile>({ | ||
authUser: session.user ?? (() => {throw new Error('No bonus')})(), | ||
user: data, | ||
}); | ||
}; | ||
|
||
const Profile = () => { | ||
const user = useLoaderData<AuthUser>() | ||
const userProfile = useLoaderData<UserProfile>(); | ||
const { state } = useTransition(); | ||
const email = userProfile.authUser.email; | ||
const fullName = | ||
userProfile.user?.full_name || | ||
userProfile.authUser.user_metadata?.full_name || | ||
""; | ||
const displayName = | ||
userProfile.user?.display_name || | ||
(userProfile.authUser.user_metadata?.full_name || "").split(" ")[0]; | ||
return ( | ||
<> | ||
<Typography.Title level={1}>User Profile</Typography.Title> | ||
<Typography.Text>Hello {user.email}! Full user data:</Typography.Text> | ||
<Typography.Text><pre>{JSON.stringify(user, undefined, 2)}</pre></Typography.Text> | ||
<Loading active={state === "submitting"}> | ||
<Form method="post" replace> | ||
<div className="sbui-space-col sbui-space-y-3"> | ||
<Input name="email" label="Email" value={email} disabled /> | ||
<Input | ||
name="fullname" | ||
label="Full Name" | ||
placeholder="Full Name" | ||
defaultValue={fullName} | ||
/> | ||
<Input | ||
name="displayname" | ||
label="Display Name" | ||
placeholder="Display Name" | ||
defaultValue={displayName} | ||
/> | ||
<Button htmlType="submit" disabled={state === "submitting"}> | ||
{state === "submitting" ? "Saving..." : "Save"} | ||
</Button> | ||
</div> | ||
</Form> | ||
</Loading> | ||
</> | ||
) | ||
} | ||
); | ||
}; | ||
|
||
export default Profile | ||
export default Profile; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
/** | ||
* This file was auto-generated by openapi-typescript. | ||
* Do not make direct changes to the file. | ||
*/ | ||
|
||
export interface paths { | ||
"/": { | ||
get: { | ||
responses: { | ||
/** OK */ | ||
200: unknown; | ||
}; | ||
}; | ||
}; | ||
"/users": { | ||
get: { | ||
parameters: { | ||
query: { | ||
id?: parameters["rowFilter.users.id"]; | ||
created_at?: parameters["rowFilter.users.created_at"]; | ||
full_name?: parameters["rowFilter.users.full_name"]; | ||
display_name?: parameters["rowFilter.users.display_name"]; | ||
email?: parameters["rowFilter.users.email"]; | ||
/** Filtering Columns */ | ||
select?: parameters["select"]; | ||
/** Ordering */ | ||
order?: parameters["order"]; | ||
/** Limiting and Pagination */ | ||
offset?: parameters["offset"]; | ||
/** Limiting and Pagination */ | ||
limit?: parameters["limit"]; | ||
}; | ||
header: { | ||
/** Limiting and Pagination */ | ||
Range?: parameters["range"]; | ||
/** Limiting and Pagination */ | ||
"Range-Unit"?: parameters["rangeUnit"]; | ||
/** Preference */ | ||
Prefer?: parameters["preferCount"]; | ||
}; | ||
}; | ||
responses: { | ||
/** OK */ | ||
200: { | ||
schema: definitions["users"][]; | ||
}; | ||
/** Partial Content */ | ||
206: unknown; | ||
}; | ||
}; | ||
post: { | ||
parameters: { | ||
body: { | ||
/** users */ | ||
users?: definitions["users"]; | ||
}; | ||
query: { | ||
/** Filtering Columns */ | ||
select?: parameters["select"]; | ||
}; | ||
header: { | ||
/** Preference */ | ||
Prefer?: parameters["preferReturn"]; | ||
}; | ||
}; | ||
responses: { | ||
/** Created */ | ||
201: unknown; | ||
}; | ||
}; | ||
delete: { | ||
parameters: { | ||
query: { | ||
id?: parameters["rowFilter.users.id"]; | ||
created_at?: parameters["rowFilter.users.created_at"]; | ||
full_name?: parameters["rowFilter.users.full_name"]; | ||
display_name?: parameters["rowFilter.users.display_name"]; | ||
email?: parameters["rowFilter.users.email"]; | ||
}; | ||
header: { | ||
/** Preference */ | ||
Prefer?: parameters["preferReturn"]; | ||
}; | ||
}; | ||
responses: { | ||
/** No Content */ | ||
204: never; | ||
}; | ||
}; | ||
patch: { | ||
parameters: { | ||
query: { | ||
id?: parameters["rowFilter.users.id"]; | ||
created_at?: parameters["rowFilter.users.created_at"]; | ||
full_name?: parameters["rowFilter.users.full_name"]; | ||
display_name?: parameters["rowFilter.users.display_name"]; | ||
email?: parameters["rowFilter.users.email"]; | ||
}; | ||
body: { | ||
/** users */ | ||
users?: definitions["users"]; | ||
}; | ||
header: { | ||
/** Preference */ | ||
Prefer?: parameters["preferReturn"]; | ||
}; | ||
}; | ||
responses: { | ||
/** No Content */ | ||
204: never; | ||
}; | ||
}; | ||
}; | ||
} | ||
|
||
export interface definitions { | ||
/** @description stores users */ | ||
users: { | ||
/** | ||
* Format: uuid | ||
* @description Note: | ||
* This is a Primary Key.<pk/> | ||
*/ | ||
id: string; | ||
/** | ||
* Format: timestamp with time zone | ||
* @default now() | ||
*/ | ||
created_at: string; | ||
/** Format: text */ | ||
full_name: string; | ||
/** Format: text */ | ||
display_name: string; | ||
/** Format: text */ | ||
email: string; | ||
}; | ||
} | ||
|
||
export interface parameters { | ||
/** @description Preference */ | ||
preferParams: "params=single-object"; | ||
/** @description Preference */ | ||
preferReturn: "return=representation" | "return=minimal" | "return=none"; | ||
/** @description Preference */ | ||
preferCount: "count=none"; | ||
/** @description Filtering Columns */ | ||
select: string; | ||
/** @description On Conflict */ | ||
on_conflict: string; | ||
/** @description Ordering */ | ||
order: string; | ||
/** @description Limiting and Pagination */ | ||
range: string; | ||
/** | ||
* @description Limiting and Pagination | ||
* @default items | ||
*/ | ||
rangeUnit: string; | ||
/** @description Limiting and Pagination */ | ||
offset: string; | ||
/** @description Limiting and Pagination */ | ||
limit: string; | ||
/** @description users */ | ||
"body.users": definitions["users"]; | ||
/** Format: uuid */ | ||
"rowFilter.users.id": string; | ||
/** Format: timestamp with time zone */ | ||
"rowFilter.users.created_at": string; | ||
/** Format: text */ | ||
"rowFilter.users.full_name": string; | ||
/** Format: text */ | ||
"rowFilter.users.display_name": string; | ||
/** Format: text */ | ||
"rowFilter.users.email": string; | ||
} | ||
|
||
export interface operations {} | ||
|
||
export interface external {} |
Oops, something went wrong.