Skip to content

Commit

Permalink
Better loading and error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
evadecker committed Nov 30, 2024
1 parent 81e2e60 commit 302279f
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,10 @@ const DeleteAccountModal = ({
clearLocalStorage();
signOut();
onSubmit();
toast("Account deleted.");
toast.success("Account deleted.");
} catch (err) {
setError("Failed to delete account. Please try again.");
} finally {
setIsDeleting(false);
}
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
Banner,
Button,
Form,
Modal,
Expand All @@ -7,13 +8,14 @@ import {
Select,
SelectItem,
} from "@/components/common";
import { SettingsItem } from "@/components/settings";
import { api } from "@convex/_generated/api";
import type { Doc } from "@convex/_generated/dataModel";
import { JURISDICTIONS, type Jurisdiction } from "@convex/constants";
import { useMutation } from "convex/react";
import { Pencil } from "lucide-react";
import { useState } from "react";
import { SettingsItem } from "../SettingsItem";
import { toast } from "sonner";

type EditBirthplaceModalProps = {
defaultBirthplace: Jurisdiction;
Expand All @@ -28,13 +30,31 @@ const EditBirthplaceModal = ({
onOpenChange,
onSubmit,
}: EditBirthplaceModalProps) => {
const [birthplace, setBirthplace] = useState<Jurisdiction>(defaultBirthplace);
const [error, setError] = useState<string>();
const [isSubmitting, setIsSubmitting] = useState(false);

const updateBirthplace = useMutation(api.users.setBirthplace);
const [birthplace, setBirthplace] = useState(defaultBirthplace);

const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
updateBirthplace({ birthplace });
onSubmit();
setError(undefined);

if (!birthplace) {
setError("Please select a state.");
return;
}

try {
setIsSubmitting(true);
await updateBirthplace({ birthplace });
onSubmit();
toast.success("Birthplace updated.");
} catch (err) {
setError("Failed to update birthplace. Please try again.");
} finally {
setIsSubmitting(false);
}
};

return (
Expand All @@ -44,13 +64,18 @@ const EditBirthplaceModal = ({
description="Where were you born? This location is used to select the forms for your birth certificate."
/>
<Form onSubmit={handleSubmit} className="w-full">
{error && <Banner variant="danger">{error}</Banner>}
<Select
label="State"
name="birthplace"
selectedKey={birthplace}
onSelectionChange={(key) => setBirthplace(key as Jurisdiction)}
placeholder="Select state"
onSelectionChange={(key) => {
setBirthplace(key as Jurisdiction);
setError(undefined);
}}
isRequired
className="w-full"
placeholder="Select state"
>
{Object.entries(JURISDICTIONS).map(([value, label]) => (
<SelectItem key={value} id={value}>
Expand All @@ -59,10 +84,14 @@ const EditBirthplaceModal = ({
))}
</Select>
<ModalFooter>
<Button variant="secondary" onPress={() => onOpenChange(false)}>
<Button
variant="secondary"
onPress={() => onOpenChange(false)}
isDisabled={isSubmitting}
>
Cancel
</Button>
<Button type="submit" variant="primary">
<Button type="submit" variant="primary" isDisabled={isSubmitting}>
Save
</Button>
</ModalFooter>
Expand All @@ -89,9 +118,9 @@ export const EditBirthplaceSetting = ({ user }: EditBirthplaceSettingProps) => {
: "Set birthplace"}
</Button>
<EditBirthplaceModal
defaultBirthplace={user.birthplace as Jurisdiction}
isOpen={isBirthplaceModalOpen}
onOpenChange={setIsBirthplaceModalOpen}
defaultBirthplace={user.birthplace as Jurisdiction}
onSubmit={() => setIsBirthplaceModalOpen(false)}
/>
</SettingsItem>
Expand Down
15 changes: 13 additions & 2 deletions src/components/settings/EditNameSetting/EditNameSetting.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type { Doc } from "@convex/_generated/dataModel";
import { useMutation } from "convex/react";
import { Pencil } from "lucide-react";
import { useState } from "react";
import { toast } from "sonner";
import { SettingsItem } from "../SettingsItem";

type EditNameModalProps = {
Expand All @@ -30,20 +31,26 @@ const EditNameModal = ({
const updateName = useMutation(api.users.setName);
const [name, setName] = useState(defaultName);
const [error, setError] = useState<string>();
const [isSubmitting, setIsSubmitting] = useState(false);

const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
setError(undefined);

if (name.length > 100) {
setError("Name must be less than 100 characters");
return;
}

try {
setIsSubmitting(true);
await updateName({ name: name.trim() });
onSubmit();
toast.success("Name updated.");
} catch (err) {
setError("Failed to update name. Please try again.");
} finally {
setIsSubmitting(false);
}
};

Expand All @@ -67,10 +74,14 @@ const EditNameModal = ({
isRequired
/>
<ModalFooter>
<Button variant="secondary" onPress={() => onOpenChange(false)}>
<Button
variant="secondary"
isDisabled={isSubmitting}
onPress={() => onOpenChange(false)}
>
Cancel
</Button>
<Button type="submit" variant="primary">
<Button type="submit" variant="primary" isDisabled={isSubmitting}>
Save
</Button>
</ModalFooter>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
Banner,
Button,
Form,
Modal,
Expand All @@ -14,6 +15,7 @@ import { JURISDICTIONS, type Jurisdiction } from "@convex/constants";
import { useMutation } from "convex/react";
import { Pencil } from "lucide-react";
import { useState } from "react";
import { toast } from "sonner";

type EditResidenceModalProps = {
defaultResidence: Jurisdiction;
Expand All @@ -28,13 +30,31 @@ const EditResidenceModal = ({
onOpenChange,
onSubmit,
}: EditResidenceModalProps) => {
const [residence, setResidence] = useState<Jurisdiction>(defaultResidence);
const [error, setError] = useState<string>();
const [isSubmitting, setIsSubmitting] = useState(false);

const updateResidence = useMutation(api.users.setResidence);
const [residence, setResidence] = useState(defaultResidence);

const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
updateResidence({ residence });
onSubmit();
setError(undefined);

if (!residence) {
setError("Please select a state.");
return;
}

try {
setIsSubmitting(true);
await updateResidence({ residence });
onSubmit();
toast.success("Residence updated.");
} catch (err) {
setError("Failed to update residence. Please try again.");
} finally {
setIsSubmitting(false);
}
};

return (
Expand All @@ -44,13 +64,18 @@ const EditResidenceModal = ({
description="Where do you live? This location is used to select the forms for your court order and state ID."
/>
<Form onSubmit={handleSubmit} className="w-full">
{error && <Banner variant="danger">{error}</Banner>}
<Select
label="State"
name="residence"
selectedKey={residence}
onSelectionChange={(key) => setResidence(key as Jurisdiction)}
placeholder="Select state"
onSelectionChange={(key) => {
setResidence(key as Jurisdiction);
setError(undefined);
}}
isRequired
className="w-full"
placeholder="Select state"
>
{Object.entries(JURISDICTIONS).map(([value, label]) => (
<SelectItem key={value} id={value}>
Expand All @@ -59,10 +84,14 @@ const EditResidenceModal = ({
))}
</Select>
<ModalFooter>
<Button variant="secondary" onPress={() => onOpenChange(false)}>
<Button
variant="secondary"
onPress={() => onOpenChange(false)}
isDisabled={isSubmitting}
>
Cancel
</Button>
<Button type="submit" variant="primary">
<Button type="submit" variant="primary" isDisabled={isSubmitting}>
Save
</Button>
</ModalFooter>
Expand Down

0 comments on commit 302279f

Please sign in to comment.