Merge branch 'main' into develop

This commit is contained in:
Tiago Ribeiro
2024-05-27 16:37:09 +01:00
6 changed files with 58 additions and 67 deletions

View File

@@ -20,6 +20,7 @@ interface Props {
export default function PaymobPayment({user, price, setIsPaymentLoading, currency, duration, duration_unit, onSuccess}: Props) { export default function PaymobPayment({user, price, setIsPaymentLoading, currency, duration, duration_unit, onSuccess}: Props) {
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
console.log(user.id);
const router = useRouter(); const router = useRouter();

View File

@@ -19,11 +19,10 @@ import moment from "moment";
interface Props { interface Props {
user: User; user: User;
hasExpired?: boolean; hasExpired?: boolean;
clientID: string;
reload: () => void; reload: () => void;
} }
export default function PaymentDue({user, hasExpired = false, clientID, reload}: Props) { export default function PaymentDue({user, hasExpired = false, reload}: Props) {
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [appliedDiscount, setAppliedDiscount] = useState(0); const [appliedDiscount, setAppliedDiscount] = useState(0);
@@ -137,7 +136,6 @@ export default function PaymentDue({user, hasExpired = false, clientID, reload}:
</div> </div>
)} )}
<PaymobPayment <PaymobPayment
key={clientID}
user={user} user={user}
setIsPaymentLoading={setIsLoading} setIsPaymentLoading={setIsLoading}
onSuccess={() => { onSuccess={() => {
@@ -177,7 +175,6 @@ export default function PaymentDue({user, hasExpired = false, clientID, reload}:
{user.corporateInformation.payment.value} {user.corporateInformation.payment.currency} {user.corporateInformation.payment.value} {user.corporateInformation.payment.currency}
</span> </span>
<PaymobPayment <PaymobPayment
key={clientID}
user={user} user={user}
setIsPaymentLoading={setIsLoading} setIsPaymentLoading={setIsLoading}
currency={user.corporateInformation.payment.currency} currency={user.corporateInformation.payment.currency}

View File

@@ -41,7 +41,12 @@ async function post(req: NextApiRequest, res: NextApiResponse) {
const response = await axios.post<IntentionResult>( const response = await axios.post<IntentionResult>(
"https://oman.paymob.com/v1/intention/", "https://oman.paymob.com/v1/intention/",
{...intention, payment_methods: [parseInt(process.env.PAYMOB_INTEGRATION_ID || "0")], items: []}, {
...intention,
payment_methods: [parseInt(process.env.PAYMOB_INTEGRATION_ID || "0")],
items: [],
extras: {...intention.extras, userID: req.session.user!.id},
} as PaymentIntention,
{headers: {Authorization: `Token ${process.env.PAYMOB_SECRET_KEY}`}}, {headers: {Authorization: `Token ${process.env.PAYMOB_SECRET_KEY}`}},
); );
const intentionResult = response.data; const intentionResult = response.data;

View File

@@ -22,8 +22,9 @@ async function post(req: NextApiRequest, res: NextApiResponse) {
const transactionResult = req.body as TransactionResult; const transactionResult = req.body as TransactionResult;
const authToken = await authenticatePaymob(); const authToken = await authenticatePaymob();
console.log("WEBHOOK: ", transactionResult);
if (!checkTransaction(authToken, transactionResult.transaction.order.id)) return res.status(404).json({ok: false}); if (!checkTransaction(authToken, transactionResult.transaction.order.id)) return res.status(404).json({ok: false});
if (!transactionResult.transaction.success) return res.status(200).json({ok: false}); if (!transactionResult.transaction.success) return res.status(400).json({ok: false});
const {userID, duration, duration_unit} = transactionResult.intention.extras.creation_extras as { const {userID, duration, duration_unit} = transactionResult.intention.extras.creation_extras as {
userID: string; userID: string;
@@ -42,9 +43,9 @@ async function post(req: NextApiRequest, res: NextApiResponse) {
const initialDate = moment(subscriptionExpirationDate).isAfter(moment()) ? moment(subscriptionExpirationDate) : moment(); const initialDate = moment(subscriptionExpirationDate).isAfter(moment()) ? moment(subscriptionExpirationDate) : moment();
const updatedSubscriptionExpirationDate = moment(initialDate).add(duration, duration_unit).toISOString(); const updatedSubscriptionExpirationDate = moment(initialDate).add(duration, duration_unit).endOf("day").subtract(2, "hours").toISOString();
await setDoc(userSnapshot.ref, {subscriptionExpirationDate: updatedSubscriptionExpirationDate}, {merge: true}); await setDoc(userSnapshot.ref, {subscriptionExpirationDate: updatedSubscriptionExpirationDate, status: "active"}, {merge: true});
await setDoc(doc(db, "paypalpayments", v4()), { await setDoc(doc(db, "paypalpayments", v4()), {
createdAt: new Date().toISOString(), createdAt: new Date().toISOString(),
currency: transactionResult.transaction.currency, currency: transactionResult.transaction.currency,
@@ -64,10 +65,16 @@ async function post(req: NextApiRequest, res: NextApiResponse) {
const participants = (await Promise.all( const participants = (await Promise.all(
groups.flatMap((x) => x.participants).map(async (x) => ({...(await getDoc(doc(db, "users", x))).data(), id: x})), groups.flatMap((x) => x.participants).map(async (x) => ({...(await getDoc(doc(db, "users", x))).data(), id: x})),
)) as User[]; )) as User[];
const sameExpiryDateParticipants = participants.filter((x) => x.subscriptionExpirationDate === subscriptionExpirationDate); const sameExpiryDateParticipants = participants.filter(
(x) => x.subscriptionExpirationDate === subscriptionExpirationDate && x.status !== "disabled",
);
for (const participant of sameExpiryDateParticipants) { for (const participant of sameExpiryDateParticipants) {
await setDoc(doc(db, "users", participant.id), {subscriptionExpirationDate: updatedSubscriptionExpirationDate}, {merge: true}); await setDoc(
doc(db, "users", participant.id),
{subscriptionExpirationDate: updatedSubscriptionExpirationDate, status: "active"},
{merge: true},
);
} }
} }

View File

@@ -49,7 +49,7 @@ export const getServerSideProps = withIronSessionSsr(({req, res}) => {
redirect: { redirect: {
destination: "/login", destination: "/login",
permanent: false, permanent: false,
} },
}; };
} }
@@ -63,7 +63,7 @@ interface Props {
envVariables: {[key: string]: string}; envVariables: {[key: string]: string};
} }
export default function Home(props: Props) { export default function Home(props: Props) {
const { envVariables} = props; const {envVariables} = props;
const [showDiagnostics, setShowDiagnostics] = useState(false); const [showDiagnostics, setShowDiagnostics] = useState(false);
const [showDemographicInput, setShowDemographicInput] = useState(false); const [showDemographicInput, setShowDemographicInput] = useState(false);
const [selectedScreen, setSelectedScreen] = useState<Type>("admin"); const [selectedScreen, setSelectedScreen] = useState<Type>("admin");
@@ -112,15 +112,7 @@ export default function Home(props: Props) {
</div> </div>
</Layout> </Layout>
)} )}
{(user.status === "paymentDue" || checkIfUserExpired()) && ( {(user.status === "paymentDue" || checkIfUserExpired()) && <PaymentDue hasExpired user={user} reload={router.reload} />}
<PaymentDue
key={envVariables["NEXT_PUBLIC_PAYPAL_CLIENT_ID"]}
hasExpired
user={user}
reload={router.reload}
clientID={envVariables["NEXT_PUBLIC_PAYPAL_CLIENT_ID"] || ""}
/>
)}
</> </>
); );
} }

View File

@@ -1,62 +1,51 @@
/* eslint-disable @next/next/no-img-element */ /* eslint-disable @next/next/no-img-element */
import Head from "next/head"; import Head from "next/head";
import { withIronSessionSsr } from "iron-session/next"; import {withIronSessionSsr} from "iron-session/next";
import { sessionOptions } from "@/lib/session"; import {sessionOptions} from "@/lib/session";
import useUser from "@/hooks/useUser"; import useUser from "@/hooks/useUser";
import PaymentDue from "./(status)/PaymentDue"; import PaymentDue from "./(status)/PaymentDue";
import { useRouter } from "next/router"; import {useRouter} from "next/router";
export const getServerSideProps = withIronSessionSsr(({ req, res }) => { export const getServerSideProps = withIronSessionSsr(({req, res}) => {
const user = req.session.user; const user = req.session.user;
const envVariables: { [key: string]: string } = {}; const envVariables: {[key: string]: string} = {};
Object.keys(process.env) Object.keys(process.env)
.filter((x) => x.startsWith("NEXT_PUBLIC")) .filter((x) => x.startsWith("NEXT_PUBLIC"))
.forEach((x: string) => { .forEach((x: string) => {
envVariables[x] = process.env[x]!; envVariables[x] = process.env[x]!;
}); });
if (!user || !user.isVerified) { if (!user || !user.isVerified) {
return { return {
redirect: { redirect: {
destination: "/login", destination: "/login",
permanent: false, permanent: false,
} },
}; };
} }
return { return {
props: { user: req.session.user, envVariables }, props: {user: req.session.user, envVariables},
}; };
}, sessionOptions); }, sessionOptions);
export default function Home({ export default function Home({envVariables}: {envVariables: {[key: string]: string}}) {
envVariables, const {user} = useUser({redirectTo: "/login"});
}: { const router = useRouter();
envVariables: { [key: string]: string };
}) {
const { user } = useUser({ redirectTo: "/login" });
const router = useRouter();
return ( return (
<> <>
<Head> <Head>
<title>EnCoach</title> <title>EnCoach</title>
<meta <meta
name="description" name="description"
content="A training platform for the IELTS exam provided by the Muscat Training Institute and developed by eCrop." content="A training platform for the IELTS exam provided by the Muscat Training Institute and developed by eCrop."
/> />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="/favicon.ico" /> <link rel="icon" href="/favicon.ico" />
</Head> </Head>
{user && ( {user && <PaymentDue user={user} reload={router.reload} />}
<PaymentDue </>
key={envVariables["NEXT_PUBLIC_PAYPAL_CLIENT_ID"]} );
clientID={envVariables["NEXT_PUBLIC_PAYPAL_CLIENT_ID"] || ""}
user={user}
reload={router.reload}
/>
)}
</>
);
} }