Skip to content

Commit

Permalink
Merge pull request #11 from hcs-t4sg/background
Browse files Browse the repository at this point in the history
Background
  • Loading branch information
AEst2002 authored Oct 29, 2023
2 parents 7303eaa + d7eeb5c commit 4d5ae3d
Show file tree
Hide file tree
Showing 6 changed files with 836 additions and 130 deletions.
99 changes: 99 additions & 0 deletions app/background/clinician-info-form.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
"use client";

import { toast } from "@/components/ui/use-toast";
import { zodResolver } from "@hookform/resolvers/zod";
import { createClientComponentClient } from "@supabase/auth-helpers-nextjs";
import { useRouter } from "next/navigation";
import { type BaseSyntheticEvent } from "react";
import { useForm } from "react-hook-form";

import { type Database } from "@/lib/schema";
import { clinicianSchema, type ClinicianData } from "./info-schemas";
type Clinician = Database["public"]["Tables"]["clinicians"]["Row"];

export default function ClinicianInfoForm(clinician: Clinician) {
const router = useRouter();

const defaultValues: Partial<ClinicianData> = {
first_name: clinician.first_name ?? undefined,
last_name: clinician.last_name ?? undefined,
employer: clinician.employer ?? undefined,
state: clinician.state ?? undefined,
city: clinician.city ?? undefined,
zip: clinician.zip ?? undefined,
};

const form = useForm<ClinicianData>({
resolver: zodResolver(clinicianSchema),
defaultValues,
mode: "onChange",
});

const onSubmit = async (input: ClinicianData) => {
const supabase = createClientComponentClient<Database>();
const { error } = await supabase
.from("clinicians")
.update({
user_id: clinician.user_id,
...input,
})
.eq("id", clinician.id);

if (error) {
return toast({
title: "Something went wrong.",
description: error.message,
variant: "destructive",
});
}

form.reset(input);
router.refresh();
return toast({
title: "Success!",
description: "Your information has been updated.",
variant: "default",
});
};

return (
<form onSubmit={(e: BaseSyntheticEvent) => void form.handleSubmit(onSubmit)(e)}>
<div>
<label htmlFor="firstname">First Name: &nbsp;</label>
<input type="text" id="firstname" {...form.register("first_name")} />
{form.formState.errors.first_name && <span> (Error: {form.formState.errors.first_name?.message})</span>}
</div>
<div>
<label htmlFor="lastname">Last Name: &nbsp;</label>
<input type="text" id="lastname" {...form.register("last_name")} />
{form.formState.errors.last_name && <span> (Error: {form.formState.errors.last_name?.message})</span>}
</div>
<div>
<label htmlFor="age">Employer: &nbsp;</label>
<input type="text" id="employer" {...form.register("employer")} />
{form.formState.errors.employer && <span> (Error: {form.formState.errors.employer?.message})</span>}
</div>
<div>
<label htmlFor="state">State: &nbsp;</label>
<input type="text" id="state" {...form.register("state")} />
{form.formState.errors.state && <span> (Error: {form.formState.errors.state?.message})</span>}
</div>
<div>
<label htmlFor="city">City: &nbsp;</label>
<input type="text" id="city" {...form.register("city")} />
{form.formState.errors.city && <span> (Error: {form.formState.errors.city?.message})</span>}
</div>
<div>
<label htmlFor="zip">Zip Code: &nbsp;</label>
<input type="text" id="zip" {...form.register("zip")} />
{form.formState.errors.zip && <span> (Error: {form.formState.errors.zip?.message})</span>}
</div>
<div>
<br />
<button type="submit" disabled={form.formState.isSubmitting}>
Submit
</button>
</div>
</form>
);
}
62 changes: 62 additions & 0 deletions app/background/info-schemas.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { z } from "zod";

const patientSchema = z.object({
first_name: z
.string()
.nullable()
.transform((val) => (val?.trim() === "" ? null : val?.trim())),
last_name: z
.string()
.nullable()
.transform((val) => (val?.trim() === "" ? null : val?.trim())),
age: z.coerce
.number()
.int()
.gte(0)
.nullable()
.transform((val) => (val == 0 ? null : val)),
state: z
.string()
.nullable()
.transform((val) => (val?.trim() === "" ? null : val?.trim())),
city: z
.string()
.nullable()
.transform((val) => (val?.trim() === "" ? null : val?.trim())),
zip: z
.string()
.nullable()
.transform((val) => (val?.trim() === "" ? null : val?.trim())),
});

const clinicianSchema = z.object({
first_name: z
.string()
.nullable()
.transform((val) => (val?.trim() === "" ? null : val?.trim())),
last_name: z
.string()
.nullable()
.transform((val) => (val?.trim() === "" ? null : val?.trim())),
employer: z
.string()
.nullable()
.transform((val) => (val?.trim() === "" ? null : val?.trim())),
state: z
.string()
.nullable()
.transform((val) => (val?.trim() === "" ? null : val?.trim())),
city: z
.string()
.nullable()
.transform((val) => (val?.trim() === "" ? null : val?.trim())),
zip: z
.string()
.nullable()
.transform((val) => (val?.trim() === "" ? null : val?.trim())),
});

type PatientData = z.infer<typeof patientSchema>;
type ClinicianData = z.infer<typeof clinicianSchema>;

export { clinicianSchema, patientSchema, type ClinicianData, type PatientData };
32 changes: 32 additions & 0 deletions app/background/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { createServerSupabaseClient } from "@/lib/server-utils";
import { redirect } from "next/navigation";
import ClinicianInfoForm from "./clinician-info-form";
import PatientInfoForm from "./patient-info-form";

export default async function BackgroundInfo() {
const supabase = createServerSupabaseClient();
const {
data: { session },
} = await supabase.auth.getSession();

if (!session) {
redirect("/");
}

// Retrieve user information
const userid = session.user.id;
const { data: patients } = await supabase.from("patients").select().eq("user_id", userid);
const { data: clinicians } = await supabase.from("clinicians").select().eq("user_id", userid);

// Allow size > 1 for now
if (!patients?.length && !clinicians?.length) {
return <>User data not found.</>;
}

return (
<>
{patients?.map((patient) => <PatientInfoForm key={patient.id} {...patient} />)}
{clinicians?.map((clinician) => <ClinicianInfoForm key={clinician.id} {...clinician} />)}
</>
);
}
94 changes: 94 additions & 0 deletions app/background/patient-info-form.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
"use client";

import { toast } from "@/components/ui/use-toast";
import { zodResolver } from "@hookform/resolvers/zod";
import { createClientComponentClient } from "@supabase/auth-helpers-nextjs";
import { useRouter } from "next/navigation";
import { type BaseSyntheticEvent } from "react";
import { useForm } from "react-hook-form";

import { type Database } from "@/lib/schema";
import { patientSchema, type PatientData } from "./info-schemas";
type Patient = Database["public"]["Tables"]["patients"]["Row"];

export default function PatientInfoForm(patient: Patient) {
const router = useRouter();

const defaultValues: Partial<PatientData> = {
first_name: patient.first_name ?? undefined,
last_name: patient.last_name ?? undefined,
age: patient.age ?? undefined,
state: patient.state ?? undefined,
city: patient.city ?? undefined,
zip: patient.zip ?? undefined,
};

const form = useForm<PatientData>({
resolver: zodResolver(patientSchema),
defaultValues,
mode: "onChange",
});

const onSubmit = async (input: PatientData) => {
const supabase = createClientComponentClient<Database>();
const { error } = await supabase
.from("patients")
.update({
user_id: patient.user_id,
...input,
})
.eq("id", patient.id);

if (error) {
return toast({
title: "Something went wrong.",
description: error.message,
variant: "destructive",
});
}

form.reset(input);
router.refresh();
};

return (
<form onSubmit={(e: BaseSyntheticEvent) => void form.handleSubmit(onSubmit)(e)}>
<div>
<label htmlFor="firstname">First Name: &nbsp;</label>
<input type="text" id="firstname" {...form.register("first_name")} />
{form.formState.errors.first_name && <span> (Error: {form.formState.errors.first_name?.message})</span>}
</div>
<div>
<label htmlFor="lastname">Last Name: &nbsp;</label>
<input type="text" id="lastname" {...form.register("last_name")} />
{form.formState.errors.last_name && <span> (Error: {form.formState.errors.last_name?.message})</span>}
</div>
<div>
<label htmlFor="age">Age: &nbsp;</label>
<input type="number" id="age" {...form.register("age")} />
{form.formState.errors.age && <span> (Error: {form.formState.errors.age?.message})</span>}
</div>
<div>
<label htmlFor="state">State: &nbsp;</label>
<input type="text" id="state" {...form.register("state")} />
{form.formState.errors.state && <span> (Error: {form.formState.errors.state?.message})</span>}
</div>
<div>
<label htmlFor="city">City: &nbsp;</label>
<input type="text" id="city" {...form.register("city")} />
{form.formState.errors.city && <span> (Error: {form.formState.errors.city?.message})</span>}
</div>
<div>
<label htmlFor="zip">Zip Code: &nbsp;</label>
<input type="text" id="zip" {...form.register("zip")} />
{form.formState.errors.zip && <span> (Error: {form.formState.errors.zip?.message})</span>}
</div>
<div>
<br />
<button type="submit" disabled={form.formState.isSubmitting}>
Submit
</button>
</div>
</form>
);
}
Loading

0 comments on commit 4d5ae3d

Please sign in to comment.