Merged develop into bug-fixing-13-jan-24

This commit is contained in:
Tiago Ribeiro
2024-01-14 00:09:32 +00:00
4 changed files with 57 additions and 15 deletions

View File

@@ -7,12 +7,13 @@ import UserList from "@/pages/(admin)/Lists/UserList";
import {dateSorter} from "@/utils"; import {dateSorter} from "@/utils";
import moment from "moment"; import moment from "moment";
import {useEffect, useState} from "react"; import {useEffect, useState} from "react";
import {BsArrowLeft, BsBriefcaseFill, BsGlobeCentralSouthAsia, BsPerson, BsPersonFill, BsPencilSquare, BsBank} from "react-icons/bs"; import {BsArrowLeft, BsBriefcaseFill, BsGlobeCentralSouthAsia, BsPerson, BsPersonFill, BsPencilSquare, BsBank, BsCurrencyDollar} from "react-icons/bs";
import UserCard from "@/components/UserCard"; import UserCard from "@/components/UserCard";
import useGroups from "@/hooks/useGroups"; import useGroups from "@/hooks/useGroups";
import IconCard from "./IconCard"; import IconCard from "./IconCard";
import useFilterStore from "@/stores/listFilterStore"; import useFilterStore from "@/stores/listFilterStore";
import {useRouter} from "next/router"; import {useRouter} from "next/router";
import usePaymentStatusUsers from '@/hooks/usePaymentStatusUsers';
interface Props { interface Props {
user: User; user: User;
@@ -26,6 +27,7 @@ export default function AdminDashboard({user}: Props) {
const {stats} = useStats(user.id); const {stats} = useStats(user.id);
const {users, reload} = useUsers(); const {users, reload} = useUsers();
const {groups} = useGroups(); const {groups} = useGroups();
const { pending, done } = usePaymentStatusUsers();
const appendUserFilters = useFilterStore((state) => state.appendUserFilter); const appendUserFilters = useFilterStore((state) => state.appendUserFilter);
const router = useRouter(); const router = useRouter();
@@ -146,6 +148,26 @@ export default function AdminDashboard({user}: Props) {
</> </>
); );
const CorporatePaidStatusList = ({ paid }: {paid: Boolean}) => {
const list = paid ? done : pending;
const filter = (x: User) => x.type === "corporate" && list.includes(x.id);
return (
<>
<div className="flex flex-col gap-4">
<div
onClick={() => setPage("")}
className="flex gap-2 items-center text-mti-purple-light cursor-pointer hover:text-mti-purple-dark transition ease-in-out duration-300">
<BsArrowLeft className="text-xl" />
<span>Back</span>
</div>
<h2 className="text-2xl font-semibold">{paid ? 'Payment Done' : 'Pending Payment'} ({list.length})</h2>
</div>
<UserList user={user} filters={[filter]} />
</>
);
};
const InactiveCountryManagerList = () => { const InactiveCountryManagerList = () => {
return ( return (
<> <>
@@ -243,7 +265,7 @@ export default function AdminDashboard({user}: Props) {
/> />
<IconCard <IconCard
onClick={() => setPage("inactiveStudents")} onClick={() => setPage("inactiveStudents")}
Icon={BsPerson} Icon={BsPersonFill}
label="Inactive Students" label="Inactive Students"
value={ value={
users.filter((x) => x.type === "student" && (x.status === "disabled" || moment().isAfter(x.subscriptionExpirationDate))) users.filter((x) => x.type === "student" && (x.status === "disabled" || moment().isAfter(x.subscriptionExpirationDate)))
@@ -253,7 +275,7 @@ export default function AdminDashboard({user}: Props) {
/> />
<IconCard <IconCard
onClick={() => setPage("inactiveCountryManagers")} onClick={() => setPage("inactiveCountryManagers")}
Icon={BsPerson} Icon={BsBriefcaseFill}
label="Inactive Country Managers" label="Inactive Country Managers"
value={users.filter(inactiveCountryManagerFilter).length} value={users.filter(inactiveCountryManagerFilter).length}
color="rose" color="rose"
@@ -268,6 +290,20 @@ export default function AdminDashboard({user}: Props) {
} }
color="rose" color="rose"
/> />
<IconCard
onClick={() => setPage("paymentdone")}
Icon={BsCurrencyDollar}
label="Payment Done"
value={done.length}
color="purple"
/>
<IconCard
onClick={() => setPage("paymentpending")}
Icon={BsCurrencyDollar}
label="Pending Payment"
value={pending.length}
color="rose"
/>
</section> </section>
<section className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 w-full justify-between"> <section className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 w-full justify-between">
@@ -477,6 +513,8 @@ export default function AdminDashboard({user}: Props) {
{page === "inactiveStudents" && <InactiveStudentsList />} {page === "inactiveStudents" && <InactiveStudentsList />}
{page === "inactiveCorporate" && <InactiveCorporateList />} {page === "inactiveCorporate" && <InactiveCorporateList />}
{page === "inactiveCountryManagers" && <InactiveCountryManagerList />} {page === "inactiveCountryManagers" && <InactiveCountryManagerList />}
{page === "paymentdone" && <CorporatePaidStatusList paid={true} />}
{page === "paymentpending" && <CorporatePaidStatusList paid={false} />}
{page === "" && <DefaultDashboard />} {page === "" && <DefaultDashboard />}
</> </>
); );

View File

@@ -161,7 +161,7 @@ export default function AgentDashboard({user}: Props) {
color="purple" color="purple"
/> />
<IconCard <IconCard
onClick={() => setPage("paymentdone")} onClick={() => setPage("paymentpending")}
Icon={BsCurrencyDollar} Icon={BsCurrencyDollar}
label="Pending Payment" label="Pending Payment"
value={pending.length} value={pending.length}

View File

@@ -103,7 +103,7 @@ export default function BatchCodeGenerator({user}: {user: User}) {
return ( return (
<div className="flex flex-col gap-4 border p-4 border-mti-gray-platinum rounded-xl"> <div className="flex flex-col gap-4 border p-4 border-mti-gray-platinum rounded-xl">
<label className="font-normal text-base text-mti-gray-dim">Choose a .txt file containing e-mails</label> <label className="font-normal text-base text-mti-gray-dim">Choose an Excel file containing e-mails</label>
<Button onClick={openFilePicker} isLoading={isLoading} disabled={isLoading}> <Button onClick={openFilePicker} isLoading={isLoading} disabled={isLoading}>
{filesContent.length > 0 ? filesContent[0].name : "Choose a file"} {filesContent.length > 0 ? filesContent[0].name : "Choose a file"}
</Button> </Button>

View File

@@ -30,16 +30,20 @@ async function get(req: NextApiRequest, res: NextApiResponse) {
return; return;
} }
const codeQuery = query( // if it's an admin, don't apply query filters
collection(db, "payments"), const whereClauses = ["admin", "developer"].includes(req.session.user.type)
? []
: [
// where("agent", "==", "xRMirufz6PPQqxKBgvPTWiWKBD63"), // where("agent", "==", "xRMirufz6PPQqxKBgvPTWiWKBD63"),
where(req.session.user.type, "==", req.session.user.id) where(req.session.user.type, "==", req.session.user.id),
// Based on the logic of query we should be able to do this: // Based on the logic of query we should be able to do this:
// where("isPaid", "==", paid === "paid"), // where("isPaid", "==", paid === "paid"),
// but for some reason it is ignoring all but the first clause // but for some reason it is ignoring all but the first clause
// I opted into only fetching relevant content for the user // I opted into only fetching relevant content for the user
// and then filter it with JS // and then filter it with JS
); ];
const codeQuery = query(collection(db, "payments"), ...whereClauses);
const snapshot = await getDocs(codeQuery); const snapshot = await getDocs(codeQuery);
if (snapshot.empty) { if (snapshot.empty) {