mirror of
https://github.com/spliit-app/spliit.git
synced 2025-12-06 09:29:39 +01:00
Add donation button (closes #40)
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { DonationButton } from '@/components/donation-button'
|
||||
import { ProgressBar } from '@/components/progress-bar'
|
||||
import { ThemeProvider } from '@/components/theme-provider'
|
||||
import { ThemeToggle } from '@/components/theme-toggle'
|
||||
@@ -111,35 +112,42 @@ export default function RootLayout({
|
||||
|
||||
{children}
|
||||
|
||||
<footer className="sm:p-8 md:p-16 sm:mt-16 sm:text-sm md:text-base md:mt-32 bg-slate-50 dark:bg-card border-t p-6 mt-8 flex flex-col space-y-2 text-xs [&_a]:underline">
|
||||
<div className="sm:text-lg font-semibold text-base flex space-x-2 items-center">
|
||||
<Link className="flex items-center gap-2" href="/">
|
||||
<Image
|
||||
src="/logo-with-text.png"
|
||||
className="m-1 h-auto"
|
||||
width={(35 * 522) / 180}
|
||||
height={35}
|
||||
alt="Spliit"
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="flex flex-col space-y a--no-underline-text-white">
|
||||
<span>Made in Montréal, Québec 🇨🇦</span>
|
||||
<span>
|
||||
Built by{' '}
|
||||
<a href="https://scastiel.dev" target="_blank" rel="noopener">
|
||||
Sebastien Castiel
|
||||
</a>{' '}
|
||||
and{' '}
|
||||
<a
|
||||
href="https://github.com/scastiel/spliit2/graphs/contributors"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
contributors
|
||||
</a>
|
||||
</span>
|
||||
<footer className="sm:p-8 md:p-16 sm:mt-16 sm:text-sm md:text-base md:mt-32 bg-slate-50 dark:bg-card border-t p-6 mt-8 flex flex-col sm:flex-row sm:justify-between gap-4 text-xs [&_a]:underline">
|
||||
<div className="flex flex-col space-y-2">
|
||||
<div className="sm:text-lg font-semibold text-base flex space-x-2 items-center">
|
||||
<Link className="flex items-center gap-2" href="/">
|
||||
<Image
|
||||
src="/logo-with-text.png"
|
||||
className="m-1 h-auto"
|
||||
width={(35 * 522) / 180}
|
||||
height={35}
|
||||
alt="Spliit"
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="flex flex-col space-y a--no-underline-text-white">
|
||||
<span>Made in Montréal, Québec 🇨🇦</span>
|
||||
<span>
|
||||
Built by{' '}
|
||||
<a href="https://scastiel.dev" target="_blank" rel="noopener">
|
||||
Sebastien Castiel
|
||||
</a>{' '}
|
||||
and{' '}
|
||||
<a
|
||||
href="https://github.com/scastiel/spliit2/graphs/contributors"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
contributors
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{env.STRIPE_DONATION_LINK && (
|
||||
<div>
|
||||
<DonationButton donationUrl={env.STRIPE_DONATION_LINK} />
|
||||
</div>
|
||||
)}
|
||||
</footer>
|
||||
<Toaster />
|
||||
</ThemeProvider>
|
||||
|
||||
123
src/components/donation-button.tsx
Normal file
123
src/components/donation-button.tsx
Normal file
@@ -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>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -8,6 +8,7 @@ const envSchema = z.object({
|
||||
FEEDBACK_EMAIL_FROM: z.string().email().optional(),
|
||||
FEEDBACK_EMAIL_TO: z.string().email().optional(),
|
||||
RESEND_API_KEY: z.string().optional(),
|
||||
STRIPE_DONATION_LINK: z.string().optional(),
|
||||
})
|
||||
|
||||
export const env = envSchema.parse(process.env)
|
||||
|
||||
Reference in New Issue
Block a user