diff --git a/app/api/subscription/route.ts b/app/api/subscription/route.ts
new file mode 100644
index 0000000..1f8ca87
--- /dev/null
+++ b/app/api/subscription/route.ts
@@ -0,0 +1,46 @@
+import { NextResponse } from 'next/server';
+import * as admin from 'firebase-admin';
+import serviceAccount from '../../../dog-voicenator.json';
+
+if (!admin.apps.length) {
+ admin.initializeApp({
+ credential: admin.credential.cert(serviceAccount)
+ });
+}
+
+export async function POST(request: Request) {
+ const data = await request.json();
+ const { userId, cardNumber, expiryDate, cvv, plan } = data;
+
+ const db = admin.firestore();
+ const subscriptionRef = db.collection('subscriptions').doc(userId);
+
+ await subscriptionRef.set({
+ cardNumber,
+ expiryDate,
+ cvv,
+ plan,
+ createdAt: new Date(),
+ active: true
+ });
+
+ return NextResponse.json({ success: true });
+}
+
+export async function GET(request: Request) {
+ const url = new URL(request.url);
+ const userId = url.searchParams.get('userId');
+
+ if (!userId) {
+ return NextResponse.json({ error: 'Missing userId' }, { status: 400 });
+ }
+
+ const db = admin.firestore();
+ const subscriptionDoc = await db.collection('subscriptions').doc(userId).get();
+
+ if (!subscriptionDoc.exists) {
+ return NextResponse.json({ error: 'No subscription found' }, { status: 404 });
+ }
+
+ return NextResponse.json(subscriptionDoc.data());
+}
diff --git a/app/components/SubscriptionForm.tsx b/app/components/SubscriptionForm.tsx
new file mode 100644
index 0000000..9c8cec9
--- /dev/null
+++ b/app/components/SubscriptionForm.tsx
@@ -0,0 +1,102 @@
+'use client'
+
+import { useState } from 'react'
+import { Card, CardContent, CardHeader, CardTitle } from './ui/card'
+import { Button } from './ui/button'
+import { useAuth } from '../contexts/AuthContext'
+import { createSubscription, getSubscription } from '../lib/subscription-utils'
+
+export default function SubscriptionForm() {
+ const { user } = useAuth()
+ const [cardNumber, setCardNumber] = useState('')
+ const [expiryDate, setExpiryDate] = useState('')
+ const [cvv, setCvv] = useState('')
+ const [plan, setPlan] = useState('basic')
+ const [loading, setLoading] = useState(false)
+
+ const handleSubmit = async (e: React.FormEvent) => {
+ e.preventDefault()
+ setLoading(true)
+
+ try {
+ await createSubscription({
+ userId: user!.uid,
+ cardNumber,
+ expiryDate,
+ cvv,
+ plan
+ })
+
+ window.location.reload()
+ } catch (error) {
+ console.error('Error creating subscription:', error)
+ } finally {
+ setLoading(false)
+ }
+ }
+
+ const checkSubscription = async () => {
+ const data = await getSubscription(user!.uid)
+ console.log('Subscription data:', data)
+ }
+
+ return (
+
+
+ Subscribe to Premium
+
+
+
+
+
+ )
+}
diff --git a/app/lib/subscription-utils.ts b/app/lib/subscription-utils.ts
new file mode 100644
index 0000000..2d11a7b
--- /dev/null
+++ b/app/lib/subscription-utils.ts
@@ -0,0 +1,39 @@
+interface SubscriptionData {
+ userId: string;
+ cardNumber: string;
+ expiryDate: string;
+ cvv: string;
+ plan: string;
+}
+
+export async function createSubscription(data: SubscriptionData) {
+ const response = await fetch('/api/subscription', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(data),
+ });
+
+ if (!response.ok) {
+ throw new Error('Failed to create subscription');
+ }
+
+ return response.json();
+}
+
+export async function getSubscription(userId: string) {
+ const response = await fetch(`/api/subscription?userId=${userId}`);
+
+ if (!response.ok) {
+ throw new Error('Failed to get subscription');
+ }
+
+ return response.json();
+}
+
+export function isSubscribed(userId: string): Promise {
+ return fetch(`/api/subscription?userId=${userId}`)
+ .then(response => response.ok)
+ .catch(() => false);
+}
diff --git a/app/page.tsx b/app/page.tsx
index c96c191..5c3e5eb 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -12,6 +12,8 @@ import { useToast } from './hooks/use-toast'
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from './components/ui/dialog'
import LoginForm from './components/LoginForm'
import RateLimitInfo from './components/RateLimitInfo'
+import SubscriptionForm from './components/SubscriptionForm'
+import { isSubscribed } from './lib/subscription-utils'
export default function Home() {
const { user, signIn, signOut } = useAuth()
@@ -26,6 +28,7 @@ export default function Home() {
const [error, setError] = useState(null)
const [showConsentDialog, setShowConsentDialog] = useState(false)
const [showLoginDialog, setShowLoginDialog] = useState(false)
+ const [isUserSubscribed, setIsUserSubscribed] = useState(false)
useEffect(() => {
if (user) {
@@ -33,6 +36,8 @@ export default function Home() {
try {
const voices = await getVoices(user.uid)
setVoices(voices)
+ const subscribed = await isSubscribed(user.uid)
+ setIsUserSubscribed(subscribed)
} catch (error) {
console.error('Error loading voices:', error)
toast({
@@ -171,6 +176,12 @@ export default function Home() {
Share the giggles with your friends and family as your furry friend becomes
the star of their own viral videos! 🌟
+ {user && !isUserSubscribed && (
+
+
Upgrade to Premium! 🌟
+
+
+ )}
🔒
@@ -359,6 +370,12 @@ export default function Home() {
😿 {error}
)}
+ {user && !isUserSubscribed && (
+
+
Upgrade to Premium! 🌟
+
+
+ )}
)}
diff --git a/firestore.rules b/firestore.rules
index 2de7404..5cb67b7 100644
--- a/firestore.rules
+++ b/firestore.rules
@@ -22,6 +22,12 @@ service cloud.firestore {
allow write: if request.auth != null && request.auth.uid == userId;
}
+ // Allow anyone to read subscription data
+ match /subscriptions/{userId} {
+ allow read: if true;
+ allow write: if true;
+ }
+
// Default deny
match /{document=**} {
allow read, write: if false;