first commit

This commit is contained in:
AyrisAI
2026-08-20 01:51:59 +03:00
commit 97b83c7fd4
109 changed files with 21215 additions and 0 deletions
+226
View File
@@ -0,0 +1,226 @@
import { useEffect, useState } from "react";
import { router } from "expo-router";
import {
ActivityIndicator,
Image,
Pressable,
ScrollView,
Share,
Text,
View,
} from "react-native";
import { Ionicons } from "@expo/vector-icons";
import * as Clipboard from "expo-clipboard";
import { api } from "@/lib/api";
import { getActiveRestaurant, type ActiveRestaurant } from "@/lib/active-restaurant";
interface QrResponse {
id: string;
redirectUrl: string;
targetUrl: string;
pngBase64: string;
}
export default function QrScreen() {
const [active, setActive] = useState<ActiveRestaurant | null>(null);
const [qr, setQr] = useState<QrResponse | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [copied, setCopied] = useState(false);
useEffect(() => {
(async () => {
const activeRest = await getActiveRestaurant();
if (!activeRest) return;
setActive(activeRest);
try {
const data = await api.post<QrResponse>(`/restaurants/${activeRest.restaurantId}/qr`);
setQr(data);
} catch (err) {
setError(err instanceof Error ? err.message : "QR oluşturulamadı");
} finally {
setLoading(false);
}
})();
}, []);
async function handleCopy() {
if (!qr?.targetUrl) return;
await Clipboard.setStringAsync(qr.targetUrl);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
}
async function handleShare() {
if (!qr?.targetUrl) return;
await Share.share({
title: "Dijital QR Menü",
message: `${qr.targetUrl}\nMenümüzü incelemek için QR kodu taratın veya linke tıklayın.`,
url: qr.targetUrl,
});
}
if (loading) {
return (
<View style={{ flex: 1, backgroundColor: "#FAF8F5", alignItems: "center", justifyContent: "center" }}>
<ActivityIndicator size="large" color="#C8A96B" />
<Text style={{ marginTop: 12, color: "#78716C", fontSize: 14 }}>QR Kod Hazırlanıyor...</Text>
</View>
);
}
if (error || !qr) {
return (
<View style={{ flex: 1, backgroundColor: "#FAF8F5", alignItems: "center", justifyContent: "center", padding: 24 }}>
<Ionicons name="alert-circle-outline" size={48} color="#DC2626" style={{ marginBottom: 12 }} />
<Text style={{ color: "#DC2626", fontSize: 16, fontWeight: "600", textAlign: "center" }}>
{error ?? "QR kod yüklenemedi"}
</Text>
<Pressable
onPress={() => router.back()}
style={{ marginTop: 20, backgroundColor: "#1C1917", paddingHorizontal: 20, paddingVertical: 10, borderRadius: 8 }}
>
<Text style={{ color: "#FFF", fontWeight: "600" }}>Geri Dön</Text>
</Pressable>
</View>
);
}
return (
<ScrollView contentContainerStyle={{ flexGrow: 1, backgroundColor: "#FAF8F5", padding: 24, justifyContent: "center" }}>
<View style={{ maxWidth: 440, width: "100%", alignSelf: "center", alignItems: "center" }}>
{/* Header Badge */}
<View
style={{
backgroundColor: "#F3EDE2",
paddingHorizontal: 14,
paddingVertical: 6,
borderRadius: 99,
marginBottom: 16,
flexDirection: "row",
alignItems: "center",
gap: 6,
}}
>
<Ionicons name="qr-code-outline" size={15} color="#926E27" />
<Text style={{ color: "#926E27", fontSize: 12, fontWeight: "700" }}>
DİJİTAL RESTORAN QR KODU
</Text>
</View>
<Text style={{ fontSize: 26, fontWeight: "800", color: "#1C1917", marginBottom: 6, textAlign: "center" }}>
Masanıza Özel QR Kod
</Text>
<Text style={{ fontSize: 14, color: "#78716C", textAlign: "center", marginBottom: 28, lineHeight: 20 }}>
Müşterileriniz bu QR kodu telefon kameralarıyla taratarak saniyeler içinde menünüzü inceleyebilir.
</Text>
{/* QR Code Container Card */}
<View
style={{
backgroundColor: "#FFFFFF",
borderRadius: 24,
padding: 24,
alignItems: "center",
shadowColor: "#000",
shadowOffset: { width: 0, height: 8 },
shadowOpacity: 0.08,
shadowRadius: 24,
elevation: 8,
borderWidth: 1,
borderColor: "rgba(200, 169, 107, 0.25)",
marginBottom: 24,
}}
>
<Image
source={{ uri: `data:image/png;base64,${qr.pngBase64}` }}
style={{ width: 220, height: 220, borderRadius: 12 }}
resizeMode="contain"
/>
<View
style={{
marginTop: 16,
paddingVertical: 6,
paddingHorizontal: 14,
backgroundColor: "#FAF8F5",
borderRadius: 8,
borderWidth: 1,
borderColor: "#E7E5E4",
}}
>
<Text style={{ fontSize: 13, fontWeight: "600", color: "#1C1917" }}>
{qr.targetUrl}
</Text>
</View>
</View>
{/* Action Buttons */}
<View style={{ width: "100%", gap: 12 }}>
{/* Share Button */}
<Pressable
onPress={handleShare}
style={({ pressed }) => ({
backgroundColor: "#1C1917",
borderRadius: 14,
padding: 16,
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
gap: 10,
opacity: pressed ? 0.9 : 1,
shadowColor: "#000",
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.1,
shadowRadius: 10,
elevation: 4,
})}
>
<Ionicons name="share-social-outline" size={18} color="#FFFFFF" />
<Text style={{ color: "#FFFFFF", fontSize: 15, fontWeight: "700" }}>
QR Kodu ve Linki Paylaş
</Text>
</Pressable>
{/* Copy Link Button */}
<Pressable
onPress={handleCopy}
style={({ pressed }) => ({
backgroundColor: "#FFFFFF",
borderWidth: 1.5,
borderColor: "#E7E5E4",
borderRadius: 14,
padding: 15,
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
gap: 8,
opacity: pressed ? 0.85 : 1,
})}
>
<Ionicons
name={copied ? "checkmark-circle-outline" : "copy-outline"}
size={18}
color={copied ? "#10B981" : "#1C1917"}
/>
<Text style={{ color: copied ? "#10B981" : "#1C1917", fontSize: 14, fontWeight: "600" }}>
{copied ? "Link Kopyalandı!" : "Menü Linkini Kopyala"}
</Text>
</Pressable>
{/* Back to Menu Editor */}
<Pressable
onPress={() => router.back()}
style={{ padding: 12, alignItems: "center", flexDirection: "row", justifyContent: "center", gap: 6 }}
>
<Ionicons name="arrow-back" size={16} color="#78716C" />
<Text style={{ color: "#78716C", fontSize: 14, fontWeight: "600" }}>
Menü Editörüne Dön
</Text>
</Pressable>
</View>
</View>
</ScrollView>
);
}