Skip to content

Commit

Permalink
Merge pull request #49 from kotalco/development
Browse files Browse the repository at this point in the history
Fix Issues
  • Loading branch information
mFarghaly authored Apr 27, 2024
2 parents 4ca7712 + 87e64bc commit ae90990
Show file tree
Hide file tree
Showing 12 changed files with 111 additions and 31 deletions.
7 changes: 7 additions & 0 deletions src/actions/create-virtual-endpoint/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ const handler = async (data: InputType): Promise<ReturnType> => {
return { error: "Name already exists." };
}

if (response?.status === 402) {
return {
error:
"You've reached your endpoint limit. To enjoy more endpoints, consider upgrading your plan.",
};
}

logger("CreateVirtualEndpoint", error);
return { error: "Something went wrong." };
}
Expand Down
4 changes: 2 additions & 2 deletions src/app/(auth)/(routes)/sign-in/components/login-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ export const LoginForm = () => {
const { execute, error, fieldErrors } = useAction(loginUser, {
onSuccess: (data) => {
if ("Authorized" in data) {
setOpen(true);
return setOpen(true);
}

if ("email" in data) {
setEmail(data.email);
return setEmail(data.email);
}

router.push(nextUrl || "/");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"use client";
import { CreditCard } from "lucide-react";
import { useRouter } from "next/navigation";

import { useChangeSubscriptionModal } from "@/hooks/use-change-subscription-modal";
import { delay } from "@/lib/utils";

import { Button } from "@/components/ui/button";

const AddNewCardButton = ({ children }: { children: React.ReactNode }) => {
const router = useRouter();
const { onClose, setStep } = useChangeSubscriptionModal();

const handleClick = async () => {
router.push("/payment-methods");
await delay(1000);
onClose();
setStep(1);
};

return (
<Button
onClick={handleClick}
type="button"
variant="outline"
size="sm"
className="mt-4 w-full"
>
<CreditCard className="w-6 h-6 mr-2" />
<span>{children}</span>
</Button>
);
};
export default AddNewCardButton;
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { PayWithNewCard } from "./pay-with-new-card";

interface InvoicePaymentFormProps {
children: React.ReactNode;
cardsLength: number;
}

type PaymentIntentState = {
Expand All @@ -26,6 +27,7 @@ const stripe = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY!);

export const InvoicePaymentForm: React.FC<InvoicePaymentFormProps> = ({
children,
cardsLength,
}) => {
const [showCards, setShowCards] = useState(true);
const intentState = useLocalStorage<PaymentIntentState>(
Expand Down Expand Up @@ -57,7 +59,10 @@ export const InvoicePaymentForm: React.FC<InvoicePaymentFormProps> = ({
>
{showCards && (
<>
<PayWithSavedCard clientSecret={pi_secret}>
<PayWithSavedCard
clientSecret={pi_secret}
cardsLength={cardsLength}
>
{children}
</PayWithSavedCard>
<Button
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,30 @@
// import { useFormState, useFormStatus } from "react-dom";
import { Suspense } from "react";

import { getPaymentMethods } from "@/services/get-payment-methods";

// import { Button } from "@/components/ui/button";
// import { prepareInvoicePayment } from "@/lib/actions";
// import { Loader2 } from "lucide-react";
import { InvoicePaymentForm } from "./invoice-payment-form";
import {
DialogContent,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import { Skeleton } from "@/components/ui/skeleton";

import { InvoicePaymentDialog } from "./invoice-payment-dialog";
import { Suspense } from "react";
import { CardSelection } from "./card-selection";
import { Skeleton } from "@/components/ui/skeleton";
import { InvoicePaymentForm } from "./invoice-payment-form";

export const InvoicePayment: React.FC<{ intentId: string }> = ({
export const InvoicePayment: React.FC<{ intentId: string }> = async ({
intentId,
}) => {
const { cards } = await getPaymentMethods();

return (
<InvoicePaymentDialog intentId={intentId}>
<DialogContent>
<DialogHeader>
<DialogTitle>Invoice Payment</DialogTitle>
</DialogHeader>
<InvoicePaymentForm>
<InvoicePaymentForm cardsLength={cards.length}>
<Suspense fallback={<CardsSkeleton />}>
<CardSelection />
</Suspense>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Suspense } from "react";

import { cn, getEnumKey } from "@/lib/utils";
import { cn, formatCurrency, getEnumKey } from "@/lib/utils";

import { SubscriptionStatus } from "@/enums";
import { getCurrentSubscription } from "@/services/get-current-subscription";
Expand Down Expand Up @@ -52,7 +52,7 @@ export const ManagePlanCard = async () => {
</p>
<p className="text-lg">{subscription.endpoint_limit} Endpoints</p>
<p className="text-sm text-muted-foreground">
${subscription.price.price} / Month
{formatCurrency(subscription.price.price)} / Month
</p>
</div>
</CardTitle>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ import { Loader2 } from "lucide-react";
interface PayWithSavedCardProps {
clientSecret: string;
children: React.ReactNode;
cardsLength: number;
}

export const PayWithSavedCard: React.FC<PayWithSavedCardProps> = ({
clientSecret,
children,
cardsLength,
}) => {
const [isLoading, setIsLoading] = useState(false);
const [errorMessage, setErrorMessage] = useState<string>();
Expand Down Expand Up @@ -72,7 +74,7 @@ export const PayWithSavedCard: React.FC<PayWithSavedCardProps> = ({
<form onSubmit={payInvoice} className="space-y-2">
{children}
{errorMessage && <Alert variant="destructive">{errorMessage}</Alert>}
<Button className="w-full" disabled={isLoading}>
<Button className="w-full" disabled={isLoading || !cardsLength}>
{isLoading && <Loader2 className="w-4 h-4 mr-2 animate-spin" />}Pay{" "}
{formatCurrency(amount)}
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,17 @@ import { SubmitButton } from "@/components/form/submit-button";
import { PaymentElement } from "./payment-element";
import { Separator } from "@/components/ui/separator";
import { Button } from "@/components/ui/button";
import AddNewCardButton from "./add-new-card-button";

interface PaymentDetailsListProps {
children?: React.ReactNode;
cardsLength: number;
data?: Proration;
}

export const PaymentDetailsList = ({
children,
cardsLength,
data,
}: PaymentDetailsListProps) => {
const {
Expand Down Expand Up @@ -54,9 +57,18 @@ export const PaymentDetailsList = ({
};

return (
<form action={onSubmit} className="">
<form action={onSubmit}>
<div>
{data.amount_due > 0 && children}
{data.amount_due > 0 && (
<>
{children}
<AddNewCardButton>
{cardsLength
? "Use Another Payment Card"
: "Add New Payment Card"}
</AddNewCardButton>
</>
)}
<ul>
<li className="flex justify-between text-sm leading-9 opacity-70">
<span>Plan Price</span>
Expand Down Expand Up @@ -94,7 +106,10 @@ export const PaymentDetailsList = ({
)}

<div className="mt-5">
<SubmitButton className="w-full">
<SubmitButton
className="w-full"
disabled={data.amount_due > 0 && cardsLength === 0}
>
Pay {formatCurrency(data.amount_due)}
</SubmitButton>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Plan } from "@/types";
import { useAction } from "@/hooks/use-action";
import { getProration } from "@/actions/get-proration";
import { useChangeSubscriptionModal } from "@/hooks/use-change-subscription-modal";
import { formatCurrency } from "@/lib/utils";

import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import { Label } from "@/components/ui/label";
Expand All @@ -18,12 +19,14 @@ import { PaymentDetailsList } from "./payment-details-list";
interface PlanSelectionFormProps {
plans: Plan[];
subscriptionId: string;
cardsLength: number;
children?: React.ReactNode;
}

export const PlanSelectionForm = ({
plans,
subscriptionId,
cardsLength,
children,
}: PlanSelectionFormProps) => {
const { step, nextStep, setPlanPrice, setNewSubscriptionData } =
Expand Down Expand Up @@ -80,7 +83,7 @@ export const PlanSelectionForm = ({

{plan.prices.map((price) => (
<p key={price.id} className="text-muted-foreground">
${price.price} / Month
{formatCurrency(price.price)} / Month
</p>
))}
</div>
Expand Down Expand Up @@ -111,7 +114,11 @@ export const PlanSelectionForm = ({
}

if (step === 2) {
return <PaymentDetailsList data={data}>{children}</PaymentDetailsList>;
return (
<PaymentDetailsList data={data} cardsLength={cardsLength}>
{children}
</PaymentDetailsList>
);
}

return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,33 @@
import { Suspense } from "react";
import { getPlans } from "@/services/get-plans";
import { getCurrentSubscription } from "@/services/get-current-subscription";

import { Skeleton } from "@/components/ui/skeleton";
import { getPaymentMethods } from "@/services/get-payment-methods";

import { PlanSelectionForm } from "./plan-selection-form";
import { Suspense } from "react";
import { CardSelection } from "./card-selection";

export const PlanSelection = async () => {
const subscriptionPromise = getCurrentSubscription();
const plansPromise = getPlans();
const cardsPromise = getPaymentMethods();

const [{ plans }, { subscription }] = await Promise.all([
const [{ plans }, { subscription }, { cards }] = await Promise.all([
plansPromise,
subscriptionPromise,
cardsPromise,
]);

const otherPlans = plans?.filter((plan) => plan.id !== subscription.plan.id);

return (
<div className="space-y-3">
<PlanSelectionForm plans={otherPlans} subscriptionId={subscription.id}>
<PlanSelectionForm
plans={otherPlans}
subscriptionId={subscription.id}
cardsLength={cards.length}
>
<Suspense fallback={<div>Loading</div>}>
<CardSelection />
</Suspense>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,16 @@ export const CreateEndpointForm: React.FC<CreateEndpointFormProps> = ({
};

return (
<form
data-testid="create-endpoint"
action={onSubmit}
className="max-w-xs space-y-4"
>
<Input id="name" label="Endpoint Name" errors={fieldErrors} />
<form data-testid="create-endpoint" action={onSubmit} className="space-y-4">
<Input
className="max-w-xs"
id="name"
label="Endpoint Name"
errors={fieldErrors}
/>

<Select
className="max-w-xs"
id="protocol"
label="Protocol"
onValueChange={setSelectedProtocol as (value: string) => void}
Expand All @@ -70,6 +72,7 @@ export const CreateEndpointForm: React.FC<CreateEndpointFormProps> = ({
networks &&
!!services[selectedProtocol]?.filter((el) => !!el).length && (
<Select
className="max-w-xs"
id="network"
label="Network"
placeholder="Select a network"
Expand Down
3 changes: 1 addition & 2 deletions src/hooks/use-change-subscription-modal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ export const useChangeSubscriptionModal =
nextStep: () => set(({ step }) => ({ step: step + 1 })),
onOpen: () => set({ isOpen: true }),
onClose: () => set({ isOpen: false }),
setPlanPrice: (price?: number) =>
set({ planPrice: price && Number(price) * 100 }),
setPlanPrice: (price?: number) => set({ planPrice: Number(price) }),
setNewSubscriptionData: (data: ChangeSubscriptionData) => set({ data }),
}));

0 comments on commit ae90990

Please sign in to comment.