Skip to content

Commit a91e1a0

Browse files
committed
fixed minor errors
1 parent ab87c71 commit a91e1a0

15 files changed

+1322
-1208
lines changed

public/assets/progress_checkmark.svg

+3
Loading

src/app/create-partner-account/layout.tsx

+6-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
import NavBarLayout from "@/components/NavBarLayout";
44
import { usePathname } from "next/navigation";
5+
import { Open_Sans } from "next/font/google";
6+
const openSans = Open_Sans({
7+
subsets: ["latin"],
8+
display: "swap",
9+
});
510

611
export default function RootLayout({
712
children,
@@ -12,7 +17,7 @@ export default function RootLayout({
1217
const hideNav = pathname.startsWith("/create-partner-account");
1318

1419
return (
15-
<html lang="en">
20+
<html lang="en" className={openSans.className}>
1621
<body>
1722
{hideNav ? (
1823
//if the path starts with /create-partner-account, render children ONLY

src/components/InviteUserForm.tsx

+91-56
Original file line numberDiff line numberDiff line change
@@ -2,106 +2,141 @@
22

33
import { useState } from "react";
44
import { UserType } from "@prisma/client";
5+
import { Open_Sans } from "next/font/google";
6+
import { useRouter } from "next/navigation";
7+
8+
const openSans = Open_Sans({ subsets: ["latin"], weight: ["400", "600", "700"] });
59

610
interface InviteUserFormProps {
711
closeModal: () => void;
812
onSubmit: (role: UserType) => void;
913
}
1014

1115
export default function InviteUserForm({ closeModal, onSubmit }: InviteUserFormProps) {
16+
const router = useRouter();
1217
const [name, setName] = useState("");
1318
const [email, setEmail] = useState("");
1419
const [role, setRole] = useState<UserType | "">("");
15-
const [step, setStep] = useState(1);
20+
const [dropdownOpen, setDropdownOpen] = useState(false);
21+
const [errorMessage, setErrorMessage] = useState("");
22+
const [success, setSuccess] = useState(false);
1623

17-
const handleSubmit = (event: React.FormEvent) => {
24+
const handleSubmit = async (event: React.FormEvent) => {
1825
event.preventDefault();
1926

20-
if (!role) {
21-
console.error("Role is not selected");
27+
if (!name.trim() || !email.trim() || !role) {
28+
setErrorMessage("All fields are required.");
2229
return;
2330
}
2431

25-
if (role === "SUPER_ADMIN" || role === "ADMIN" || role === "STAFF") {
26-
onSubmit(role as UserType);
27-
setStep(2);
28-
} else {
32+
//if the role is PARTNER, go to account creation without sending an invite
33+
if (role === "PARTNER") {
34+
closeModal();
35+
router.push(`/create-partner-account?name=${encodeURIComponent(name)}&email=${encodeURIComponent(email)}`);
36+
return;
37+
}
38+
39+
//otherwise, send invite immediately
40+
try {
41+
const response = await fetch("/api/invites", {
42+
method: "POST",
43+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
44+
body: new URLSearchParams({
45+
email,
46+
name,
47+
userType: role.toUpperCase(),
48+
}).toString(),
49+
});
50+
51+
if (!response.ok) throw new Error("Couldn't send invite.");
52+
53+
setSuccess(true);
2954
onSubmit(role as UserType);
55+
} catch (error) {
56+
setErrorMessage("Couldn't send invite. Please try again.");
3057
}
3158
};
3259

3360
return (
34-
<div className="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50">
35-
<div className="bg-white p-6 rounded-lg shadow-lg w-96">
36-
{step === 1 ? (
61+
<div className={`fixed inset-0 flex items-center justify-center bg-black bg-opacity-50 ${openSans.className}`}>
62+
<div className="bg-white p-6 rounded-[16px] w-[450px] relative">
63+
{success ? (
64+
<>
65+
<h2 className="text-[24px] font-bold text-[#22070B] mb-4">Add new account</h2>
66+
<button className="text-[24px] absolute top-4 right-4 mr-3 text-[#22070B]" onClick={closeModal}></button>
67+
<p className="text-[16px] text-[#22070B]/70 mb-4">
68+
An email has been sent to finalize account creation. This account is currently pending.
69+
</p>
70+
<p className="text-[16px] text-[#22070B]/70 mb-8">
71+
You can view the current status from the account management page.
72+
</p>
73+
<div className="flex justify-center mb-8">
74+
<img src="/assets/blue_arrow.svg" alt="Success" className="w-30 h-30" />
75+
</div>
76+
77+
<button
78+
className="bg-mediumRed text-white px-6 py-3 rounded-[4px] font-semibold w-full"
79+
onClick={closeModal}
80+
>
81+
Back to account management
82+
</button>
83+
</>
84+
) : (
3785
<>
38-
<h2 className="text-xl font-bold mb-4">Add new account</h2>
39-
<button className="absolute top-4 right-4" onClick={closeModal}></button>
86+
<h2 className="text-[24px] font-bold text-[#22070B] mb-4">Add new account</h2>
87+
<button className="absolute top-4 right-4 text-[#22070B]" onClick={closeModal}></button>
4088
<form onSubmit={handleSubmit}>
41-
<label className="block mb-2">Name</label>
89+
<label className="block text-[16px] text-[#22070B] mb-2">Name</label>
4290
<input
4391
type="text"
44-
className="w-full p-2 border rounded mb-2"
92+
className="w-full p-3 border bg-[#F9F9F9] text-[16px] text-[#22070B] rounded-[4px] mb-5"
93+
placeholder="Name"
4594
value={name}
4695
onChange={(e) => setName(e.target.value)}
4796
required
4897
/>
4998

50-
<label className="block mb-2">Email</label>
99+
<label className="block text-[16px] text-[#22070B] mb-2">Email</label>
51100
<input
52101
type="email"
53-
className="w-full p-2 border rounded mb-2"
102+
className="w-full p-3 border bg-[#F9F9F9] text-[16px] text-[#22070B] rounded-[4px] mb-5"
103+
placeholder="Email"
54104
value={email}
55105
onChange={(e) => setEmail(e.target.value)}
56106
required
57107
/>
58108

59-
<label className="block mb-2">Role</label>
60-
<select
61-
className="w-full p-2 border rounded mb-4"
62-
value={role}
63-
onChange={(e) => setRole(e.target.value as UserType)}
64-
required
65-
>
66-
<option value="" disabled>Select a role</option>
67-
{Object.values(UserType).map((roleOption) => (
68-
<option key={roleOption} value={roleOption}>{roleOption}</option>
69-
))}
70-
</select>
71-
72-
<div className="flex justify-between">
73-
<button
74-
type="button"
75-
className="border border-mainRed text-mainRed px-4 py-2 rounded"
76-
onClick={closeModal}
77-
>
109+
<label className="block text-[16px] text-[#22070B] mb-2">Role</label>
110+
<div className="relative w-full">
111+
<button type="button" className="w-full p-3 border bg-[#F9F9F9] text-[16px] text-[#22070B] rounded-[4px] flex justify-between items-center" onClick={() => setDropdownOpen(!dropdownOpen)}>
112+
{role ? role : "Select a role"}
113+
<svg className="w-4 h-4 text-[#6B7280]" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
114+
<path strokeLinecap="round" strokeLinejoin="round" d="M19 9l-7 7-7-7" />
115+
</svg>
116+
</button>
117+
{dropdownOpen && (
118+
<div className="w-full bg-white border rounded-[4px] mt-1">
119+
{(["SUPER_ADMIN", "ADMIN", "STAFF", "PARTNER"]).map((option) => (
120+
<div key={option} className="p-3 text-[16px] text-[#22070B] bg-[#F9F9F9] hover:bg-[#22070B]/10 cursor-pointer" onClick={() => { setRole(option as UserType); setDropdownOpen(false); }}>
121+
{option}
122+
</div>
123+
))}
124+
</div>
125+
)}
126+
</div>
127+
128+
{errorMessage && <p className="text-red-500 text-sm mt-2">{errorMessage}</p>}
129+
130+
<div className="flex justify-between mt-6">
131+
<button type="button" className="border text-mainRed px-6 py-3 rounded-[4px] font-semibold" onClick={closeModal}>
78132
Cancel
79133
</button>
80-
<button
81-
type="submit"
82-
className="bg-mainRed text-white px-4 py-2 rounded"
83-
>
134+
<button type="submit" className="bg-mainRed text-white px-6 py-3 rounded-[4px] font-semibold">
84135
{role === "PARTNER" ? "Next" : "Send invite link"}
85136
</button>
86137
</div>
87138
</form>
88139
</>
89-
) : (
90-
<>
91-
<h2 className="text-xl font-bold mb-4">Add new account</h2>
92-
<button className="absolute top-4 right-4" onClick={closeModal}></button>
93-
<p className="mb-4">An email has been sent to finalize account creation. This account is currently pending.</p>
94-
<p className="mb-4">You can view the current status from the account management page.</p>
95-
<div className="flex justify-center mb-4">
96-
<img src="/assets/blue_arrow.svg" alt="Blue Arrow" className="w-12 h-12" />
97-
</div>
98-
<button
99-
className="bg-mainRed text-white px-4 py-2 rounded w-full"
100-
onClick={closeModal}
101-
>
102-
Back to account management
103-
</button>
104-
</>
105140
)}
106141
</div>
107142
</div>

src/screens/AccountManagementScreen.tsx

+18-17
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import { useState } from "react";
44
import { useRouter } from "next/navigation";
55
import InviteUserForm from "@/components/InviteUserForm";
66
import { UserType } from "@prisma/client";
7+
import { Open_Sans } from "next/font/google";
78

9+
const openSans = Open_Sans({ subsets: ["latin"], weight: ["400", "600", "700"] });
810
export default function AccountManagementScreen() {
911
const router = useRouter();
1012
const [isInviteModalOpen, setInviteModalOpen] = useState(false);
@@ -19,28 +21,27 @@ export default function AccountManagementScreen() {
1921
};
2022

2123
return (
22-
<div className="p-6">
23-
<div className="flex justify-between items-center mb-4">
24-
<h1 className="text-2xl font-semibold">Account Management</h1>
24+
<div className={`p-6 ${openSans.className}`}>
25+
<h1 className="text-2xl font-semibold text-[#22070B] mb-4">
26+
Account Management
27+
</h1>
28+
29+
<div className="flex items-center justify-between mb-4">
30+
<input
31+
type="text"
32+
placeholder="Search"
33+
className="w-full max-w-[80%] p-2 border border-[#22070B]/10
34+
bg-[#F9F9F9] text-[#22070B] text-[16px] rounded-[4px]
35+
placeholder:text-[#22070B]/50 mr-4"
36+
/>
2537
<button
26-
className="bg-mainRed text-white px-4 py-2 rounded"
38+
className="bg-mainRed text-white px-4 py-2 rounded-[4px]
39+
font-semibold"
2740
onClick={() => setInviteModalOpen(true)}
2841
>
29-
+ Add Account
42+
+ Add account
3043
</button>
3144
</div>
32-
33-
<input
34-
type="text"
35-
placeholder="Search"
36-
className="w-full p-2 border rounded mb-4"
37-
/>
38-
<div className="flex space-x-4 border-b mb-4">
39-
<button className="pb-2 font-semibold border-b-2 border-black">All</button>
40-
<button className="pb-2 font-semibold text-gray-500">Hope for Haiti Staff</button>
41-
<button className="pb-2 font-semibold text-gray-500">Partners</button>
42-
</div>
43-
4445
{isInviteModalOpen && (
4546
<InviteUserForm
4647
closeModal={() => setInviteModalOpen(false)}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
"use client";
2+
3+
import React from "react";
4+
5+
interface StepEightProps {
6+
prevStep: () => void;
7+
nextStep: () => void;
8+
handleCancelClick: () => void;
9+
}
10+
11+
export default function StepEight({
12+
prevStep,
13+
nextStep,
14+
handleCancelClick,
15+
}: StepEightProps) {
16+
return (
17+
<>
18+
<h2 className="text-[24px] font-bold text-[#22070B] mb-2 font-[Open_Sans]">
19+
Create partner account
20+
</h2>
21+
<h3 className="text-[18px] font-bold text-[#22070B]/70 mb-5 font-[Open_Sans]">
22+
Staff Information
23+
</h3>
24+
25+
{[
26+
"Number of doctors",
27+
"Number of nurses",
28+
"Number of midwives",
29+
"Number of auxiliaries",
30+
"Number of statisticians",
31+
"Number of pharmacists",
32+
"Number of CHW",
33+
"Number of administrative",
34+
"Number of health officers",
35+
"Total number of staff",
36+
"Other staff not listed",
37+
].map((label, index) => (
38+
<div key={index} className="mb-5">
39+
<label className="block text-[16px] text-[#22070B] mb-2">{label}</label>
40+
<input
41+
className="w-full p-3 border border-[#22070B]/10 bg-[#F9F9F9] text-[16px]
42+
text-[#22070B] placeholder:text-[#22070B]/50 font-[Open_Sans] rounded-[4px]"
43+
placeholder={label}
44+
/>
45+
</div>
46+
))}
47+
48+
<div className="flex justify-between mt-6">
49+
<button className="text-mainRed font-semibold font-[Open_Sans]" onClick={handleCancelClick}>
50+
Cancel account creation
51+
</button>
52+
<div>
53+
<button
54+
className="border border-mainRed text-mainRed px-6 py-3 rounded-[4px] font-semibold mr-4 font-[Open_Sans]"
55+
onClick={prevStep}
56+
>
57+
Previous
58+
</button>
59+
<button
60+
className="bg-mainRed text-white px-6 py-3 rounded-[4px] font-semibold font-[Open_Sans]"
61+
onClick={nextStep}
62+
>
63+
Next
64+
</button>
65+
</div>
66+
</div>
67+
</>
68+
);
69+
}

0 commit comments

Comments
 (0)