Skip to content

Commit

Permalink
UI improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
phukon committed Mar 23, 2024
1 parent ca53e28 commit 60b83ab
Show file tree
Hide file tree
Showing 13 changed files with 633 additions and 306 deletions.
2 changes: 1 addition & 1 deletion src/actions/getNotionToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { getUserById } from "@/data/user";
import { currentUser } from "@/lib/auth";
import { db } from "@/lib/db";
// import { db } from "@/lib/db";

export const getNotionToken = async () => {
try {
Expand Down
16 changes: 0 additions & 16 deletions src/app/api/notion-auth-redirect/route.ts

This file was deleted.

3 changes: 2 additions & 1 deletion src/app/api/notion/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ export async function GET(): Promise<Response> {
}

// Extracting data and processing it
const wordArray = await extractNotionData(id);
const token = (dbUser.notionDetails as { access_token: string }).access_token;
const wordArray = await extractNotionData(token, id);
const combinedString = wordArray.join(" ");

keyValuePairs[url] = combinedString;
Expand Down
38 changes: 26 additions & 12 deletions src/app/auth/notionAuth/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
import { useSearchParams } from "next/navigation";
import { useCallback, useEffect, useState } from "react";
import { notionOAuth } from "@/actions/notionOAuth";
import CardWrapper from "@/components/auth/CardWrapper";
import { BeatLoader } from "react-spinners";
import FormSuccess from "@/components/form-success";
import FormError from "@/components/form-error";

const NotionAuth = () => {
const [error, setError] = useState<string | undefined>();
Expand All @@ -10,7 +14,7 @@ const NotionAuth = () => {
const searchParams = useSearchParams();
const code = searchParams.get("code");
// const state = searchParams.get("state"); Might use later.
const errorParam = searchParams.get("error");
// const errorParam = searchParams.get("error");

const onSubmit = useCallback(() => {
if (success || error) return;
Expand All @@ -28,22 +32,32 @@ const NotionAuth = () => {
.catch(() => {
setError("Something went wrong!");
});

// newVerification(token)
// .then((data) => {
// setSuccess(data.success);
// setError(data.error);
// })
// .catch(() => {
// setError("Something went wrong!");
// });
}, [code, errorParam, success, error]);
}, [code, success, error]);

useEffect(() => {
onSubmit();
}, [onSubmit]);

return <div>NotionAuth</div>;
return (
<div className="min-h-screen flex flex-col lg:flex-row bg-gray-100 overflow-x-hidden">
<div className="flex-1 relative flex justify-center items-center">
<div className=" bg-contain md:bg-fixed bg-center absolute inset-0 bg-[url('/showcase/cat.png')] md:bg-[url('/showcase/plant.png')]" />
<div className="bg-white bg-opacity-45 rounded-lg shadow-md p-8 md:mx-8 relative z-10">
<CardWrapper
headerLabel="Confirming your verification"
backButtonLabel="Back to settings"
backButtonHref="/dash/settings"
>
<div className="flex items-center w-full justify-center">
{!success && !error && <BeatLoader />}
<FormSuccess message={success} />
{!success && <FormError message={error} />}
</div>
</CardWrapper>
</div>
</div>
</div>
);
};

export default NotionAuth;
272 changes: 272 additions & 0 deletions src/app/dash/settings/_.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,272 @@
/**
* This is server side action.
* I may use it in the future again.
*/

/* import { auth, signOut } from '@/auth';
const SettingsPage = async () => {
const session = await auth();
return (
<div>
{JSON.stringify(session)}
<form
action={async () => {
'use server';
await signOut(); // this signOut function was made exclusively for server actions
}}
>
<button type="submit">Sign out</button>
</form>
</div>
);
};
export default SettingsPage;
*/

// -------------------------------------

/**
* This is a combination of server action and a client component!
*/
// 'use client';
// import { logout } from '@/actions/logout';
// import { useCurrentUser } from '@/hooks/use-current-user';

// const SettingsPage = () => {
// const user = useCurrentUser();
// const onClick = () => {
// logout();
// };

// return (
// <div className=' bg-white p-10 rounded-xl'>
// <button onClick={onClick}>Sign out</button>
// </div>
// );
// };

// export default SettingsPage;

"use client";

import * as z from "zod";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { useTransition, useState } from "react";
import { useSession } from "next-auth/react";

import { Switch } from "@/components/ui/switch";
// import {
// Select,
// SelectContent,
// SelectItem,
// SelectTrigger,
// SelectValue,
// } from "@/components/ui/select";
import { SettingsSchema } from "@/schemas";
import { Card, CardHeader, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { settings } from "@/actions/settings";
import {
Form,
FormField,
FormControl,
FormItem,
FormLabel,
FormDescription,
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { useCurrentUser } from "@/hooks/use-current-user";
import FormError from "@/components/form-error";
import FormSuccess from "@/components/form-success";
import { UserRole } from "@prisma/client";
import { UserInfo } from "@/components/user-info";
import Link from "next/link";

const SettingsPage = () => {
const user = useCurrentUser();

const [error, setError] = useState<string | undefined>();
const [success, setSuccess] = useState<string | undefined>();
const { update } = useSession();
const [isPending, startTransition] = useTransition();

const form = useForm<z.infer<typeof SettingsSchema>>({
resolver: zodResolver(SettingsSchema),
defaultValues: {
password: undefined,
newPassword: undefined,
name: user?.name || undefined,
email: user?.email || undefined,
role: user?.role || undefined,
isTwoFactorEnabled: user?.isTwoFactorEnabled || undefined,
},
});

const onSubmit = (values: z.infer<typeof SettingsSchema>) => {
startTransition(() => {
settings(values)
.then((data) => {
if (data.error) {
setError(data.error);
}

if (data.success) {
update();
setSuccess(data.success);
}
})
.catch(() => setError("Something went wrong!"));
});
};

return (
<div className=" flex flex-col">
<UserInfo label="Profile details" user={user} />
<Card className="min-w-[350px] max-w-[600px] md:max-w-full shadow-none border-none md:shadow-lg">
<CardHeader>
<p className="text-2xl font-semibold text-center">⚙️ Settings</p>
</CardHeader>
<CardContent>
<Form {...form}>
<form className="space-y-6" onSubmit={form.handleSubmit(onSubmit)}>
<div className="space-y-4">
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>Name</FormLabel>
<FormControl>
<Input {...field} placeholder="John Doe" disabled={isPending} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
{user?.isOAuth === false && (
<>
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem>
<FormLabel>Email</FormLabel>
<FormControl>
<Input
{...field}
placeholder="[email protected]"
type="email"
disabled={isPending}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="password"
render={({ field }) => (
<FormItem>
<FormLabel>Password</FormLabel>
<FormControl>
<Input
{...field}
placeholder="******"
type="password"
disabled={isPending}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="newPassword"
render={({ field }) => (
<FormItem>
<FormLabel>New Password</FormLabel>
<FormControl>
<Input
{...field}
placeholder="******"
type="password"
disabled={isPending}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</>
)}
{/* <FormField
control={form.control}
name="role"
render={({ field }) => (
<FormItem>
<FormLabel>Role</FormLabel>
<Select
disabled={isPending}
onValueChange={field.onChange}
defaultValue={field.value}
>
<FormControl>
<SelectTrigger>
<SelectValue placeholder="Select a role" />
</SelectTrigger>
</FormControl>
<SelectContent>
<SelectItem value={UserRole.ADMIN}>Admin</SelectItem>
<SelectItem value={UserRole.USER}>User</SelectItem>
</SelectContent>
</Select>
<FormMessage />
</FormItem>
)}
/> */}
{user?.isOAuth === false && (
<FormField
control={form.control}
name="isTwoFactorEnabled"
render={({ field }) => (
<FormItem className="flex flex-row items-center justify-between rounded-lg border p-3 shadow-sm">
<div className="space-y-0.5">
<FormLabel>Two Factor Authentication</FormLabel>
<FormDescription>
Enable two factor authentication for your account
</FormDescription>
</div>
<FormControl>
<Switch
disabled={isPending}
checked={field.value}
onCheckedChange={field.onChange}
/>
</FormControl>
</FormItem>
)}
/>
)}
</div>
<FormError message={error} />
<FormSuccess message={success} />
<Button disabled={isPending} type="submit">
Save
</Button>
</form>
</Form>
</CardContent>
</Card>
</div>
);
};

export default SettingsPage;
Loading

0 comments on commit 60b83ab

Please sign in to comment.