aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/donation-button.tsx
diff options
context:
space:
mode:
authorSebastien Castiel <sebastien@castiel.me>2024-01-14 11:42:32 -0500
committerSebastien Castiel <sebastien@castiel.me>2024-01-14 11:43:48 -0500
commitbeae3366667b54b83e20f7e8d532f694c81bc5d0 (patch)
treec40a3136b474978d048a40a6589e35d9c08dfceb /src/components/donation-button.tsx
parent2dcb80f954dcc6a9c87dac1dc33668b4478993b9 (diff)
Add donation button (closes #40)
Diffstat (limited to 'src/components/donation-button.tsx')
-rw-r--r--src/components/donation-button.tsx123
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>
+ </>
+ )
+}