Skip to content

Commit

Permalink
feat: simplify setings page (#126)
Browse files Browse the repository at this point in the history
### TL;DR

The settings page was a bit confusing having two paperless settings on different pages so I moved them to the same page. Also, changing info updates the auto fill now
  • Loading branch information
aamirazad authored Aug 21, 2024
1 parent c01ed64 commit 21d187c
Show file tree
Hide file tree
Showing 2 changed files with 165 additions and 116 deletions.
202 changes: 86 additions & 116 deletions src/app/settings/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ import {
} from "@tanstack/react-query";
import { EyeIcon, EyeOffIcon } from "lucide-react";
import type { UsersTableType } from "@/server/db/schema";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import BodyMessage from "@/components/body-message";

const queryClient = new QueryClient();

Expand All @@ -37,99 +45,35 @@ interface FormProps {
userData: UsersTableType;
}

function PaperlessURL({ setActiveTab, userData }: FormProps) {
const [isAutofilled, setIsAutofilled] = useState(false);
const formSchema = z.object({
URL: z.string(),
});

const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
URL: "",
},
});

if (userData.paperlessURL && !isAutofilled) {
form.setValue("URL", userData.paperlessURL);
setIsAutofilled(true);
}

async function onSubmit(values: z.infer<typeof formSchema>) {
if (values.URL == "") {
setActiveTab((prevTab) => prevTab + 2); // Skip api key form
} else {
setActiveTab((prevTab) => prevTab + 1); // Increment activeTab
}
try {
await setUserProperty("paperlessURL", values.URL);
// Operation succeeded, show success toast
toast("Your paperless URL preferences was saved");
// Optionally, move to a new tab or take another action to indicate success
} catch {
// Operation failed, show error toast
toast("Uh oh! Something went wrong.", {
description: "Your Paperless URL preferences were not saved.",
action: {
label: "Go back",
onClick: () => setActiveTab((prevTab) => prevTab - 1), // Go back to try again
},
});
}
}

return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="w-64 space-y-4">
<FormField
control={form.control}
name="URL"
render={({ field }) => (
<FormItem>
<FormLabel>Paperless URL</FormLabel>
<FormControl>
<Input type="url" {...field} />
</FormControl>
<FormDescription>Leave empty to disable</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit">Submit</Button>
</form>
</Form>
);
}

function PaperlessToken({ setActiveTab, userData }: FormProps) {
const [isAutofilled, setIsAutofilled] = useState(false);
function PaperlessCard({ setActiveTab, userData }: FormProps) {
const [isHidden, setIsHidden] = useState(false);

const formSchema = z.object({
token: z.string(),
PaperlessURL: z.string(),
PaperlessToken: z.string(),
});

const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
token: "",
PaperlessURL: userData.paperlessURL ?? "",
PaperlessToken: userData.paperlessToken ?? "",
},
});

if (userData.paperlessToken && !isAutofilled) {
form.setValue("token", userData.paperlessToken);
setIsAutofilled(true);
}

async function onSubmit(values: z.infer<typeof formSchema>) {
setActiveTab((prevTab) => prevTab + 1); // Increment activeTab

try {
await setUserProperty("paperlessToken", values.token);
await setUserProperty("paperlessURL", values.PaperlessURL);
await setUserProperty("paperlessToken", values.PaperlessToken);
// Operation succeeded, show success toast
toast("Your paperless token preferences was saved");
toast("Your paperless preferences was saved");
void queryClient.invalidateQueries({ queryKey: ["userData"] });
// Optionally, move to a new tab or take another action to indicate success
} catch {
// Operation failed, show error toast
toast("Uh oh! Something went wrong.", {
description: "Your Paperless token preferences were not saved.",
description: "Your Paperless preferences were not saved.",
action: {
label: "Go back",
onClick: () => setActiveTab((prevTab) => prevTab - 1), // Go back to try again
Expand All @@ -139,35 +83,64 @@ function PaperlessToken({ setActiveTab, userData }: FormProps) {
}

return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="w-64 space-y-4">
<FormField
control={form.control}
name="token"
render={({ field }) => (
<FormItem>
<FormLabel>Paperless API Token</FormLabel>
<FormControl>
<div className="flex flex-shrink items-center space-x-2">
<Input type={isHidden ? "text" : "password"} {...field} />
{isHidden ? (
<EyeIcon onClick={() => setIsHidden(false)} />
) : (
<EyeOffIcon onClick={() => setIsHidden(true)} />
)}
</div>
</FormControl>
<FormDescription>
You can create (or re-create) an API token by opening the
&quot;My Profile&quot; link in the user dropdown found in the
web UI and clicking the circular arrow button.
</FormDescription>
</FormItem>
)}
/>
<Button type="submit">Submit</Button>
</form>
</Form>
<Card>
<CardHeader>
<CardTitle>Paperless settings</CardTitle>
<CardDescription>Paperless ngx is a pdf organizer</CardDescription>
</CardHeader>
<CardContent className="items-center justify-center">
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="w-64 space-y-4"
>
<FormField
control={form.control}
name="PaperlessURL"
render={({ field }) => (
<FormItem>
<FormLabel>Paperless URL</FormLabel>
<FormControl>
<Input type="url" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="PaperlessToken"
render={({ field }) => (
<FormItem>
<FormItem>
<FormLabel>Paperless API Token</FormLabel>
<FormControl>
<div className="flex flex-shrink items-center space-x-2">
<Input
type={isHidden ? "text" : "password"}
{...field}
/>
{isHidden ? (
<EyeIcon onClick={() => setIsHidden(false)} />
) : (
<EyeOffIcon onClick={() => setIsHidden(true)} />
)}
</div>
</FormControl>
<FormDescription>
You can create (or re-create) an API token by opening the
&quot;My Profile&quot; link in the user dropdown found in
the web UI and clicking the circular arrow button.
</FormDescription>
</FormItem>
</FormItem>
)}
/>
<Button type="submit">Submit</Button>
</form>
</Form>
</CardContent>
</Card>
);
}

Expand Down Expand Up @@ -199,6 +172,7 @@ function WhishperURL({ setActiveTab, userData }: FormProps) {
await setUserProperty("whishperURL", values.URL);
// Operation succeeded, show success toast
toast("Your whishper URL preferences was saved");
void queryClient.invalidateQueries({ queryKey: ["userData"] });
// Optionally, move to a new tab or take another action to indicate success
} catch {
// Operation failed, show error toast
Expand Down Expand Up @@ -263,46 +237,42 @@ const ProgressIndicator: React.FC<ProgressIndicatorProps> = ({

export function Forms() {
const [activeTab, setActiveTab] = useState(0);
const { user: clerkUser, isLoaded } = useUser();
const { user: clerkUser, isLoaded: clerkUserIsLoaded } = useUser();
const pathname = usePathname();

const { data: userData, isLoading } = useQuery({
const { data: userData, isLoading: userDataIsLoading } = useQuery({
queryKey: ["userData"],
queryFn: async () => {
const data = await getUserData();
return data;
},
});

if (!userData || isLoading || !isLoaded) {
if (!userData || userDataIsLoading || !clerkUserIsLoaded) {
return <LoadingSpinner>Loading...</LoadingSpinner>;
} else if (!clerkUser) {
return redirect("/sign-in?redirect=" + pathname);
}

const formElements = [
<PaperlessURL
<PaperlessCard
key="paperlessURL"
setActiveTab={setActiveTab}
userData={userData}
/>,
<PaperlessToken
key="paperlessToken"
setActiveTab={setActiveTab}
userData={userData}
/>,
<WhishperURL
key="paperlessToken"
setActiveTab={setActiveTab}
userData={userData}
/>,
<BodyMessage key="done">All done</BodyMessage>,
];
return (
<>
{formElements[activeTab]}
<ProgressIndicator
activeTab={activeTab}
totalTabs={formElements.length}
totalTabs={formElements.length - 1}
setActiveTab={setActiveTab}
/>
</>
Expand Down
79 changes: 79 additions & 0 deletions src/components/ui/card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import * as React from "react"

import { cn } from "@/lib/utils"

const Card = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn(
"rounded-lg border border-slate-200 bg-white text-slate-950 shadow-sm dark:border-slate-800 dark:bg-slate-950 dark:text-slate-50",
className
)}
{...props}
/>
))
Card.displayName = "Card"

const CardHeader = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("flex flex-col space-y-1.5 p-6", className)}
{...props}
/>
))
CardHeader.displayName = "CardHeader"

const CardTitle = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLHeadingElement>
>(({ className, ...props }, ref) => (
<h3
ref={ref}
className={cn(
"text-2xl font-semibold leading-none tracking-tight",
className
)}
{...props}
/>
))
CardTitle.displayName = "CardTitle"

const CardDescription = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLParagraphElement>
>(({ className, ...props }, ref) => (
<p
ref={ref}
className={cn("text-sm text-slate-500 dark:text-slate-400", className)}
{...props}
/>
))
CardDescription.displayName = "CardDescription"

const CardContent = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
))
CardContent.displayName = "CardContent"

const CardFooter = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("flex items-center p-6 pt-0", className)}
{...props}
/>
))
CardFooter.displayName = "CardFooter"

export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }

0 comments on commit 21d187c

Please sign in to comment.