-
Notifications
You must be signed in to change notification settings - Fork 125
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'upstream/dev'
- Loading branch information
Showing
31 changed files
with
994 additions
and
75 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
export default function Logo({ expanded }: { expanded: boolean }) { | ||
return ( | ||
<h1 | ||
className={`font-[500] uppercase text-primary-foreground ${ | ||
expanded | ||
? "text-[1.25rem] leading-[1.2rem]" | ||
: "text-[0.75rem] leading-normal" | ||
}`} | ||
> | ||
logo | ||
</h1> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import { Check, X } from "lucide-react"; | ||
|
||
import { Button } from "~/components/ui/button"; | ||
import { | ||
Card, | ||
CardContent, | ||
CardDescription, | ||
CardFooter, | ||
CardHeader, | ||
CardTitle, | ||
} from "~/components/ui/card"; | ||
|
||
interface PricingCardProperties { | ||
title: string; | ||
price: string; | ||
period: string; | ||
description: string; | ||
features: { text: string; included: boolean }[]; | ||
buttonText: string; | ||
borderColor: string; | ||
onClick: () => void; | ||
isSelected: boolean; | ||
} | ||
|
||
const PricingCard = ({ | ||
title, | ||
price, | ||
period, | ||
description, | ||
features, | ||
buttonText, | ||
borderColor, | ||
onClick, | ||
isSelected, | ||
}: PricingCardProperties) => { | ||
return ( | ||
<Card | ||
className={`w-full max-w-sm lg:w-96 ${isSelected ? borderColor : ""}`} | ||
onClick={onClick} | ||
> | ||
<CardHeader className="space-y-3"> | ||
<CardTitle className="text-2xl">{title}</CardTitle> | ||
<CardTitle className="text-4xl leading-none"> | ||
{price} <span className="text-lg font-light">/{period}</span> | ||
</CardTitle> | ||
<CardDescription className="w-full text-sm leading-6 md:w-[247px]"> | ||
{description} | ||
</CardDescription> | ||
</CardHeader> | ||
<CardContent className="my-5 space-y-4"> | ||
{features.map((feature, index) => ( | ||
<CardDescription | ||
key={index} | ||
className={`flex items-center gap-3 ${ | ||
feature.included ? "text-accent-foreground" : "text-accent" | ||
}`} | ||
> | ||
{feature.included ? <Check /> : <X />} {feature.text} | ||
</CardDescription> | ||
))} | ||
</CardContent> | ||
<CardFooter className="w-full"> | ||
<Button className="w-full bg-primary">{buttonText}</Button> | ||
</CardFooter> | ||
</Card> | ||
); | ||
}; | ||
|
||
export default PricingCard; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
import { useState } from "react"; | ||
|
||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "~/components/ui/tabs"; | ||
import PricingCard from "./PricingCard"; | ||
|
||
const PricingPage = () => { | ||
const [selectedCard, setSelectedCard] = useState<string | undefined>(); | ||
|
||
const handleCardClick = (cardName: string) => { | ||
setSelectedCard(cardName); | ||
}; | ||
|
||
return ( | ||
<main> | ||
<div className="container my-10 flex flex-col items-center px-8"> | ||
<p className="rounded-lg bg-secondary px-4 py-2 text-xl font-light"> | ||
Pricing | ||
</p> | ||
<div className="mt-5 flex w-full max-w-5xl flex-col items-center text-center"> | ||
<h2 className="text-2xl font-semibold leading-none md:text-6xl"> | ||
Simple and <span className="text-primary">Affordable</span> Pricing | ||
Plan | ||
</h2> | ||
<p className="mt-5 w-full text-lg font-light leading-tight md:w-9/12 md:text-2xl"> | ||
Our flexible plans are designed to scale with your business. We have | ||
a plan for you. | ||
</p> | ||
</div> | ||
|
||
<Tabs defaultValue="account" className="mt-10"> | ||
<TabsList className="mx-auto grid w-96 grid-cols-2"> | ||
<TabsTrigger value="account">Monthly</TabsTrigger> | ||
<TabsTrigger value="password">Annual (save 20%)</TabsTrigger> | ||
</TabsList> | ||
<TabsContent | ||
value="account" | ||
className="mt-5 gap-5 space-y-5 md:flex md:space-y-0" | ||
> | ||
<PricingCard | ||
title="Basic" | ||
price="$800" | ||
period="month" | ||
description="The essentials to provide your best work for clients." | ||
features={[ | ||
{ text: "2 Projects", included: true }, | ||
{ text: "Up to 100 subscribers", included: true }, | ||
{ text: "Basic analytics", included: true }, | ||
{ text: "24-hour support response time", included: true }, | ||
{ text: "Marketing advisor", included: false }, | ||
{ text: "Custom integration", included: false }, | ||
]} | ||
buttonText="Continue" | ||
borderColor="border-primary" | ||
onClick={() => handleCardClick("basic-monthly")} | ||
isSelected={selectedCard === "basic-monthly"} | ||
/> | ||
<PricingCard | ||
title="Premium" | ||
price="$3,000" | ||
period="month" | ||
description="The essentials to provide your best work for clients." | ||
features={[ | ||
{ text: "25 Projects", included: true }, | ||
{ text: "Up to 10,000 subscribers", included: true }, | ||
{ text: "Advanced analytics", included: true }, | ||
{ text: "24-hour support response time", included: true }, | ||
{ text: "Marketing advisor", included: true }, | ||
{ text: "Custom integration", included: true }, | ||
]} | ||
buttonText="Continue" | ||
borderColor="border-primary" | ||
onClick={() => handleCardClick("premium-monthly")} | ||
isSelected={selectedCard === "premium-monthly"} | ||
/> | ||
</TabsContent> | ||
<TabsContent | ||
value="password" | ||
className="mt-5 gap-5 space-y-5 md:mt-0 md:flex md:space-y-0" | ||
> | ||
<PricingCard | ||
title="Basic" | ||
price="$500" | ||
period="month" | ||
description="The essentials to provide your best work for clients." | ||
features={[ | ||
{ text: "2 Projects", included: true }, | ||
{ text: "Up to 100 subscribers", included: true }, | ||
{ text: "Basic analytics", included: true }, | ||
{ text: "24-hour support response time", included: true }, | ||
{ text: "Marketing advisor", included: false }, | ||
{ text: "Custom integration", included: false }, | ||
]} | ||
buttonText="Continue" | ||
borderColor="border-primary" | ||
onClick={() => handleCardClick("basic-annual")} | ||
isSelected={selectedCard === "basic-annual"} | ||
/> | ||
<PricingCard | ||
title="Premium" | ||
price="$2,000" | ||
period="month" | ||
description="The essentials to provide your best work for clients." | ||
features={[ | ||
{ text: "25 Projects", included: true }, | ||
{ text: "Up to 10,000 subscribers", included: true }, | ||
{ text: "Advanced analytics", included: true }, | ||
{ text: "24-hour support response time", included: true }, | ||
{ text: "Marketing advisor", included: true }, | ||
{ text: "Custom integration", included: true }, | ||
]} | ||
buttonText="Continue" | ||
borderColor="border-primary" | ||
onClick={() => handleCardClick("premium-annual")} | ||
isSelected={selectedCard === "premium-annual"} | ||
/> | ||
</TabsContent> | ||
</Tabs> | ||
</div> | ||
</main> | ||
); | ||
}; | ||
|
||
export default PricingPage; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
export default function Profile({ expanded }: { expanded: boolean }) { | ||
return ( | ||
<div className={`flex items-center gap-1 ${expanded ? "ml-0" : "-ml-2"}`}> | ||
<div className="h-[2.6875rem] w-[2.6875rem] rounded-full border-[1px] border-[#f973164d] bg-background bg-cover bg-no-repeat sm:hidden"></div> | ||
<div | ||
className={`${expanded ? "" : "hidden"} flex flex-col items-start justify-center`} | ||
> | ||
<h3 className="text-[0.875rem] font-semibold text-[#0A0A0A]"> | ||
Your Profile | ||
</h3> | ||
<p className="ml-[2px] text-[0.75rem] font-[500] text-[#525252]"> | ||
Login | ||
</p> | ||
</div> | ||
</div> | ||
); | ||
} |
Oops, something went wrong.