Made it so the admin and agent should also be able to edit the amount each corporate should pay

This commit is contained in:
Tiago Ribeiro
2023-11-26 15:15:58 +00:00
parent a9bbbe8b52
commit ca89261e10
6 changed files with 107 additions and 65 deletions

View File

@@ -70,6 +70,7 @@ export default function Input({
name={name} name={name}
disabled={disabled} disabled={disabled}
onChange={(e) => onChange(e.target.value)} onChange={(e) => onChange(e.target.value)}
min={type === "number" ? 0 : undefined}
placeholder={placeholder} placeholder={placeholder}
className={clsx( className={clsx(
"px-8 py-6 text-sm font-normal bg-white border border-mti-gray-platinum focus:outline-none", "px-8 py-6 text-sm font-normal bg-white border border-mti-gray-platinum focus:outline-none",

View File

@@ -103,7 +103,7 @@ export default function MobileMenu({isOpen, onClose, path, user}: Props) {
)}> )}>
Record Record
</Link> </Link>
{user.type !== "student" && ( {user.type !== "student" && user.type !== "admin" && (
<Link <Link
href="/settings" href="/settings"
className={clsx( className={clsx(

View File

@@ -89,7 +89,7 @@ export default function Sidebar({path, navDisabled = false, focusMode = false, u
)} )}
<Nav disabled={disableNavigation} Icon={BsGraphUp} label="Stats" path={path} keyPath="/stats" isMinimized={isMinimized} /> <Nav disabled={disableNavigation} Icon={BsGraphUp} label="Stats" path={path} keyPath="/stats" isMinimized={isMinimized} />
<Nav disabled={disableNavigation} Icon={BsClockHistory} label="Record" path={path} keyPath="/record" isMinimized={isMinimized} /> <Nav disabled={disableNavigation} Icon={BsClockHistory} label="Record" path={path} keyPath="/record" isMinimized={isMinimized} />
{userType !== "student" && ( {userType !== "student" && userType !== "admin" && (
<Nav <Nav
disabled={disableNavigation} disabled={disableNavigation}
Icon={BsShieldFill} Icon={BsShieldFill}

View File

@@ -18,6 +18,7 @@ import ProfileSummary from "./ProfileSummary";
import Select from "react-select"; import Select from "react-select";
import useUsers from "@/hooks/useUsers"; import useUsers from "@/hooks/useUsers";
import {USER_TYPE_LABELS} from "@/resources/user"; import {USER_TYPE_LABELS} from "@/resources/user";
import {CURRENCIES} from "@/resources/paypal";
const expirationDateColor = (date: Date) => { const expirationDateColor = (date: Date) => {
const momentDate = moment(date); const momentDate = moment(date);
@@ -44,6 +45,9 @@ const UserCard = ({user, loggedInUser, onClose, onViewStudents, onViewTeachers}:
const [companyName, setCompanyName] = useState(user.corporateInformation?.companyInformation.name); const [companyName, setCompanyName] = useState(user.corporateInformation?.companyInformation.name);
const [userAmount, setUserAmount] = useState(user.corporateInformation?.companyInformation.userAmount); const [userAmount, setUserAmount] = useState(user.corporateInformation?.companyInformation.userAmount);
const [referralAgentLabel, setReferralAgentLabel] = useState<string>(); const [referralAgentLabel, setReferralAgentLabel] = useState<string>();
const [paymentValue, setPaymentValue] = useState(user.corporateInformation?.payment?.value);
const [paymentCurrency, setPaymentCurrency] = useState(user.corporateInformation?.payment?.currency);
const [monthlyDuration, setMonthlyDuration] = useState(user.corporateInformation?.monthlyDuration);
const {stats} = useStats(user.id); const {stats} = useStats(user.id);
const {users} = useUsers(); const {users} = useUsers();
@@ -61,9 +65,10 @@ const UserCard = ({user, loggedInUser, onClose, onViewStudents, onViewTeachers}:
}, [users, referralAgent]); }, [users, referralAgent]);
const updateUser = () => { const updateUser = () => {
if (user.type === "corporate" && (!paymentValue || paymentValue < 0))
return toast.error("Please set a price for the user's package before updating!");
if (!confirm(`Are you sure you want to update ${user.name}'s account?`)) return; if (!confirm(`Are you sure you want to update ${user.name}'s account?`)) return;
// TODO: Add the corporate information when it is changed as well
axios axios
.post<{user?: User; ok?: boolean}>(`/api/users/update?id=${user.id}`, { .post<{user?: User; ok?: boolean}>(`/api/users/update?id=${user.id}`, {
...user, ...user,
@@ -74,10 +79,15 @@ const UserCard = ({user, loggedInUser, onClose, onViewStudents, onViewTeachers}:
type === "corporate" type === "corporate"
? { ? {
referralAgent, referralAgent,
monthlyDuration,
companyInformation: { companyInformation: {
companyName, companyName,
userAmount, userAmount,
}, },
payment: {
value: paymentValue,
currency: paymentCurrency,
},
} }
: undefined, : undefined,
}) })
@@ -113,6 +123,94 @@ const UserCard = ({user, loggedInUser, onClose, onViewStudents, onViewTeachers}:
]} ]}
/> />
{user.type === "corporate" && (
<>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 w-full">
<Input
label="Company Name"
type="text"
name="companyName"
onChange={setCompanyName}
placeholder="Enter company name"
defaultValue={companyName}
/>
<Input
label="Amount of Users"
type="number"
name="userAmount"
onChange={(e) => setUserAmount(e ? parseInt(e) : undefined)}
placeholder="Enter amount of users"
defaultValue={userAmount}
/>
<Input
label="Monthly Duration"
type="number"
name="monthlyDuration"
onChange={(e) => setMonthlyDuration(e ? parseInt(e) : undefined)}
placeholder="Enter monthly duration"
defaultValue={userAmount}
/>
<div className="flex flex-col gap-3 w-full">
<label className="font-normal text-base text-mti-gray-dim">Country Manager</label>
{referralAgentLabel && (
<Select
className="px-4 py-4 w-full text-sm font-normal placeholder:text-mti-gray-cool disabled:bg-mti-gray-platinum/40 disabled:text-mti-gray-dim disabled:cursor-not-allowed bg-white rounded-full border border-mti-gray-platinum focus:outline-none"
options={[
{value: "", label: "No referral"},
...users.filter((u) => u.type === "agent").map((x) => ({value: x.id, label: `${x.name} - ${x.email}`})),
]}
defaultValue={{
value: referralAgent,
label: referralAgentLabel,
}}
onChange={(value) => setReferralAgent(value?.value)}
styles={{
control: (styles) => ({
...styles,
paddingLeft: "4px",
border: "none",
outline: "none",
":focus": {
outline: "none",
},
}),
option: (styles, state) => ({
...styles,
backgroundColor: state.isFocused ? "#D5D9F0" : state.isSelected ? "#7872BF" : "white",
color: state.isFocused ? "black" : styles.color,
}),
}}
/>
)}
</div>
<div className="flex flex-col gap-3 w-full lg:col-span-2">
<label className="font-normal text-base text-mti-gray-dim">Pricing</label>
<div className="w-full grid grid-cols-5 gap-2">
<Input
name="paymentValue"
onChange={(e) => setPaymentValue(e ? parseInt(e) : undefined)}
type="number"
defaultValue={paymentValue || 0}
className="col-span-3"
/>
<select
defaultValue={paymentCurrency}
onChange={(e) => setPaymentCurrency(e.target.value)}
className="p-6 col-span-2 w-full min-h-[70px] flex justify-center text-sm font-normal rounded-full border focus:outline-none cursor-pointer bg-white">
{CURRENCIES.map(({label, currency}) => (
<option value={currency} key={currency}>
{label}
</option>
))}
</select>
</div>
</div>
</div>
<Divider className="w-full" />
</>
)}
<section className="flex flex-col gap-4 justify-between"> <section className="flex flex-col gap-4 justify-between">
<div className="flex flex-col md:flex-row gap-8 w-full"> <div className="flex flex-col md:flex-row gap-8 w-full">
<Input <Input
@@ -297,67 +395,6 @@ const UserCard = ({user, loggedInUser, onClose, onViewStudents, onViewTeachers}:
</div> </div>
</> </>
)} )}
{user.type === "corporate" && (
<>
<Divider className="w-full" />
<div className="grid grid-cols-2 gap-8 w-full">
<Input
label="Company Name"
type="text"
name="companyName"
onChange={setCompanyName}
placeholder="Enter company name"
defaultValue={companyName}
/>
<Input
label="Amount of Users"
type="number"
name="userAmount"
onChange={(e) => setUserAmount(e ? parseInt(e) : undefined)}
placeholder="Enter amount of users"
defaultValue={userAmount}
/>
<div className="flex flex-col gap-3 w-full">
<label className="font-normal text-base text-mti-gray-dim">Country Manager</label>
{referralAgentLabel && (
<Select
className="px-4 py-4 w-full text-sm font-normal placeholder:text-mti-gray-cool disabled:bg-mti-gray-platinum/40 disabled:text-mti-gray-dim disabled:cursor-not-allowed bg-white rounded-full border border-mti-gray-platinum focus:outline-none"
options={[
{value: "", label: "No referral"},
...users.filter((u) => u.type === "agent").map((x) => ({value: x.id, label: `${x.name} - ${x.email}`})),
]}
defaultValue={{
value: referralAgent,
label: referralAgentLabel,
}}
onChange={(value) => setReferralAgent(value?.value)}
styles={{
control: (styles) => ({
...styles,
paddingLeft: "4px",
border: "none",
outline: "none",
":focus": {
outline: "none",
},
}),
option: (styles, state) => ({
...styles,
backgroundColor: state.isFocused ? "#D5D9F0" : state.isSelected ? "#7872BF" : "white",
color: state.isFocused ? "black" : styles.color,
}),
}}
/>
)}
</div>
<div className="flex flex-col gap-3 w-full">
<label className="font-normal text-base text-mti-gray-dim">Pricing</label>
</div>
</div>
</>
)}
</section> </section>
<div className="flex gap-4 justify-between mt-4 w-full"> <div className="flex gap-4 justify-between mt-4 w-full">

View File

@@ -25,6 +25,10 @@ export default function AdminDashboard({user}: Props) {
const {users, reload} = useUsers(); const {users, reload} = useUsers();
const {groups} = useGroups(); const {groups} = useGroups();
useEffect(() => {
setInterval(reload, 5000);
}, [reload]);
useEffect(() => { useEffect(() => {
setShowModal(!!selectedUser && page === ""); setShowModal(!!selectedUser && page === "");
}, [selectedUser, page]); }, [selectedUser, page]);

View File

@@ -154,7 +154,7 @@ export default function Home() {
{user.type === "corporate" && <CorporateDashboard user={user} />} {user.type === "corporate" && <CorporateDashboard user={user} />}
{user.type === "agent" && <AgentDashboard user={user} />} {user.type === "agent" && <AgentDashboard user={user} />}
{user.type === "admin" && <AdminDashboard user={user} />} {user.type === "admin" && <AdminDashboard user={user} />}
{user.type === "developer" && <StudentDashboard user={user} />} {user.type === "developer" && <AdminDashboard user={user} />}
</Layout> </Layout>
)} )}
</> </>