diff options
| author | Sebastien Castiel <sebastien@castiel.me> | 2024-01-14 11:42:32 -0500 |
|---|---|---|
| committer | Sebastien Castiel <sebastien@castiel.me> | 2024-01-14 11:43:48 -0500 |
| commit | beae3366667b54b83e20f7e8d532f694c81bc5d0 (patch) | |
| tree | c40a3136b474978d048a40a6589e35d9c08dfceb /src/components/donation-button.tsx | |
| parent | 2dcb80f954dcc6a9c87dac1dc33668b4478993b9 (diff) | |
Add donation button (closes #40)
Diffstat (limited to 'src/components/donation-button.tsx')
| -rw-r--r-- | src/components/donation-button.tsx | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/src/components/donation-button.tsx b/src/components/donation-button.tsx new file mode 100644 index 0000000..34fcfb1 --- /dev/null +++ b/src/components/donation-button.tsx @@ -0,0 +1,123 @@ +'use client' +import { Button } from '@/components/ui/button' +import { + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, + DialogTrigger, +} from '@/components/ui/dialog' +import { + Drawer, + DrawerContent, + DrawerDescription, + DrawerHeader, + DrawerTitle, + DrawerTrigger, +} from '@/components/ui/drawer' +import { useMediaQuery } from '@/lib/hooks' +import { Heart } from 'lucide-react' +import { useState } from 'react' + +type Props = { + donationUrl: string +} + +export function DonationButton({ donationUrl }: Props) { + const isDesktop = useMediaQuery('(min-width: 768px)') + return isDesktop ? ( + <DonationDialog donationUrl={donationUrl} /> + ) : ( + <DonationDrawer donationUrl={donationUrl} /> + ) +} + +function DonationDrawer({ donationUrl }: Props) { + const [open, setOpen] = useState(false) + + return ( + <Drawer open={open} onOpenChange={setOpen}> + <DrawerTrigger asChild> + <Button className="bg-pink-700 hover:bg-pink-600"> + <Heart className="w-4 h-4 mr-2" /> Support us + </Button> + </DrawerTrigger> + <DrawerContent> + <DrawerHeader> + <DrawerTitle>Support us</DrawerTitle> + <DrawerDescription> + Help keep <strong>Spliit</strong> free and without ads! + </DrawerDescription> + </DrawerHeader> + <div className="px-4 pb-4"> + <DonationForm donationUrl={donationUrl} /> + </div> + </DrawerContent> + </Drawer> + ) +} + +function DonationDialog({ donationUrl }: Props) { + const [open, setOpen] = useState(false) + + return ( + <Dialog open={open} onOpenChange={setOpen}> + <DialogTrigger asChild> + <Button className="bg-pink-700 hover:bg-pink-600"> + <Heart className="w-4 h-4 mr-2" /> Support us + </Button> + </DialogTrigger> + <DialogContent> + <DialogHeader> + <DialogTitle>Support us</DialogTitle> + <DialogDescription> + Help keep <strong>Spliit</strong> free and without ads! + </DialogDescription> + </DialogHeader> + <DonationForm donationUrl={donationUrl} /> + </DialogContent> + </Dialog> + ) +} + +function DonationForm({ donationUrl }: Props) { + return ( + <> + <div className="prose prose-sm"> + <p> + Spliit is offered for free, but costs money and energy. If you like + the app, you can choose to support it by buying me (Sebastien) a + coffee with a one-time small donation. + </p> + <p>By supporting Spliit:</p> + <ul> + <li> + You contribute to the <strong>hosting costs</strong> for the app + (currently ~$150/year). + </li> + <li> + You help us keeping the application{' '} + <strong>free and without ads</strong>. + </li> + <li> + You give me energy to build <strong>new features</strong> and + improve the application. + </li> + </ul> + <p> + You will be redirected to <strong>Stripe</strong>, our payment + provider, where you can choose an amount to donate and complete the + payment. + </p> + </div> + <div className="mt-4 text-center"> + <Button asChild className="bg-pink-700 hover:bg-pink-600"> + <a href={donationUrl} target="_blank"> + <Heart className="w-4 h-4 mr-2" /> Support us + </a> + </Button> + </div> + </> + ) +} |
