Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Improve Review Form #55

Merged
merged 8 commits into from
Apr 14, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions public/svg/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 1 addition & 3 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ export default function RootLayout({
suppressHydrationWarning
>
<body className={cn("min-h-screen bg-white font-sans antialiased")}>
<TRPCReactProvider>
<HeaderLayout>{children}</HeaderLayout>
</TRPCReactProvider>
<TRPCReactProvider>{children}</TRPCReactProvider>
</body>
</html>
);
Expand Down
3 changes: 2 additions & 1 deletion src/components/form/company-details-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { Textarea } from "~/components/ui/textarea";

type CompanyDetailsSectionProps = {
companyName: string;
textColor: string;
};

/**
Expand All @@ -27,7 +28,7 @@ export function CompanyDetailsSection(props: CompanyDetailsSectionProps) {
const [otherBenefits, setOtherBenefits] = useState(false);

return (
<FormSection title="Company Details" className="text-cooper-red-500">
<FormSection title="Company Details" className={props.textColor}>
<FormField
control={form.control}
name="workEnvironment"
Expand Down
4 changes: 2 additions & 2 deletions src/components/form/coop-cycle-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import dayjs from "dayjs";
/**
* CoopCycleSection component renders form fields for selecting co-op cycle and year.
*/
export function CoopCycleSection() {
export function CoopCycleSection({ textColor }: { textColor: string }) {
const form = useFormContext();

// Need to evaluate whether this is a bad idea
Expand All @@ -26,7 +26,7 @@ export function CoopCycleSection() {
);

return (
<FormSection title="Co-op Cycle" className="text-cooper-pink-500">
<FormSection title="Co-op Cycle" className={textColor}>
<FormField
control={form.control}
name="workTerm"
Expand Down
4 changes: 2 additions & 2 deletions src/components/form/ratings-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ import { Rating } from "~/components/ui/rating";
* RatingsSection component renders form fields for rating various
* aspects of a co-op experience.
*/
export function RatingsSection() {
export function RatingsSection({ textColor }: { textColor: string }) {
const form = useFormContext();

return (
<FormSection title="Ratings" className="text-cooper-green-500">
<FormSection title="Ratings" className={textColor}>
<FormField
control={form.control}
name="overallRating"
Expand Down
155 changes: 137 additions & 18 deletions src/components/form/review-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import { Company, WorkEnvironment, WorkTerm } from "@prisma/client";
import { api } from "~/trpc/react";
import { cn } from "~/lib/utils";
import { animateScroll as scroll } from "react-scroll";
import Image from "next/image";
import { CheckIcon } from "@radix-ui/react-icons";

const formSchema = z.object({
workTerm: z.nativeEnum(WorkTerm, {
Expand Down Expand Up @@ -119,12 +121,25 @@ export const benefits = [
{ field: "freeMerch", label: "Free merchandise" },
];

const steps: { fields: string[]; color: string }[] = [
// This object is CURSED. It's a mess to maintain and update.
// Find a better way of linking the colors to the steps.
// Tailwind needs complete utility classes so we can't do "border-" + steps[currentStep - 1]?.borderColor
const steps: {
label: string;
fields: string[];
borderColor: string;
textColor: string;
bgColor: string;
}[] = [
{
label: "Co-op Cycle",
fields: ["workTerm", "workYear"],
color: "border-cooper-pink-500",
borderColor: "border-cooper-yellow-500",
textColor: "text-cooper-yellow-500",
bgColor: "bg-cooper-yellow-500",
},
{
label: "Ratings",
fields: [
"overallRating",
"cultureRating",
Expand All @@ -133,13 +148,19 @@ const steps: { fields: string[]; color: string }[] = [
"interviewDifficulty",
"interviewReview",
],
color: "border-cooper-green-500",
borderColor: "border-cooper-yellow-600",
textColor: "text-cooper-yellow-600",
bgColor: "bg-cooper-yellow-600",
},
{
label: "Review",
fields: ["reviewHeadline", "textReview", "location", "hourlyPay"],
color: "border-cooper-yellow-500",
borderColor: "border-cooper-green-500",
textColor: "text-cooper-green-500",
bgColor: "bg-cooper-green-500",
},
{
label: "Company Details",
fields: [
"workEnvironment",
"drugTest",
Expand All @@ -151,7 +172,9 @@ const steps: { fields: string[]; color: string }[] = [
"freeMerch",
"otherBenefits",
],
color: "border-cooper-red-500",
borderColor: "border-cooper-blue-800",
textColor: "text-cooper-blue-800",
bgColor: "bg-cooper-blue-800",
},
];

Expand Down Expand Up @@ -199,7 +222,7 @@ export function ReviewForm(props: ReviewFormProps) {

const next = async (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
e.preventDefault();
const fields = steps[currentStep]?.fields;
const fields = steps[currentStep - 1]?.fields;
const output = await form.trigger(fields as FieldName[], {
shouldFocus: true,
});
Expand All @@ -208,8 +231,8 @@ export function ReviewForm(props: ReviewFormProps) {
return;
}

if (currentStep < steps.length) {
if (currentStep === steps.length - 1) {
if (currentStep <= steps.length) {
if (currentStep === steps.length) {
await form.handleSubmit(onSubmit)();
}
setCurrentStep((step) => step + 1);
Expand All @@ -235,35 +258,131 @@ export function ReviewForm(props: ReviewFormProps) {
});
}

if (currentStep === steps.length) {
if (currentStep === steps.length + 1) {
// Also check if the mutation is successful before displaying this. Otherwise, show a loading spinner.
return <SubmissionConfirmation />;
}

if (currentStep === 0) {
return (
<div className="flex flex-col border-2">
<div className="z-10 -mb-4 h-4 w-full rounded-t-xl bg-cooper-blue-700" />
<div className="flex h-[80vh] w-full items-center justify-center rounded-xl bg-white pl-24 pr-4 text-cooper-blue-600">
<div className="flex w-1/2 flex-col space-y-6">
<h1 className="text-4xl font-semibold text-cooper-blue-700">
Submit a Co-op Review!
</h1>
<p className="text-2xl text-cooper-blue-700">
Thank you for taking the time to leave a review of your co-op
experience! Join others in the Northeastern community and help
people like yourself make the right career decision.
</p>
<Button
className="w-1/2"
onClick={() => {
setCurrentStep((step) => step + 1);
}}
>
Start a review
</Button>
</div>
<Image
src="/svg/logo.svg"
alt="Co-op Review Logo"
width={650}
height={650}
/>
</div>
</div>
);
}

function ProgressBar() {
const grayBorder = "border-gray-400";
const grayText = "text-gray-400";

return (
<div className="flex justify-between">
{steps.map((progress, index) => (
<div className="flex flex-col items-center space-y-4" key={index}>
{currentStep > index + 1 ? (
<div
className={cn(
"flex h-12 w-12 items-center justify-center rounded-full",
progress.bgColor,
)}
>
<CheckIcon className="h-12 w-12 font-bold text-white" />
</div>
) : (
<div
className={cn(
"flex h-12 w-12 items-center justify-center rounded-full border-[3px]",
currentStep > index ? progress.borderColor : grayBorder,
)}
>
<h1
className={cn(
"text-xl font-semibold",
currentStep > index ? progress.textColor : grayText,
)}
>
{index + 1}
</h1>
</div>
)}
<p
className={cn(
"text-lg font-semibold",
currentStep > index ? progress.textColor : grayText,
)}
>
{progress.label}
</p>
</div>
))}
</div>
);
}

return (
<Form {...form}>
<form
className={cn(
"space-y-12 rounded-2xl border-t-[16px] bg-white px-32 py-16",
steps[currentStep]?.color,
"space-y-8 rounded-2xl border-t-[16px] bg-white px-32 py-16",
steps[currentStep - 1]?.borderColor,
)}
>
{currentStep == 0 && <CoopCycleSection />}
{currentStep == 1 && <RatingsSection />}
{currentStep == 2 && <ReviewSection />}
<ProgressBar />
<div className="w-full border border-blue-100"></div>
{currentStep === 1 && (
<CoopCycleSection
textColor={steps[currentStep - 1]?.textColor || ""}
/>
)}
{currentStep == 2 && (
<RatingsSection textColor={steps[currentStep - 1]?.textColor || ""} />
)}
{currentStep == 3 && (
<CompanyDetailsSection companyName={props.company.name} />
<ReviewSection textColor={steps[currentStep - 1]?.textColor || ""} />
)}
{currentStep == 4 && (
<CompanyDetailsSection
companyName={props.company.name}
textColor={steps[currentStep - 1]?.textColor || ""}
/>
)}
{currentStep >= 0 && currentStep <= steps.length - 1 && (
{currentStep >= 1 && currentStep <= steps.length && (
<div className="flex justify-end space-x-4">
<Button
variant="outline"
onClick={prev}
disabled={currentStep === 0}
disabled={currentStep === 1}
>
Previous
</Button>
<Button onClick={next}>
{currentStep == steps.length - 1 ? "Submit" : "Save and continue"}
{currentStep == steps.length ? "Submit" : "Save and continue"}
</Button>
</div>
)}
Expand Down
4 changes: 2 additions & 2 deletions src/components/form/review-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ import { useFormContext } from "react-hook-form";
/**
* ReviewSection component renders form fields for writing a co-op review.
*/
export function ReviewSection() {
export function ReviewSection({ textColor }: { textColor: string }) {
const form = useFormContext();

return (
<FormSection title="Review" className="text-cooper-yellow-500">
<FormSection title="Review" className={textColor}>
<FormField
control={form.control}
name="reviewHeadline"
Expand Down
1 change: 1 addition & 0 deletions src/components/header-layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use client";
import { ReactNode } from "react";
import Header from "~/components/header";
import { useRouter } from "next/navigation";

/**
* This should be used when placing content under the header, standardizes how children are placed under a header.
Expand Down
Loading
Loading