feat(mobile): add QrTemplate6 Stonehearth Grill, modal text editor and vertical positioning (offsetY) controls
This commit is contained in:
+427
-184
@@ -3,6 +3,7 @@ import { router } from "expo-router";
|
|||||||
import {
|
import {
|
||||||
ActivityIndicator,
|
ActivityIndicator,
|
||||||
Alert,
|
Alert,
|
||||||
|
Modal,
|
||||||
Pressable,
|
Pressable,
|
||||||
ScrollView,
|
ScrollView,
|
||||||
Share,
|
Share,
|
||||||
@@ -12,6 +13,7 @@ import {
|
|||||||
View,
|
View,
|
||||||
} from "react-native";
|
} from "react-native";
|
||||||
import { Ionicons } from "@expo/vector-icons";
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
|
||||||
import * as Clipboard from "expo-clipboard";
|
import * as Clipboard from "expo-clipboard";
|
||||||
import ViewShot from "react-native-view-shot";
|
import ViewShot from "react-native-view-shot";
|
||||||
import * as Sharing from "expo-sharing";
|
import * as Sharing from "expo-sharing";
|
||||||
@@ -91,6 +93,24 @@ export default function QrScreen() {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const [selectedEditField, setSelectedEditField] = useState<keyof QrCustomFields | null>(null);
|
||||||
|
|
||||||
|
const FIELD_DEFINITIONS: Array<{
|
||||||
|
key: keyof QrCustomFields;
|
||||||
|
label: string;
|
||||||
|
placeholder: string;
|
||||||
|
min: number;
|
||||||
|
max: number;
|
||||||
|
icon: string;
|
||||||
|
}> = [
|
||||||
|
{ key: "restaurantName", label: "Restoran Başlığı", placeholder: "Restoran Adı", min: 14, max: 48, icon: "restaurant-outline" },
|
||||||
|
{ key: "subtitle", label: "Slogan / Alt Başlık", placeholder: "Slogan (Enter ile alt satıra geçebilir)", min: 8, max: 26, icon: "chatbubble-outline" },
|
||||||
|
{ key: "ctaText", label: "Yönlendirme (CTA) Metni", placeholder: "Örn: MENÜYÜ GÖRMEK İÇİN OKUTUN", min: 9, max: 28, icon: "scan-outline" },
|
||||||
|
{ key: "tableNo", label: "Masa Numarası", placeholder: "Örn: MASA NO: 01", min: 8, max: 22, icon: "grid-outline" },
|
||||||
|
{ key: "wifiText", label: "WiFi & Şifre Bilgisi", placeholder: "Örn: WiFi: Bistro | Şifre: 12345", min: 7, max: 20, icon: "wifi-outline" },
|
||||||
|
{ key: "socialText", label: "Sosyal Medya / İletişim", placeholder: "Örn: @menulio", min: 7, max: 20, icon: "share-social-outline" },
|
||||||
|
];
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const viewShotRef = useRef<any>(null);
|
const viewShotRef = useRef<any>(null);
|
||||||
|
|
||||||
@@ -107,6 +127,7 @@ export default function QrScreen() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
(async () => {
|
(async () => {
|
||||||
const activeRest = await getActiveRestaurant();
|
const activeRest = await getActiveRestaurant();
|
||||||
@@ -389,7 +410,55 @@ export default function QrScreen() {
|
|||||||
</ViewShot>
|
</ViewShot>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
{/* Metin & Font & Boyut Özelleştirme Kartı (Açılır/Kapanır) */}
|
{/* Hızlı Katman Seçici (Tıklayınca Modal Açar) */}
|
||||||
|
<View style={{ width: "100%", marginBottom: 16 }}>
|
||||||
|
<Text style={{ color: "#D4AF37", fontSize: 12, fontWeight: "700", marginBottom: 8, letterSpacing: 0.5 }}>
|
||||||
|
DÜZENLEMEK VE KONUMUNU DEĞİŞTİRMEK İÇİN TIKLAYIN:
|
||||||
|
</Text>
|
||||||
|
<ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={{ gap: 8 }}>
|
||||||
|
{FIELD_DEFINITIONS.map(({ key, label, icon }) => {
|
||||||
|
const item = fields[key];
|
||||||
|
return (
|
||||||
|
<Pressable
|
||||||
|
key={key}
|
||||||
|
onPress={() => setSelectedEditField(key)}
|
||||||
|
style={({ pressed }) => ({
|
||||||
|
backgroundColor: item.visible ? "#242429" : "#1A1A1E",
|
||||||
|
paddingHorizontal: 12,
|
||||||
|
paddingVertical: 9,
|
||||||
|
borderRadius: 12,
|
||||||
|
borderWidth: 1.5,
|
||||||
|
borderColor: item.visible ? "rgba(212, 175, 55, 0.4)" : "#2B2B32",
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
gap: 6,
|
||||||
|
opacity: pressed ? 0.8 : 1,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<Ionicons name={icon as any} size={14} color={item.visible ? "#D4AF37" : "#71717A"} />
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
color: item.visible ? "#FFFFFF" : "#71717A",
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: "700",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{label}
|
||||||
|
</Text>
|
||||||
|
{item.offsetY ? (
|
||||||
|
<View style={{ backgroundColor: "#D4AF37", borderRadius: 6, paddingHorizontal: 4, paddingVertical: 1 }}>
|
||||||
|
<Text style={{ color: "#0C0C0E", fontSize: 9, fontWeight: "800" }}>
|
||||||
|
{item.offsetY > 0 ? `+${item.offsetY}` : item.offsetY}px
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
) : null}
|
||||||
|
</Pressable>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</ScrollView>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Metin & Font & Boyut Özelleştirme Kartı (Açılır/Kapanır Liste) */}
|
||||||
<View
|
<View
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: "#18181B",
|
backgroundColor: "#18181B",
|
||||||
@@ -423,10 +492,10 @@ export default function QrScreen() {
|
|||||||
</View>
|
</View>
|
||||||
<View>
|
<View>
|
||||||
<Text style={{ color: "#FFFFFF", fontSize: 15, fontWeight: "700" }}>
|
<Text style={{ color: "#FFFFFF", fontSize: 15, fontWeight: "700" }}>
|
||||||
Metin, Font & Boyut Özelleştir
|
Tüm Katmanları Listele
|
||||||
</Text>
|
</Text>
|
||||||
<Text style={{ color: "#A1A1AA", fontSize: 12 }}>
|
<Text style={{ color: "#A1A1AA", fontSize: 12 }}>
|
||||||
Çok satırlı metin (Enter), özel font ve boyut ayarı
|
Tıkla & Düzenle, dikey konum kaydırma ve font ayarı
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
@@ -438,200 +507,374 @@ export default function QrScreen() {
|
|||||||
</Pressable>
|
</Pressable>
|
||||||
|
|
||||||
{showCustomizePanel && (
|
{showCustomizePanel && (
|
||||||
<View style={{ marginTop: 16, gap: 16, borderTopWidth: 1, borderTopColor: "rgba(255,255,255,0.06)", paddingTop: 16 }}>
|
<View style={{ marginTop: 16, gap: 12, borderTopWidth: 1, borderTopColor: "rgba(255,255,255,0.06)", paddingTop: 16 }}>
|
||||||
{/* Yardımcı Açıklama */}
|
{FIELD_DEFINITIONS.map(({ key, label, icon }) => {
|
||||||
<View
|
|
||||||
style={{
|
|
||||||
backgroundColor: "rgba(212, 175, 55, 0.08)",
|
|
||||||
borderRadius: 10,
|
|
||||||
padding: 10,
|
|
||||||
flexDirection: "row",
|
|
||||||
alignItems: "center",
|
|
||||||
gap: 8,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Ionicons name="information-circle-outline" size={16} color="#D4AF37" />
|
|
||||||
<Text style={{ color: "#E5C378", fontSize: 11.5, flex: 1 }}>
|
|
||||||
İpucu: Uzun metinlerde alt satıra geçmek için klavyeden Enter'a basabilirsiniz.
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
{/* Alan Düzenleyicileri */}
|
|
||||||
{(
|
|
||||||
[
|
|
||||||
{ key: "restaurantName", label: "RESTORAN BAŞLIĞI", placeholder: "Restoran Adı", min: 14, max: 48 },
|
|
||||||
{ key: "subtitle", label: "SLOGAN / ALT BAŞLIK", placeholder: "Slogan (Enter ile alt satıra geçebilir)", min: 8, max: 24 },
|
|
||||||
{ key: "ctaText", label: "YÖNLENDİRME (CTA) METNİ", placeholder: "Yönlendirme Metni", min: 9, max: 28 },
|
|
||||||
{ key: "tableNo", label: "MASA NUMARASI", placeholder: "Örn: MASA NO: 01", min: 8, max: 22 },
|
|
||||||
{ key: "wifiText", label: "WIFI BİLGİSİ", placeholder: "Örn: WiFi: Bistro | Şifre: 12345", min: 7, max: 20 },
|
|
||||||
{ key: "socialText", label: "SOSYAL MEDYA / İLETİŞİM", placeholder: "Örn: @menulio", min: 7, max: 20 },
|
|
||||||
] as const
|
|
||||||
).map(({ key, label, placeholder, min, max }) => {
|
|
||||||
const item = fields[key];
|
const item = fields[key];
|
||||||
return (
|
return (
|
||||||
<View
|
<Pressable
|
||||||
key={key}
|
key={key}
|
||||||
style={{
|
onPress={() => setSelectedEditField(key)}
|
||||||
gap: 8,
|
style={({ pressed }) => ({
|
||||||
paddingBottom: 12,
|
backgroundColor: "#141417",
|
||||||
borderBottomWidth: 1,
|
borderRadius: 14,
|
||||||
borderBottomColor: "rgba(255,255,255,0.06)",
|
padding: 12,
|
||||||
}}
|
borderWidth: 1,
|
||||||
|
borderColor: "rgba(255,255,255,0.06)",
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
opacity: pressed ? 0.8 : 1,
|
||||||
|
})}
|
||||||
>
|
>
|
||||||
{/* Başlık ve Görünürlük Anahtarı */}
|
<View style={{ flexDirection: "row", alignItems: "center", gap: 10, flex: 1 }}>
|
||||||
<View style={{ flexDirection: "row", justifyContent: "space-between", alignItems: "center" }}>
|
<Ionicons name={icon as any} size={18} color="#D4AF37" />
|
||||||
<Text style={{ color: "#D4AF37", fontSize: 12, fontWeight: "700" }}>{label}</Text>
|
<View style={{ flex: 1 }}>
|
||||||
<View style={{ flexDirection: "row", alignItems: "center", gap: 8 }}>
|
<Text style={{ color: "#FFFFFF", fontSize: 13, fontWeight: "700" }}>
|
||||||
<Text style={{ color: item.visible ? "#10B981" : "#71717A", fontSize: 11, fontWeight: "600" }}>
|
{label}
|
||||||
{item.visible ? "Açık" : "Gizli"}
|
</Text>
|
||||||
|
<Text style={{ color: "#A1A1AA", fontSize: 11 }} numberOfLines={1}>
|
||||||
|
{item.text || "Boş"}
|
||||||
</Text>
|
</Text>
|
||||||
<Switch
|
|
||||||
value={item.visible}
|
|
||||||
onValueChange={(v) =>
|
|
||||||
setFields((prev) => ({
|
|
||||||
...prev,
|
|
||||||
[key]: { ...prev[key], visible: v },
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
trackColor={{ false: "#27272A", true: "#D4AF37" }}
|
|
||||||
thumbColor="#FFFFFF"
|
|
||||||
ios_backgroundColor="#27272A"
|
|
||||||
/>
|
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
<View style={{ flexDirection: "row", alignItems: "center", gap: 8 }}>
|
||||||
{item.visible && (
|
<View
|
||||||
<>
|
style={{
|
||||||
{/* Çok Satırlı TextInput */}
|
backgroundColor: "#242429",
|
||||||
<TextInput
|
paddingHorizontal: 8,
|
||||||
value={item.text}
|
paddingVertical: 4,
|
||||||
onChangeText={(t) =>
|
borderRadius: 8,
|
||||||
setFields((prev) => ({
|
}}
|
||||||
...prev,
|
>
|
||||||
[key]: { ...prev[key], text: t },
|
<Text style={{ color: "#D4AF37", fontSize: 10, fontWeight: "700" }}>
|
||||||
}))
|
{item.fontSize || 12}px
|
||||||
}
|
</Text>
|
||||||
placeholder={placeholder}
|
</View>
|
||||||
placeholderTextColor="#71717A"
|
<Ionicons name="create-outline" size={18} color="#D4AF37" />
|
||||||
multiline
|
</View>
|
||||||
style={{
|
</Pressable>
|
||||||
backgroundColor: "#121215",
|
|
||||||
borderWidth: 1,
|
|
||||||
borderColor: "rgba(255,255,255,0.1)",
|
|
||||||
borderRadius: 12,
|
|
||||||
paddingHorizontal: 12,
|
|
||||||
paddingVertical: 8,
|
|
||||||
color: "#FFFFFF",
|
|
||||||
fontSize: 13,
|
|
||||||
minHeight: 42,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{/* Font ve Boyut Kontrol Çubuğu */}
|
|
||||||
<View style={{ flexDirection: "row", alignItems: "center", justifyContent: "space-between", gap: 8 }}>
|
|
||||||
{/* Font Hapları */}
|
|
||||||
<ScrollView
|
|
||||||
horizontal
|
|
||||||
showsHorizontalScrollIndicator={false}
|
|
||||||
contentContainerStyle={{ gap: 6 }}
|
|
||||||
style={{ flex: 1 }}
|
|
||||||
>
|
|
||||||
{FONT_OPTIONS.map((f) => {
|
|
||||||
const isSelected = item.fontId === f.id;
|
|
||||||
return (
|
|
||||||
<Pressable
|
|
||||||
key={f.id}
|
|
||||||
onPress={() =>
|
|
||||||
setFields((prev) => ({
|
|
||||||
...prev,
|
|
||||||
[key]: { ...prev[key], fontId: f.id },
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
style={{
|
|
||||||
backgroundColor: isSelected ? "#D4AF37" : "#242429",
|
|
||||||
paddingHorizontal: 9,
|
|
||||||
paddingVertical: 5,
|
|
||||||
borderRadius: 8,
|
|
||||||
borderWidth: 1,
|
|
||||||
borderColor: isSelected ? "#D4AF37" : "rgba(255,255,255,0.06)",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Text
|
|
||||||
style={{
|
|
||||||
color: isSelected ? "#0C0C0E" : "#D4D4D8",
|
|
||||||
fontSize: 10.5,
|
|
||||||
fontWeight: isSelected ? "700" : "500",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{f.label}
|
|
||||||
</Text>
|
|
||||||
</Pressable>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</ScrollView>
|
|
||||||
|
|
||||||
{/* Boyut Artır / Azalt */}
|
|
||||||
<View
|
|
||||||
style={{
|
|
||||||
flexDirection: "row",
|
|
||||||
alignItems: "center",
|
|
||||||
backgroundColor: "#242429",
|
|
||||||
borderRadius: 8,
|
|
||||||
paddingHorizontal: 4,
|
|
||||||
borderWidth: 1,
|
|
||||||
borderColor: "rgba(255,255,255,0.06)",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Pressable
|
|
||||||
onPress={() =>
|
|
||||||
setFields((prev) => ({
|
|
||||||
...prev,
|
|
||||||
[key]: {
|
|
||||||
...prev[key],
|
|
||||||
fontSize: Math.max(min, (prev[key].fontSize || 12) - 1),
|
|
||||||
},
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
style={{ padding: 6 }}
|
|
||||||
>
|
|
||||||
<Ionicons name="remove" size={13} color="#FFFFFF" />
|
|
||||||
</Pressable>
|
|
||||||
<Text
|
|
||||||
style={{
|
|
||||||
color: "#D4AF37",
|
|
||||||
fontSize: 11,
|
|
||||||
fontWeight: "700",
|
|
||||||
minWidth: 26,
|
|
||||||
textAlign: "center",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{item.fontSize || 12}
|
|
||||||
</Text>
|
|
||||||
<Pressable
|
|
||||||
onPress={() =>
|
|
||||||
setFields((prev) => ({
|
|
||||||
...prev,
|
|
||||||
[key]: {
|
|
||||||
...prev[key],
|
|
||||||
fontSize: Math.min(max, (prev[key].fontSize || 12) + 1),
|
|
||||||
},
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
style={{ padding: 6 }}
|
|
||||||
>
|
|
||||||
<Ionicons name="add" size={13} color="#FFFFFF" />
|
|
||||||
</Pressable>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</View>
|
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
{/* Modal: Tıklanan Metin Katmanını Detaylı Düzenleme */}
|
||||||
|
<Modal
|
||||||
|
visible={!!selectedEditField}
|
||||||
|
animationType="slide"
|
||||||
|
transparent
|
||||||
|
onRequestClose={() => setSelectedEditField(null)}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "rgba(0,0,0,0.75)",
|
||||||
|
justifyContent: "flex-end",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{selectedEditField && (() => {
|
||||||
|
const def = FIELD_DEFINITIONS.find((d) => d.key === selectedEditField)!;
|
||||||
|
const item = fields[selectedEditField];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#18181B",
|
||||||
|
borderTopLeftRadius: 28,
|
||||||
|
borderTopRightRadius: 28,
|
||||||
|
padding: 20,
|
||||||
|
maxHeight: "85%",
|
||||||
|
gap: 16,
|
||||||
|
borderTopWidth: 1,
|
||||||
|
borderColor: "rgba(212, 175, 55, 0.3)",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/* Modal Başlığı & Kapat Butonu */}
|
||||||
|
<View style={{ flexDirection: "row", justifyContent: "space-between", alignItems: "center" }}>
|
||||||
|
<View style={{ flexDirection: "row", alignItems: "center", gap: 8 }}>
|
||||||
|
<Ionicons name={def.icon as any} size={20} color="#D4AF37" />
|
||||||
|
<Text style={{ color: "#FFFFFF", fontSize: 17, fontWeight: "800" }}>
|
||||||
|
{def.label}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<Pressable
|
||||||
|
onPress={() => setSelectedEditField(null)}
|
||||||
|
style={{
|
||||||
|
width: 32,
|
||||||
|
height: 32,
|
||||||
|
borderRadius: 16,
|
||||||
|
backgroundColor: "#242429",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Ionicons name="close" size={18} color="#FFFFFF" />
|
||||||
|
</Pressable>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<ScrollView showsVerticalScrollIndicator={false} contentContainerStyle={{ gap: 16, paddingBottom: 20 }}>
|
||||||
|
{/* Görünürlük Anahtarı */}
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
alignItems: "center",
|
||||||
|
backgroundColor: "#121215",
|
||||||
|
padding: 12,
|
||||||
|
borderRadius: 14,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text style={{ color: "#FFFFFF", fontSize: 13, fontWeight: "700" }}>
|
||||||
|
Stantta Göster
|
||||||
|
</Text>
|
||||||
|
<Switch
|
||||||
|
value={item.visible}
|
||||||
|
onValueChange={(v) =>
|
||||||
|
setFields((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[selectedEditField]: { ...prev[selectedEditField], visible: v },
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
trackColor={{ false: "#27272A", true: "#D4AF37" }}
|
||||||
|
thumbColor="#FFFFFF"
|
||||||
|
ios_backgroundColor="#27272A"
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Metin Girişi (Multiline / Enter Destekli) */}
|
||||||
|
<View style={{ gap: 6 }}>
|
||||||
|
<Text style={{ color: "#D4AF37", fontSize: 12, fontWeight: "700" }}>
|
||||||
|
METİN İÇERİĞİ (ENTER İLE YENİ SATIR)
|
||||||
|
</Text>
|
||||||
|
<TextInput
|
||||||
|
value={item.text}
|
||||||
|
onChangeText={(t) =>
|
||||||
|
setFields((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[selectedEditField]: { ...prev[selectedEditField], text: t },
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
placeholder={def.placeholder}
|
||||||
|
placeholderTextColor="#71717A"
|
||||||
|
multiline
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#121215",
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: "rgba(255,255,255,0.12)",
|
||||||
|
borderRadius: 14,
|
||||||
|
paddingHorizontal: 14,
|
||||||
|
paddingVertical: 12,
|
||||||
|
color: "#FFFFFF",
|
||||||
|
fontSize: 14,
|
||||||
|
minHeight: 60,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* DİKEY KONUM / YUKARI - AŞAĞI TAŞIMA (offsetY) */}
|
||||||
|
<View style={{ gap: 8, backgroundColor: "#121215", padding: 12, borderRadius: 14 }}>
|
||||||
|
<View style={{ flexDirection: "row", justifyContent: "space-between", alignItems: "center" }}>
|
||||||
|
<Text style={{ color: "#D4AF37", fontSize: 12, fontWeight: "700" }}>
|
||||||
|
DİKEY KONUM (YUKARI / AŞAĞI)
|
||||||
|
</Text>
|
||||||
|
<Text style={{ color: "#E5C378", fontSize: 12, fontWeight: "800" }}>
|
||||||
|
{item.offsetY ? `${item.offsetY > 0 ? "+" : ""}${item.offsetY} px` : "Orijinal (0px)"}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<View style={{ flexDirection: "row", gap: 8 }}>
|
||||||
|
<Pressable
|
||||||
|
onPress={() =>
|
||||||
|
setFields((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[selectedEditField]: {
|
||||||
|
...prev[selectedEditField],
|
||||||
|
offsetY: (prev[selectedEditField].offsetY || 0) - 3,
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
style={{
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "#242429",
|
||||||
|
paddingVertical: 10,
|
||||||
|
borderRadius: 10,
|
||||||
|
alignItems: "center",
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "center",
|
||||||
|
gap: 4,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Ionicons name="arrow-up" size={14} color="#D4AF37" />
|
||||||
|
<Text style={{ color: "#FFFFFF", fontSize: 12, fontWeight: "700" }}>Yukarı (-3px)</Text>
|
||||||
|
</Pressable>
|
||||||
|
|
||||||
|
<Pressable
|
||||||
|
onPress={() =>
|
||||||
|
setFields((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[selectedEditField]: {
|
||||||
|
...prev[selectedEditField],
|
||||||
|
offsetY: (prev[selectedEditField].offsetY || 0) + 3,
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
style={{
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: "#242429",
|
||||||
|
paddingVertical: 10,
|
||||||
|
borderRadius: 10,
|
||||||
|
alignItems: "center",
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "center",
|
||||||
|
gap: 4,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Ionicons name="arrow-down" size={14} color="#D4AF37" />
|
||||||
|
<Text style={{ color: "#FFFFFF", fontSize: 12, fontWeight: "700" }}>Aşağı (+3px)</Text>
|
||||||
|
</Pressable>
|
||||||
|
|
||||||
|
{item.offsetY ? (
|
||||||
|
<Pressable
|
||||||
|
onPress={() =>
|
||||||
|
setFields((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[selectedEditField]: {
|
||||||
|
...prev[selectedEditField],
|
||||||
|
offsetY: 0,
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#3A2A2A",
|
||||||
|
paddingHorizontal: 12,
|
||||||
|
paddingVertical: 10,
|
||||||
|
borderRadius: 10,
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text style={{ color: "#EF4444", fontSize: 11, fontWeight: "700" }}>Sıfırla</Text>
|
||||||
|
</Pressable>
|
||||||
|
) : null}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* YAZI TİPİ (FONT) SEÇİMİ */}
|
||||||
|
<View style={{ gap: 8 }}>
|
||||||
|
<Text style={{ color: "#D4AF37", fontSize: 12, fontWeight: "700" }}>
|
||||||
|
YAZI TİPİ (TÜRKÇE DESTEKLİ FONT)
|
||||||
|
</Text>
|
||||||
|
<View style={{ flexDirection: "row", flexWrap: "wrap", gap: 8 }}>
|
||||||
|
{FONT_OPTIONS.map((f) => {
|
||||||
|
const isSelected = item.fontId === f.id;
|
||||||
|
return (
|
||||||
|
<Pressable
|
||||||
|
key={f.id}
|
||||||
|
onPress={() =>
|
||||||
|
setFields((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[selectedEditField]: { ...prev[selectedEditField], fontId: f.id },
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
style={{
|
||||||
|
backgroundColor: isSelected ? "#D4AF37" : "#242429",
|
||||||
|
paddingHorizontal: 14,
|
||||||
|
paddingVertical: 10,
|
||||||
|
borderRadius: 12,
|
||||||
|
borderWidth: 1.5,
|
||||||
|
borderColor: isSelected ? "#D4AF37" : "rgba(255,255,255,0.06)",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
color: isSelected ? "#0C0C0E" : "#FFFFFF",
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: isSelected ? "800" : "500",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{f.label}
|
||||||
|
</Text>
|
||||||
|
</Pressable>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* YAZI BOYUTU (FONT SIZE) */}
|
||||||
|
<View style={{ gap: 8, backgroundColor: "#121215", padding: 12, borderRadius: 14 }}>
|
||||||
|
<Text style={{ color: "#D4AF37", fontSize: 12, fontWeight: "700" }}>
|
||||||
|
YAZI BOYUTU
|
||||||
|
</Text>
|
||||||
|
<View style={{ flexDirection: "row", alignItems: "center", justifyContent: "space-between" }}>
|
||||||
|
<Pressable
|
||||||
|
onPress={() =>
|
||||||
|
setFields((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[selectedEditField]: {
|
||||||
|
...prev[selectedEditField],
|
||||||
|
fontSize: Math.max(def.min, (prev[selectedEditField].fontSize || 12) - 1),
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#242429",
|
||||||
|
paddingHorizontal: 16,
|
||||||
|
paddingVertical: 10,
|
||||||
|
borderRadius: 10,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Ionicons name="remove" size={18} color="#FFFFFF" />
|
||||||
|
</Pressable>
|
||||||
|
|
||||||
|
<Text style={{ color: "#D4AF37", fontSize: 18, fontWeight: "800" }}>
|
||||||
|
{item.fontSize || 12} px
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Pressable
|
||||||
|
onPress={() =>
|
||||||
|
setFields((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[selectedEditField]: {
|
||||||
|
...prev[selectedEditField],
|
||||||
|
fontSize: Math.min(def.max, (prev[selectedEditField].fontSize || 12) + 1),
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#242429",
|
||||||
|
paddingHorizontal: 16,
|
||||||
|
paddingVertical: 10,
|
||||||
|
borderRadius: 10,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Ionicons name="add" size={18} color="#FFFFFF" />
|
||||||
|
</Pressable>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Kaydet & Tamamla Butonu */}
|
||||||
|
<Pressable
|
||||||
|
onPress={() => setSelectedEditField(null)}
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#D4AF37",
|
||||||
|
borderRadius: 14,
|
||||||
|
paddingVertical: 14,
|
||||||
|
alignItems: "center",
|
||||||
|
marginTop: 6,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text style={{ color: "#0C0C0E", fontSize: 15, fontWeight: "800" }}>
|
||||||
|
Tamamla & Uygula
|
||||||
|
</Text>
|
||||||
|
</Pressable>
|
||||||
|
</ScrollView>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
})()}
|
||||||
|
</View>
|
||||||
|
</Modal>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{/* Output Action Buttons */}
|
{/* Output Action Buttons */}
|
||||||
|
|||||||
@@ -223,6 +223,7 @@ const QrTemplate2 = ({
|
|||||||
text: rName?.text || "The Daily Grind",
|
text: rName?.text || "The Daily Grind",
|
||||||
x: 200,
|
x: 200,
|
||||||
y: 110,
|
y: 110,
|
||||||
|
offsetY: rName?.offsetY,
|
||||||
fill: "#2c1a0e",
|
fill: "#2c1a0e",
|
||||||
fontFamily: rNameFont,
|
fontFamily: rNameFont,
|
||||||
fontSize: rName?.fontSize || 28,
|
fontSize: rName?.fontSize || 28,
|
||||||
@@ -236,6 +237,7 @@ const QrTemplate2 = ({
|
|||||||
text: sub?.text || "COFFEE & KITCHEN",
|
text: sub?.text || "COFFEE & KITCHEN",
|
||||||
x: 200,
|
x: 200,
|
||||||
y: 144,
|
y: 144,
|
||||||
|
offsetY: sub?.offsetY,
|
||||||
fill: "#3a2312",
|
fill: "#3a2312",
|
||||||
fontFamily: subFont,
|
fontFamily: subFont,
|
||||||
fontSize: sub?.fontSize || 12,
|
fontSize: sub?.fontSize || 12,
|
||||||
@@ -249,6 +251,7 @@ const QrTemplate2 = ({
|
|||||||
text: cta?.text || "MENÜYÜ GÖRMEK İÇİN OKUTUN",
|
text: cta?.text || "MENÜYÜ GÖRMEK İÇİN OKUTUN",
|
||||||
x: 200,
|
x: 200,
|
||||||
y: 486,
|
y: 486,
|
||||||
|
offsetY: cta?.offsetY,
|
||||||
fill: "#2c1a0e",
|
fill: "#2c1a0e",
|
||||||
fontFamily: ctaFont,
|
fontFamily: ctaFont,
|
||||||
fontSize: cta?.fontSize || 15,
|
fontSize: cta?.fontSize || 15,
|
||||||
@@ -262,6 +265,7 @@ const QrTemplate2 = ({
|
|||||||
text: wifi?.text || "WiFi: DailyGrind | Şifre: coffee2026",
|
text: wifi?.text || "WiFi: DailyGrind | Şifre: coffee2026",
|
||||||
x: 200,
|
x: 200,
|
||||||
y: 520,
|
y: 520,
|
||||||
|
offsetY: wifi?.offsetY,
|
||||||
fill: "#3a2312",
|
fill: "#3a2312",
|
||||||
fontFamily: infoFont,
|
fontFamily: infoFont,
|
||||||
fontSize: wifi?.fontSize || 10.5,
|
fontSize: wifi?.fontSize || 10.5,
|
||||||
@@ -280,6 +284,7 @@ const QrTemplate2 = ({
|
|||||||
.join(" • "),
|
.join(" • "),
|
||||||
x: 200,
|
x: 200,
|
||||||
y: 544,
|
y: 544,
|
||||||
|
offsetY: table?.offsetY || social?.offsetY,
|
||||||
fill: "#8c6239",
|
fill: "#8c6239",
|
||||||
fontFamily: infoFont,
|
fontFamily: infoFont,
|
||||||
fontSize: table?.fontSize || social?.fontSize || 10,
|
fontSize: table?.fontSize || social?.fontSize || 10,
|
||||||
@@ -287,6 +292,7 @@ const QrTemplate2 = ({
|
|||||||
letterSpacing: 1,
|
letterSpacing: 1,
|
||||||
})}
|
})}
|
||||||
|
|
||||||
|
|
||||||
<Text
|
<Text
|
||||||
x={200}
|
x={200}
|
||||||
y={611}
|
y={611}
|
||||||
|
|||||||
@@ -258,6 +258,7 @@ const QrTemplate3 = ({
|
|||||||
text: table?.text || "MASA NO: 01",
|
text: table?.text || "MASA NO: 01",
|
||||||
x: 200,
|
x: 200,
|
||||||
y: 50,
|
y: 50,
|
||||||
|
offsetY: table?.offsetY,
|
||||||
fill: "#18181b",
|
fill: "#18181b",
|
||||||
fontFamily: infoFont,
|
fontFamily: infoFont,
|
||||||
fontSize: table?.fontSize || 11,
|
fontSize: table?.fontSize || 11,
|
||||||
@@ -282,6 +283,7 @@ const QrTemplate3 = ({
|
|||||||
text: rName?.text || "BELLA NAPOLI",
|
text: rName?.text || "BELLA NAPOLI",
|
||||||
x: 200,
|
x: 200,
|
||||||
y: 130,
|
y: 130,
|
||||||
|
offsetY: rName?.offsetY,
|
||||||
fill: "#18181b",
|
fill: "#18181b",
|
||||||
fontFamily: rNameFont,
|
fontFamily: rNameFont,
|
||||||
fontSize: rName?.fontSize || 26,
|
fontSize: rName?.fontSize || 26,
|
||||||
@@ -295,6 +297,7 @@ const QrTemplate3 = ({
|
|||||||
text: sub?.text || "AUTENTICA CUCINA ITALIANA",
|
text: sub?.text || "AUTENTICA CUCINA ITALIANA",
|
||||||
x: 200,
|
x: 200,
|
||||||
y: 222,
|
y: 222,
|
||||||
|
offsetY: sub?.offsetY,
|
||||||
fill: "#2e7d32",
|
fill: "#2e7d32",
|
||||||
fontFamily: subFont,
|
fontFamily: subFont,
|
||||||
fontSize: sub?.fontSize || 11.5,
|
fontSize: sub?.fontSize || 11.5,
|
||||||
@@ -308,6 +311,7 @@ const QrTemplate3 = ({
|
|||||||
text: cta?.text || "MENÜYÜ GÖRMEK İÇİN OKUTUN",
|
text: cta?.text || "MENÜYÜ GÖRMEK İÇİN OKUTUN",
|
||||||
x: 200,
|
x: 200,
|
||||||
y: 474,
|
y: 474,
|
||||||
|
offsetY: cta?.offsetY,
|
||||||
fill: "#b92b27",
|
fill: "#b92b27",
|
||||||
fontFamily: ctaFont,
|
fontFamily: ctaFont,
|
||||||
fontSize: cta?.fontSize || 13,
|
fontSize: cta?.fontSize || 13,
|
||||||
@@ -321,6 +325,7 @@ const QrTemplate3 = ({
|
|||||||
text: wifi?.text || "WiFi: GourmetBistro | Şifre: lezzetli01",
|
text: wifi?.text || "WiFi: GourmetBistro | Şifre: lezzetli01",
|
||||||
x: 200,
|
x: 200,
|
||||||
y: 546,
|
y: 546,
|
||||||
|
offsetY: wifi?.offsetY,
|
||||||
fill: "#3e2723",
|
fill: "#3e2723",
|
||||||
fontFamily: infoFont,
|
fontFamily: infoFont,
|
||||||
fontSize: wifi?.fontSize || 10.5,
|
fontSize: wifi?.fontSize || 10.5,
|
||||||
@@ -333,12 +338,14 @@ const QrTemplate3 = ({
|
|||||||
text: social?.text || "BİZİ TAKİP EDİN | @gourmetbistro",
|
text: social?.text || "BİZİ TAKİP EDİN | @gourmetbistro",
|
||||||
x: 200,
|
x: 200,
|
||||||
y: 570,
|
y: 570,
|
||||||
|
offsetY: social?.offsetY,
|
||||||
fill: "#b92b27",
|
fill: "#b92b27",
|
||||||
fontFamily: infoFont,
|
fontFamily: infoFont,
|
||||||
fontSize: social?.fontSize || 10.5,
|
fontSize: social?.fontSize || 10.5,
|
||||||
fontWeight: "bold",
|
fontWeight: "bold",
|
||||||
letterSpacing: 0.5,
|
letterSpacing: 0.5,
|
||||||
})}
|
})}
|
||||||
|
|
||||||
</G>
|
</G>
|
||||||
</Svg>
|
</Svg>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -191,6 +191,7 @@ const QrTemplate4 = ({
|
|||||||
text: table?.text || "MASA NO: 01",
|
text: table?.text || "MASA NO: 01",
|
||||||
x: 200,
|
x: 200,
|
||||||
y: 56,
|
y: 56,
|
||||||
|
offsetY: table?.offsetY,
|
||||||
fill: "#c59b4b",
|
fill: "#c59b4b",
|
||||||
fontFamily: infoFont,
|
fontFamily: infoFont,
|
||||||
fontSize: table?.fontSize || 11,
|
fontSize: table?.fontSize || 11,
|
||||||
@@ -204,6 +205,7 @@ const QrTemplate4 = ({
|
|||||||
text: rName?.text || "THE CRIMSON PETAL",
|
text: rName?.text || "THE CRIMSON PETAL",
|
||||||
x: 200,
|
x: 200,
|
||||||
y: 114,
|
y: 114,
|
||||||
|
offsetY: rName?.offsetY,
|
||||||
fill: "#111111",
|
fill: "#111111",
|
||||||
fontFamily: rNameFont,
|
fontFamily: rNameFont,
|
||||||
fontSize: rName?.fontSize || 24,
|
fontSize: rName?.fontSize || 24,
|
||||||
@@ -217,6 +219,7 @@ const QrTemplate4 = ({
|
|||||||
text: sub?.text || "FINE DINING EXPERIENCE",
|
text: sub?.text || "FINE DINING EXPERIENCE",
|
||||||
x: 200,
|
x: 200,
|
||||||
y: 154,
|
y: 154,
|
||||||
|
offsetY: sub?.offsetY,
|
||||||
fill: "#71717a",
|
fill: "#71717a",
|
||||||
fontFamily: subFont,
|
fontFamily: subFont,
|
||||||
fontSize: sub?.fontSize || 11,
|
fontSize: sub?.fontSize || 11,
|
||||||
@@ -230,6 +233,7 @@ const QrTemplate4 = ({
|
|||||||
text: cta?.text || "MENÜYÜ GÖRMEK İÇİN OKUTUN",
|
text: cta?.text || "MENÜYÜ GÖRMEK İÇİN OKUTUN",
|
||||||
x: 200,
|
x: 200,
|
||||||
y: 440,
|
y: 440,
|
||||||
|
offsetY: cta?.offsetY,
|
||||||
fill: "#111111",
|
fill: "#111111",
|
||||||
fontFamily: ctaFont,
|
fontFamily: ctaFont,
|
||||||
fontSize: cta?.fontSize || 15,
|
fontSize: cta?.fontSize || 15,
|
||||||
@@ -243,6 +247,7 @@ const QrTemplate4 = ({
|
|||||||
text: wifi?.text || "WiFi: CrimsonGuest | Şifre: petal2026",
|
text: wifi?.text || "WiFi: CrimsonGuest | Şifre: petal2026",
|
||||||
x: 200,
|
x: 200,
|
||||||
y: 488,
|
y: 488,
|
||||||
|
offsetY: wifi?.offsetY,
|
||||||
fill: "#71717a",
|
fill: "#71717a",
|
||||||
fontFamily: infoFont,
|
fontFamily: infoFont,
|
||||||
fontSize: wifi?.fontSize || 10.5,
|
fontSize: wifi?.fontSize || 10.5,
|
||||||
@@ -256,6 +261,7 @@ const QrTemplate4 = ({
|
|||||||
text: social?.text || "@thecrimsonpetal",
|
text: social?.text || "@thecrimsonpetal",
|
||||||
x: 200,
|
x: 200,
|
||||||
y: 514,
|
y: 514,
|
||||||
|
offsetY: social?.offsetY,
|
||||||
fill: "#c59b4b",
|
fill: "#c59b4b",
|
||||||
fontFamily: infoFont,
|
fontFamily: infoFont,
|
||||||
fontSize: social?.fontSize || 10.5,
|
fontSize: social?.fontSize || 10.5,
|
||||||
@@ -263,6 +269,7 @@ const QrTemplate4 = ({
|
|||||||
letterSpacing: 0.5,
|
letterSpacing: 0.5,
|
||||||
})}
|
})}
|
||||||
</G>
|
</G>
|
||||||
|
|
||||||
</Svg>
|
</Svg>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ const QrTemplate5 = ({
|
|||||||
text: table?.text || "MASA NO: 01",
|
text: table?.text || "MASA NO: 01",
|
||||||
x: 190,
|
x: 190,
|
||||||
y: 40,
|
y: 40,
|
||||||
|
offsetY: table?.offsetY,
|
||||||
fill: "#003554",
|
fill: "#003554",
|
||||||
fontFamily: infoFont,
|
fontFamily: infoFont,
|
||||||
fontSize: table?.fontSize || 11,
|
fontSize: table?.fontSize || 11,
|
||||||
@@ -113,6 +114,7 @@ const QrTemplate5 = ({
|
|||||||
text: rName?.text || "THE URBAN FORK",
|
text: rName?.text || "THE URBAN FORK",
|
||||||
x: 190,
|
x: 190,
|
||||||
y: 86,
|
y: 86,
|
||||||
|
offsetY: rName?.offsetY,
|
||||||
fill: "#003554",
|
fill: "#003554",
|
||||||
fontFamily: rNameFont,
|
fontFamily: rNameFont,
|
||||||
fontSize: rName?.fontSize || 24,
|
fontSize: rName?.fontSize || 24,
|
||||||
@@ -126,6 +128,7 @@ const QrTemplate5 = ({
|
|||||||
text: cta?.text || "DİJİTAL MENÜYÜ GÖRÜNTÜLE",
|
text: cta?.text || "DİJİTAL MENÜYÜ GÖRÜNTÜLE",
|
||||||
x: 190,
|
x: 190,
|
||||||
y: 160,
|
y: 160,
|
||||||
|
offsetY: cta?.offsetY,
|
||||||
fill: "#003554",
|
fill: "#003554",
|
||||||
fontFamily: ctaFont,
|
fontFamily: ctaFont,
|
||||||
fontSize: cta?.fontSize || 13,
|
fontSize: cta?.fontSize || 13,
|
||||||
@@ -139,6 +142,7 @@ const QrTemplate5 = ({
|
|||||||
text: sub?.text || "FRESH FLAVORS DAILY",
|
text: sub?.text || "FRESH FLAVORS DAILY",
|
||||||
x: 190,
|
x: 190,
|
||||||
y: 402,
|
y: 402,
|
||||||
|
offsetY: sub?.offsetY,
|
||||||
fill: "#003554",
|
fill: "#003554",
|
||||||
fontFamily: subFont,
|
fontFamily: subFont,
|
||||||
fontSize: sub?.fontSize || 13,
|
fontSize: sub?.fontSize || 13,
|
||||||
@@ -152,6 +156,7 @@ const QrTemplate5 = ({
|
|||||||
text: wifi?.text || "WiFi: UrbanFork | Şifre: urban2026",
|
text: wifi?.text || "WiFi: UrbanFork | Şifre: urban2026",
|
||||||
x: 190,
|
x: 190,
|
||||||
y: 430,
|
y: 430,
|
||||||
|
offsetY: wifi?.offsetY,
|
||||||
fill: "#003554",
|
fill: "#003554",
|
||||||
fontFamily: infoFont,
|
fontFamily: infoFont,
|
||||||
fontSize: wifi?.fontSize || 10,
|
fontSize: wifi?.fontSize || 10,
|
||||||
@@ -165,6 +170,7 @@ const QrTemplate5 = ({
|
|||||||
text: social?.text || "@theurbanfork",
|
text: social?.text || "@theurbanfork",
|
||||||
x: 190,
|
x: 190,
|
||||||
y: 454,
|
y: 454,
|
||||||
|
offsetY: social?.offsetY,
|
||||||
fill: "#003554",
|
fill: "#003554",
|
||||||
fontFamily: infoFont,
|
fontFamily: infoFont,
|
||||||
fontSize: social?.fontSize || 10,
|
fontSize: social?.fontSize || 10,
|
||||||
|
|||||||
@@ -0,0 +1,260 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import Svg, {
|
||||||
|
Defs,
|
||||||
|
G,
|
||||||
|
Path,
|
||||||
|
Circle,
|
||||||
|
Rect,
|
||||||
|
Use,
|
||||||
|
Text,
|
||||||
|
Image,
|
||||||
|
} from "react-native-svg";
|
||||||
|
import { type QrTemplateProps, getFontFamily, renderSvgLines } from "./index";
|
||||||
|
|
||||||
|
const QrTemplate6 = ({
|
||||||
|
qrBase64,
|
||||||
|
fields,
|
||||||
|
...props
|
||||||
|
}: QrTemplateProps) => {
|
||||||
|
const rName = fields?.restaurantName;
|
||||||
|
const sub = fields?.subtitle;
|
||||||
|
const table = fields?.tableNo;
|
||||||
|
const cta = fields?.ctaText;
|
||||||
|
const wifi = fields?.wifiText;
|
||||||
|
const social = fields?.socialText;
|
||||||
|
|
||||||
|
const rNameFont = getFontFamily(rName?.fontId, "Georgia, 'Times New Roman', serif");
|
||||||
|
const subFont = getFontFamily(sub?.fontId, "System, -apple-system, Roboto, sans-serif");
|
||||||
|
const ctaFont = getFontFamily(cta?.fontId, "Georgia, 'Times New Roman', serif");
|
||||||
|
const infoFont = getFontFamily(wifi?.fontId, "System, -apple-system, Roboto, sans-serif");
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Svg width={300} height={435} viewBox="0 0 400 580" {...props}>
|
||||||
|
<Defs>
|
||||||
|
<G id="b6">
|
||||||
|
<Path
|
||||||
|
fill="none"
|
||||||
|
stroke="#c59b58"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeWidth={1.2}
|
||||||
|
d="M0 0c10 25 12 55 5 85"
|
||||||
|
/>
|
||||||
|
<Path
|
||||||
|
fill="#f4efe6"
|
||||||
|
stroke="#c59b58"
|
||||||
|
strokeWidth={1.1}
|
||||||
|
d="M3 15c-11-5-15 9-1 9 4 0 4-6 1-9Z"
|
||||||
|
/>
|
||||||
|
<Path
|
||||||
|
fill="#f4efe6"
|
||||||
|
stroke="#9e4d28"
|
||||||
|
strokeWidth={1.1}
|
||||||
|
d="M5 22c11-6 17 6 3 10-4 0-4-6-3-10Zm2 20c-12-6-17 8-3 10 4 0 4-6 3-10Z"
|
||||||
|
/>
|
||||||
|
<Path
|
||||||
|
fill="#f4efe6"
|
||||||
|
stroke="#c59b58"
|
||||||
|
strokeWidth={1.1}
|
||||||
|
d="M8 50c12-6 16 8 2 12-4 0-4-7-2-12ZM6 70c-10-5-14 8-2 10 3 0 4-6 2-10Z"
|
||||||
|
/>
|
||||||
|
<Path
|
||||||
|
fill="#f4efe6"
|
||||||
|
stroke="#9e4d28"
|
||||||
|
strokeWidth={1.1}
|
||||||
|
d="M5 78c11-4 15 8 3 12-4 0-4-6-3-12Z"
|
||||||
|
/>
|
||||||
|
<Circle cx={-10} cy={18} r={1.5} fill="#c59b58" />
|
||||||
|
<Circle cx={18} cy={46} r={1.5} fill="#9e4d28" />
|
||||||
|
</G>
|
||||||
|
<G id="a6">
|
||||||
|
<Path
|
||||||
|
fill="#a64423"
|
||||||
|
d="M0-18C4-12 8-6 8 0c6-4 8 6 4 12 4-2 6 4 2 8S2 26 0 26s-10-2-14-6-2-10 2-8c-4-6-2-16 4-12 0-6 4-12 8-18"
|
||||||
|
/>
|
||||||
|
<Path
|
||||||
|
fill="#f4efe6"
|
||||||
|
d="M-4 4v8c0 3 2 4 4 4v8c2-8 4-9 4-12V4H3v7c0 2-1.5 3-3 3s-3-1-3-3V4Z"
|
||||||
|
/>
|
||||||
|
<Path stroke="#f4efe6" d="M0 4v8" />
|
||||||
|
</G>
|
||||||
|
</Defs>
|
||||||
|
<Path fill="#434b54" d="M0 0h400v580H0z" />
|
||||||
|
<Rect
|
||||||
|
width={360}
|
||||||
|
height={548}
|
||||||
|
x={20}
|
||||||
|
y={16}
|
||||||
|
fill="#f6efe3"
|
||||||
|
stroke="#122a42"
|
||||||
|
strokeWidth={1.5}
|
||||||
|
rx={16}
|
||||||
|
/>
|
||||||
|
<Path
|
||||||
|
fill="none"
|
||||||
|
stroke="#122a42"
|
||||||
|
strokeWidth={1.2}
|
||||||
|
d="M46 32h308a12 12 0 0 1 12 12v492a12 12 0 0 1-12 12H46a12 12 0 0 1-12-12V44a12 12 0 0 1 12-12Z"
|
||||||
|
/>
|
||||||
|
<Path
|
||||||
|
fill="none"
|
||||||
|
stroke="#122a42"
|
||||||
|
strokeWidth={1.2}
|
||||||
|
d="M34 46a12 12 0 0 0 12-12m320 12a12 12 0 0 1-12-12M34 534a12 12 0 0 1 12 12m320-12a12 12 0 0 0-12 12"
|
||||||
|
/>
|
||||||
|
<Path stroke="#c59b58" d="M34 135h332M34 500h332" />
|
||||||
|
<Use href="#a6" transform="matrix(.85 0 0 .85 200 52)" />
|
||||||
|
<Use href="#b6" transform="matrix(.8 0 0 .8 42 42)" />
|
||||||
|
<Use href="#b6" transform="matrix(-.8 0 0 .8 358 42)" />
|
||||||
|
<Use href="#b6" transform="matrix(.95 0 0 .95 40 185)" />
|
||||||
|
<Use href="#b6" transform="matrix(-.95 0 0 .95 360 185)" />
|
||||||
|
<Use href="#a6" transform="matrix(.65 0 0 .65 68 320)" />
|
||||||
|
<Use href="#a6" transform="matrix(.65 0 0 .65 332 320)" />
|
||||||
|
<Use href="#b6" transform="matrix(.95 0 0 .95 40 360)" />
|
||||||
|
<Use href="#b6" transform="matrix(-.95 0 0 .95 360 360)" />
|
||||||
|
|
||||||
|
{/* QR Placeholder / Gerçek QR */}
|
||||||
|
<G transform="translate(95 205)">
|
||||||
|
<Path
|
||||||
|
fill="#fdfbf7"
|
||||||
|
stroke="#122a42"
|
||||||
|
strokeWidth={3}
|
||||||
|
d="M0 0h210v210H0z"
|
||||||
|
/>
|
||||||
|
<Path
|
||||||
|
fill="none"
|
||||||
|
stroke="#c59b58"
|
||||||
|
strokeWidth={1.5}
|
||||||
|
d="M4 4h202v202H4z"
|
||||||
|
/>
|
||||||
|
{qrBase64 ? (
|
||||||
|
<Image
|
||||||
|
href={`data:image/png;base64,${qrBase64}`}
|
||||||
|
x={10}
|
||||||
|
y={10}
|
||||||
|
width={190}
|
||||||
|
height={190}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<Path
|
||||||
|
fill="#faf8f5"
|
||||||
|
stroke="#122a42"
|
||||||
|
strokeDasharray="4 3"
|
||||||
|
d="M12 12h186v186H12z"
|
||||||
|
/>
|
||||||
|
<Circle
|
||||||
|
cx={105}
|
||||||
|
cy={95}
|
||||||
|
r={16}
|
||||||
|
fill="#f6efe3"
|
||||||
|
stroke="#c59b58"
|
||||||
|
strokeWidth={1.2}
|
||||||
|
/>
|
||||||
|
<Use href="#a6" transform="matrix(.45 0 0 .45 105 93)" />
|
||||||
|
<Text
|
||||||
|
x={105}
|
||||||
|
y={128}
|
||||||
|
fill="#122a42"
|
||||||
|
fontFamily="System, sans-serif"
|
||||||
|
fontSize={11}
|
||||||
|
fontWeight="bold"
|
||||||
|
letterSpacing={1.5}
|
||||||
|
textAnchor="middle"
|
||||||
|
>
|
||||||
|
{"QR KOD ALANI"}
|
||||||
|
</Text>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</G>
|
||||||
|
|
||||||
|
{/* Metinler */}
|
||||||
|
<G textAnchor="middle">
|
||||||
|
{/* Masa Numarası */}
|
||||||
|
{table?.visible !== false &&
|
||||||
|
renderSvgLines({
|
||||||
|
text: table?.text || "MASA NO: 01",
|
||||||
|
x: 200,
|
||||||
|
y: 36,
|
||||||
|
offsetY: table?.offsetY,
|
||||||
|
fill: "#122a42",
|
||||||
|
fontFamily: infoFont,
|
||||||
|
fontSize: table?.fontSize || 10,
|
||||||
|
fontWeight: "bold",
|
||||||
|
letterSpacing: 1.5,
|
||||||
|
})}
|
||||||
|
|
||||||
|
{/* Restoran Başlığı */}
|
||||||
|
{rName?.visible !== false &&
|
||||||
|
renderSvgLines({
|
||||||
|
text: rName?.text || "THE STONEHEARTH GRILL",
|
||||||
|
x: 200,
|
||||||
|
y: 84,
|
||||||
|
offsetY: rName?.offsetY,
|
||||||
|
fill: "#a64423",
|
||||||
|
fontFamily: rNameFont,
|
||||||
|
fontSize: rName?.fontSize || 19,
|
||||||
|
fontWeight: "bold",
|
||||||
|
letterSpacing: 1.5,
|
||||||
|
})}
|
||||||
|
|
||||||
|
{/* Slogan */}
|
||||||
|
{sub?.visible !== false &&
|
||||||
|
renderSvgLines({
|
||||||
|
text: sub?.text || "SCAN. ORDER. ENJOY.",
|
||||||
|
x: 200,
|
||||||
|
y: 118,
|
||||||
|
offsetY: sub?.offsetY,
|
||||||
|
fill: "#122a42",
|
||||||
|
fontFamily: subFont,
|
||||||
|
fontSize: sub?.fontSize || 10,
|
||||||
|
fontWeight: "bold",
|
||||||
|
letterSpacing: 2,
|
||||||
|
})}
|
||||||
|
|
||||||
|
{/* CTA */}
|
||||||
|
{cta?.visible !== false &&
|
||||||
|
renderSvgLines({
|
||||||
|
text: cta?.text || "VIEW OUR MENU & ORDER ONLINE",
|
||||||
|
x: 200,
|
||||||
|
y: 160,
|
||||||
|
offsetY: cta?.offsetY,
|
||||||
|
fill: "#122a42",
|
||||||
|
fontFamily: ctaFont,
|
||||||
|
fontSize: cta?.fontSize || 13,
|
||||||
|
fontWeight: "bold",
|
||||||
|
letterSpacing: 0.5,
|
||||||
|
})}
|
||||||
|
|
||||||
|
{/* WiFi */}
|
||||||
|
{wifi?.visible !== false &&
|
||||||
|
renderSvgLines({
|
||||||
|
text: wifi?.text || "FREE WIFI: StonehearthGuest | PW: Grill720",
|
||||||
|
x: 200,
|
||||||
|
y: 524,
|
||||||
|
offsetY: wifi?.offsetY,
|
||||||
|
fill: "#222",
|
||||||
|
fontFamily: infoFont,
|
||||||
|
fontSize: wifi?.fontSize || 9,
|
||||||
|
fontWeight: "bold",
|
||||||
|
letterSpacing: 0.2,
|
||||||
|
})}
|
||||||
|
|
||||||
|
{/* Sosyal Medya */}
|
||||||
|
{social?.visible !== false &&
|
||||||
|
renderSvgLines({
|
||||||
|
text: social?.text || "Follow Us @StonehearthGrill",
|
||||||
|
x: 200,
|
||||||
|
y: 540,
|
||||||
|
offsetY: social?.offsetY,
|
||||||
|
fill: "#222",
|
||||||
|
fontFamily: infoFont,
|
||||||
|
fontSize: social?.fontSize || 9,
|
||||||
|
fontWeight: "bold",
|
||||||
|
letterSpacing: 0.2,
|
||||||
|
})}
|
||||||
|
</G>
|
||||||
|
</Svg>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default QrTemplate6;
|
||||||
@@ -137,6 +137,7 @@ const QrTemplateLumiere = ({
|
|||||||
text: rName?.text || "LUMIÈRE",
|
text: rName?.text || "LUMIÈRE",
|
||||||
x: 300,
|
x: 300,
|
||||||
y: 148,
|
y: 148,
|
||||||
|
offsetY: rName?.offsetY,
|
||||||
fill: "#d4af37",
|
fill: "#d4af37",
|
||||||
fontFamily: rNameFont,
|
fontFamily: rNameFont,
|
||||||
fontSize: rName?.fontSize || 30,
|
fontSize: rName?.fontSize || 30,
|
||||||
@@ -150,6 +151,7 @@ const QrTemplateLumiere = ({
|
|||||||
text: sub?.text || "RESTAURANT & BAR | MODERN CUISINE",
|
text: sub?.text || "RESTAURANT & BAR | MODERN CUISINE",
|
||||||
x: 300,
|
x: 300,
|
||||||
y: 178,
|
y: 178,
|
||||||
|
offsetY: sub?.offsetY,
|
||||||
fill: "#e5c378",
|
fill: "#e5c378",
|
||||||
fontFamily: subFont,
|
fontFamily: subFont,
|
||||||
fontSize: sub?.fontSize || 11,
|
fontSize: sub?.fontSize || 11,
|
||||||
@@ -163,6 +165,7 @@ const QrTemplateLumiere = ({
|
|||||||
text: cta?.text || "MENÜYÜ GÖRMEK İÇİN OKUTUN",
|
text: cta?.text || "MENÜYÜ GÖRMEK İÇİN OKUTUN",
|
||||||
x: 300,
|
x: 300,
|
||||||
y: 472,
|
y: 472,
|
||||||
|
offsetY: cta?.offsetY,
|
||||||
fill: "#d4af37",
|
fill: "#d4af37",
|
||||||
fontFamily: ctaFont,
|
fontFamily: ctaFont,
|
||||||
fontSize: cta?.fontSize || 13,
|
fontSize: cta?.fontSize || 13,
|
||||||
@@ -176,6 +179,7 @@ const QrTemplateLumiere = ({
|
|||||||
text: social?.text || "Rezervasyon: 0212 555 0199",
|
text: social?.text || "Rezervasyon: 0212 555 0199",
|
||||||
x: 300,
|
x: 300,
|
||||||
y: 504,
|
y: 504,
|
||||||
|
offsetY: social?.offsetY,
|
||||||
fill: "#e2ddd2",
|
fill: "#e2ddd2",
|
||||||
fontFamily: infoFont,
|
fontFamily: infoFont,
|
||||||
fontSize: social?.fontSize || 10.5,
|
fontSize: social?.fontSize || 10.5,
|
||||||
@@ -194,12 +198,14 @@ const QrTemplateLumiere = ({
|
|||||||
.join(" • "),
|
.join(" • "),
|
||||||
x: 300,
|
x: 300,
|
||||||
y: 526,
|
y: 526,
|
||||||
|
offsetY: table?.offsetY || wifi?.offsetY,
|
||||||
fill: "#c5a059",
|
fill: "#c5a059",
|
||||||
fontFamily: infoFont,
|
fontFamily: infoFont,
|
||||||
fontSize: table?.fontSize || wifi?.fontSize || 10,
|
fontSize: table?.fontSize || wifi?.fontSize || 10,
|
||||||
fontWeight: 600,
|
fontWeight: 600,
|
||||||
letterSpacing: 1,
|
letterSpacing: 1,
|
||||||
})}
|
})}
|
||||||
|
|
||||||
</G>
|
</G>
|
||||||
</Svg>
|
</Svg>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -5,11 +5,13 @@ import QrTemplate2 from "./QrTemplate2";
|
|||||||
import QrTemplate3 from "./QrTemplate3";
|
import QrTemplate3 from "./QrTemplate3";
|
||||||
import QrTemplate4 from "./QrTemplate4";
|
import QrTemplate4 from "./QrTemplate4";
|
||||||
import QrTemplate5 from "./QrTemplate5";
|
import QrTemplate5 from "./QrTemplate5";
|
||||||
|
import QrTemplate6 from "./QrTemplate6";
|
||||||
|
|
||||||
export interface TextItemConfig {
|
export interface TextItemConfig {
|
||||||
text: string;
|
text: string;
|
||||||
fontSize?: number;
|
fontSize?: number;
|
||||||
fontId?: string;
|
fontId?: string;
|
||||||
|
offsetY?: number; // Dikey konum kaydırma (yukarı / aşağı)
|
||||||
visible?: boolean;
|
visible?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,11 +64,12 @@ export function getFontFamily(fontId?: string, defaultFamily = "Georgia, serif")
|
|||||||
return found ? found.fontFamily : defaultFamily;
|
return found ? found.fontFamily : defaultFamily;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Çok satırlı (Enter / \n) metinleri SVG içinde alt alta kusursuz render eden yardımcı fonksiyon
|
// Çok satırlı (Enter / \n) ve dikey kaydırmalı (offsetY) SVG metin render fonksiyonu
|
||||||
export function renderSvgLines({
|
export function renderSvgLines({
|
||||||
text,
|
text,
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
|
offsetY = 0,
|
||||||
lineHeight,
|
lineHeight,
|
||||||
fill,
|
fill,
|
||||||
fontFamily,
|
fontFamily,
|
||||||
@@ -78,6 +81,7 @@ export function renderSvgLines({
|
|||||||
text?: string;
|
text?: string;
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
|
offsetY?: number;
|
||||||
lineHeight?: number;
|
lineHeight?: number;
|
||||||
fill?: string;
|
fill?: string;
|
||||||
fontFamily?: string;
|
fontFamily?: string;
|
||||||
@@ -89,6 +93,7 @@ export function renderSvgLines({
|
|||||||
if (!text) return null;
|
if (!text) return null;
|
||||||
const lines = text.split("\n");
|
const lines = text.split("\n");
|
||||||
const computedLineHeight = lineHeight || (fontSize ? fontSize * 1.25 : 18);
|
const computedLineHeight = lineHeight || (fontSize ? fontSize * 1.25 : 18);
|
||||||
|
const startY = y + (offsetY || 0);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -96,7 +101,7 @@ export function renderSvgLines({
|
|||||||
<SvgText
|
<SvgText
|
||||||
key={idx}
|
key={idx}
|
||||||
x={x}
|
x={x}
|
||||||
y={y + idx * computedLineHeight}
|
y={startY + idx * computedLineHeight}
|
||||||
fill={fill}
|
fill={fill}
|
||||||
fontFamily={fontFamily}
|
fontFamily={fontFamily}
|
||||||
fontSize={fontSize}
|
fontSize={fontSize}
|
||||||
@@ -121,6 +126,7 @@ export const COMPONENT_TEMPLATES: Record<
|
|||||||
"qr-3": QrTemplate3,
|
"qr-3": QrTemplate3,
|
||||||
"qr-4": QrTemplate4,
|
"qr-4": QrTemplate4,
|
||||||
"qr-5": QrTemplate5,
|
"qr-5": QrTemplate5,
|
||||||
|
"qr-6": QrTemplate6,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Her template'in aspect ratio'su (width/height)
|
// Her template'in aspect ratio'su (width/height)
|
||||||
@@ -130,4 +136,5 @@ export const TEMPLATE_ASPECT_RATIOS: Record<string, number> = {
|
|||||||
"qr-3": 400 / 650, // 400x650 = standart kart
|
"qr-3": 400 / 650, // 400x650 = standart kart
|
||||||
"qr-4": 400 / 580, // 400x580 = zarif altın çerçeve
|
"qr-4": 400 / 580, // 400x580 = zarif altın çerçeve
|
||||||
"qr-5": 380 / 500, // 380x500 = PNG arka planlı modern kart
|
"qr-5": 380 / 500, // 380x500 = PNG arka planlı modern kart
|
||||||
|
"qr-6": 400 / 580, // 400x580 = taş & ızgara vintage stant
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,327 @@
|
|||||||
|
import Svg, {
|
||||||
|
SvgProps,
|
||||||
|
Defs,
|
||||||
|
G,
|
||||||
|
Path,
|
||||||
|
Circle,
|
||||||
|
Rect,
|
||||||
|
Use,
|
||||||
|
Text,
|
||||||
|
} from "react-native-svg"
|
||||||
|
import { memo } from "react"
|
||||||
|
const SvgComponent = (props: SvgProps) => (
|
||||||
|
<Svg width={400} height={580} {...props}>
|
||||||
|
<Defs>
|
||||||
|
<G id="b">
|
||||||
|
<Path
|
||||||
|
fill="none"
|
||||||
|
stroke="#c59b58"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeWidth={1.2}
|
||||||
|
d="M0 0c10 25 12 55 5 85"
|
||||||
|
/>
|
||||||
|
<Path
|
||||||
|
fill="#f4efe6"
|
||||||
|
stroke="#c59b58"
|
||||||
|
strokeWidth={1.1}
|
||||||
|
d="M3 15c-11-5-15 9-1 9 4 0 4-6 1-9Z"
|
||||||
|
/>
|
||||||
|
<Path
|
||||||
|
fill="#f4efe6"
|
||||||
|
stroke="#9e4d28"
|
||||||
|
strokeWidth={1.1}
|
||||||
|
d="M5 22c11-6 17 6 3 10-4 0-4-6-3-10Zm2 20c-12-6-17 8-3 10 4 0 4-6 3-10Z"
|
||||||
|
/>
|
||||||
|
<Path
|
||||||
|
fill="#f4efe6"
|
||||||
|
stroke="#c59b58"
|
||||||
|
strokeWidth={1.1}
|
||||||
|
d="M8 50c12-6 16 8 2 12-4 0-4-7-2-12ZM6 70c-10-5-14 8-2 10 3 0 4-6 2-10Z"
|
||||||
|
/>
|
||||||
|
<Path
|
||||||
|
fill="#f4efe6"
|
||||||
|
stroke="#9e4d28"
|
||||||
|
strokeWidth={1.1}
|
||||||
|
d="M5 78c11-4 15 8 3 12-4 0-4-6-3-12Z"
|
||||||
|
/>
|
||||||
|
<Circle cx={-10} cy={18} r={1.5} fill="#c59b58" />
|
||||||
|
<Circle cx={18} cy={46} r={1.5} fill="#9e4d28" />
|
||||||
|
</G>
|
||||||
|
<G id="a">
|
||||||
|
<Path
|
||||||
|
fill="#a64423"
|
||||||
|
d="M0-18C4-12 8-6 8 0c6-4 8 6 4 12 4-2 6 4 2 8S2 26 0 26s-10-2-14-6-2-10 2-8c-4-6-2-16 4-12 0-6 4-12 8-18"
|
||||||
|
/>
|
||||||
|
<Path
|
||||||
|
fill="#f4efe6"
|
||||||
|
d="M-4 4v8c0 3 2 4 4 4v8c2-8 4-9 4-12V4H3v7c0 2-1.5 3-3 3s-3-1-3-3V4Z"
|
||||||
|
/>
|
||||||
|
<Path stroke="#f4efe6" d="M0 4v8" />
|
||||||
|
</G>
|
||||||
|
</Defs>
|
||||||
|
<Path fill="#434b54" d="M0 0h400v580H0z" />
|
||||||
|
<Rect
|
||||||
|
width={360}
|
||||||
|
height={548}
|
||||||
|
x={20}
|
||||||
|
y={16}
|
||||||
|
fill="#f6efe3"
|
||||||
|
stroke="#122a42"
|
||||||
|
strokeWidth={1.5}
|
||||||
|
rx={16}
|
||||||
|
/>
|
||||||
|
<Path
|
||||||
|
fill="none"
|
||||||
|
stroke="#122a42"
|
||||||
|
strokeWidth={1.2}
|
||||||
|
d="M46 32h308a12 12 0 0 1 12 12v492a12 12 0 0 1-12 12H46a12 12 0 0 1-12-12V44a12 12 0 0 1 12-12Z"
|
||||||
|
/>
|
||||||
|
<Path
|
||||||
|
fill="none"
|
||||||
|
stroke="#122a42"
|
||||||
|
strokeWidth={1.2}
|
||||||
|
d="M34 46a12 12 0 0 0 12-12m320 12a12 12 0 0 1-12-12M34 534a12 12 0 0 1 12 12m320-12a12 12 0 0 0-12 12"
|
||||||
|
/>
|
||||||
|
<Path stroke="#c59b58" d="M34 135h332M34 500h332" />
|
||||||
|
<Use href="#a" transform="matrix(.85 0 0 .85 200 52)" />
|
||||||
|
<Use href="#b" transform="matrix(.8 0 0 .8 42 42)" />
|
||||||
|
<Use href="#b" transform="matrix(-.8 0 0 .8 358 42)" />
|
||||||
|
<Use href="#b" transform="matrix(.95 0 0 .95 40 185)" />
|
||||||
|
<Use href="#b" transform="matrix(-.95 0 0 .95 360 185)" />
|
||||||
|
<Use href="#a" transform="matrix(.65 0 0 .65 68 320)" />
|
||||||
|
<Use href="#a" transform="matrix(.65 0 0 .65 332 320)" />
|
||||||
|
<Use href="#b" transform="matrix(.95 0 0 .95 40 360)" />
|
||||||
|
<Use href="#b" transform="matrix(-.95 0 0 .95 360 360)" />
|
||||||
|
<G transform="translate(200 465)">
|
||||||
|
<Rect
|
||||||
|
width={18}
|
||||||
|
height={28}
|
||||||
|
x={-9}
|
||||||
|
y={-14}
|
||||||
|
fill="#122a42"
|
||||||
|
stroke="#122a42"
|
||||||
|
rx={3.5}
|
||||||
|
/>
|
||||||
|
<Rect width={14} height={20} x={-7} y={-11} fill="#fff" rx={1.5} />
|
||||||
|
<Path fill="#122a42" d="M-4.5-8.5h9v9h-9z" />
|
||||||
|
<Path fill="#fff" d="M-3-7h6v6h-6z" />
|
||||||
|
<Path fill="#122a42" d="M-1.5-5.5h3v3h-3z" />
|
||||||
|
<Circle cy={11} r={1} fill="#fff" />
|
||||||
|
</G>
|
||||||
|
<Circle cx={258} cy={537} r={4.5} fill="#a64423" />
|
||||||
|
<Path
|
||||||
|
fill="#f6efe3"
|
||||||
|
d="M259 541h-1.5v-4h-1v-1.5h1v-1c0-1 .5-1.5 2-1.5h1v1.5h-1c-.5 0-.5.3-.5.7v.3h1.5l-.3 1.5H259Z"
|
||||||
|
/>
|
||||||
|
<Rect
|
||||||
|
width={9}
|
||||||
|
height={9}
|
||||||
|
x={266}
|
||||||
|
y={532.5}
|
||||||
|
fill="none"
|
||||||
|
stroke="#a64423"
|
||||||
|
strokeWidth={1.2}
|
||||||
|
rx={2.5}
|
||||||
|
/>
|
||||||
|
<Circle cx={270.5} cy={537} r={2} fill="none" stroke="#a64423" />
|
||||||
|
<Circle cx={273} cy={534.5} r={0.5} fill="#a64423" />
|
||||||
|
<G transform="translate(95 205)">
|
||||||
|
<Path
|
||||||
|
fill="#fdfbf7"
|
||||||
|
stroke="#122a42"
|
||||||
|
strokeWidth={3}
|
||||||
|
d="M0 0h210v210H0z"
|
||||||
|
/>
|
||||||
|
<Path
|
||||||
|
fill="none"
|
||||||
|
stroke="#c59b58"
|
||||||
|
strokeWidth={1.5}
|
||||||
|
d="M4 4h202v202H4z"
|
||||||
|
/>
|
||||||
|
<Path
|
||||||
|
fill="#faf8f5"
|
||||||
|
stroke="#122a42"
|
||||||
|
strokeDasharray="4 3"
|
||||||
|
d="M12 12h186v186H12z"
|
||||||
|
/>
|
||||||
|
<Circle
|
||||||
|
cx={105}
|
||||||
|
cy={95}
|
||||||
|
r={16}
|
||||||
|
fill="#f6efe3"
|
||||||
|
stroke="#c59b58"
|
||||||
|
strokeWidth={1.2}
|
||||||
|
/>
|
||||||
|
<Use href="#a" transform="matrix(.45 0 0 .45 105 93)" />
|
||||||
|
<Text
|
||||||
|
x={105}
|
||||||
|
y={128}
|
||||||
|
fill="#122a42"
|
||||||
|
fontFamily="Inter, Arial, sans-serif"
|
||||||
|
fontSize={11}
|
||||||
|
fontWeight={800}
|
||||||
|
letterSpacing={1.5}
|
||||||
|
textAnchor="middle"
|
||||||
|
>
|
||||||
|
{"QR KOD ALANI"}
|
||||||
|
</Text>
|
||||||
|
</G>
|
||||||
|
<Text
|
||||||
|
x={172}
|
||||||
|
y={55}
|
||||||
|
fill="#122a42"
|
||||||
|
fontFamily="Inter, Arial, sans-serif"
|
||||||
|
fontSize={8.5}
|
||||||
|
fontWeight={800}
|
||||||
|
letterSpacing={1}
|
||||||
|
textAnchor="middle"
|
||||||
|
>
|
||||||
|
{"EST."}
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
x={228}
|
||||||
|
y={55}
|
||||||
|
fill="#122a42"
|
||||||
|
fontFamily="Inter, Arial, sans-serif"
|
||||||
|
fontSize={8.5}
|
||||||
|
fontWeight={800}
|
||||||
|
letterSpacing={1}
|
||||||
|
textAnchor="middle"
|
||||||
|
>
|
||||||
|
{"2018"}
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
x={200}
|
||||||
|
y={84}
|
||||||
|
fill="#a64423"
|
||||||
|
fontFamily="'Playfair Display', Georgia, 'Times New Roman', serif"
|
||||||
|
fontSize={19}
|
||||||
|
fontWeight={900}
|
||||||
|
letterSpacing={1.5}
|
||||||
|
textAnchor="middle"
|
||||||
|
>
|
||||||
|
{"THE STONEHEARTH GRILL"}
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
x={200}
|
||||||
|
y={102}
|
||||||
|
fill="#122a42"
|
||||||
|
fontFamily="Inter, Arial, sans-serif"
|
||||||
|
fontSize={8.5}
|
||||||
|
fontWeight={700}
|
||||||
|
letterSpacing={2}
|
||||||
|
textAnchor="middle"
|
||||||
|
>
|
||||||
|
{"EST. 2018"}
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
x={200}
|
||||||
|
y={118}
|
||||||
|
fill="#122a42"
|
||||||
|
fontFamily="Inter, Arial, sans-serif"
|
||||||
|
fontSize={10}
|
||||||
|
fontWeight={800}
|
||||||
|
letterSpacing={2}
|
||||||
|
textAnchor="middle"
|
||||||
|
>
|
||||||
|
{"SCAN. ORDER. ENJOY."}
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
x={200}
|
||||||
|
y={158}
|
||||||
|
fill="#122a42"
|
||||||
|
fontFamily="'Playfair Display', Georgia, 'Times New Roman', serif"
|
||||||
|
fontSize={15.5}
|
||||||
|
fontWeight={900}
|
||||||
|
letterSpacing={0.5}
|
||||||
|
textAnchor="middle"
|
||||||
|
>
|
||||||
|
{"VIEW OUR MENU & ORDER ONLINE"}
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
x={200}
|
||||||
|
y={176}
|
||||||
|
fill="#222"
|
||||||
|
fontFamily="Inter, Arial, sans-serif"
|
||||||
|
fontSize={9}
|
||||||
|
fontWeight={500}
|
||||||
|
letterSpacing={0.1}
|
||||||
|
textAnchor="middle"
|
||||||
|
>
|
||||||
|
{"Simply scan the QR code with your phone camera to access our"}
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
x={200}
|
||||||
|
y={189}
|
||||||
|
fill="#222"
|
||||||
|
fontFamily="Inter, Arial, sans-serif"
|
||||||
|
fontSize={9}
|
||||||
|
fontWeight={500}
|
||||||
|
letterSpacing={0.1}
|
||||||
|
textAnchor="middle"
|
||||||
|
>
|
||||||
|
{"digital menu, daily specials, wine list, and place your order."}
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
x={162}
|
||||||
|
y={468}
|
||||||
|
fill="#122a42"
|
||||||
|
fontFamily="Inter, Arial, sans-serif"
|
||||||
|
fontSize={11}
|
||||||
|
fontWeight={800}
|
||||||
|
letterSpacing={1}
|
||||||
|
textAnchor="end"
|
||||||
|
>
|
||||||
|
{"NO APP"}
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
x={238}
|
||||||
|
y={468}
|
||||||
|
fill="#122a42"
|
||||||
|
fontFamily="Inter, Arial, sans-serif"
|
||||||
|
fontSize={11}
|
||||||
|
fontWeight={800}
|
||||||
|
letterSpacing={1}
|
||||||
|
>
|
||||||
|
{"REQUIRED"}
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
x={200}
|
||||||
|
y={515}
|
||||||
|
fill="#122a42"
|
||||||
|
fontFamily="Inter, Arial, sans-serif"
|
||||||
|
fontSize={10.5}
|
||||||
|
fontWeight={800}
|
||||||
|
letterSpacing={1}
|
||||||
|
textAnchor="middle"
|
||||||
|
>
|
||||||
|
{"WWW.THESTONEHEARTHGRILL.COM"}
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
x={200}
|
||||||
|
y={527}
|
||||||
|
fill="#222"
|
||||||
|
fontFamily="Inter, Arial, sans-serif"
|
||||||
|
fontSize={9}
|
||||||
|
fontWeight={600}
|
||||||
|
letterSpacing={0.2}
|
||||||
|
textAnchor="middle"
|
||||||
|
>
|
||||||
|
{"FREE WIFI: StonehearthGuest (PW: Grill720)"}
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
x={195}
|
||||||
|
y={540}
|
||||||
|
fill="#222"
|
||||||
|
fontFamily="Inter, Arial, sans-serif"
|
||||||
|
fontSize={9}
|
||||||
|
fontWeight={600}
|
||||||
|
letterSpacing={0.2}
|
||||||
|
textAnchor="middle"
|
||||||
|
>
|
||||||
|
{"Follow Us @StonehearthGrill"}
|
||||||
|
</Text>
|
||||||
|
</Svg>
|
||||||
|
)
|
||||||
|
const Memo = memo(SvgComponent)
|
||||||
|
export default Memo
|
||||||
@@ -90,4 +90,19 @@ export const QR_STAND_PRESETS: Record<string, QrStandPreset> = {
|
|||||||
subText: "#0284c7",
|
subText: "#0284c7",
|
||||||
dividerColor: "rgba(0, 53, 84, 0.3)",
|
dividerColor: "rgba(0, 53, 84, 0.3)",
|
||||||
},
|
},
|
||||||
|
"qr-6": {
|
||||||
|
key: "qr-6",
|
||||||
|
name: "The Stonehearth Grill (QR-6)",
|
||||||
|
categoryName: "Özel Masa Kartı",
|
||||||
|
svgTemplateUrl: "/qr-6.svg",
|
||||||
|
aspectRatio: "400/580",
|
||||||
|
bgGradient: "radial-gradient(circle at 50% 50%, #434b54 0%, #1a2228 100%)",
|
||||||
|
plaqueColor: "#f6efe3",
|
||||||
|
borderAccent: "#c59b58",
|
||||||
|
accentText: "#a64423",
|
||||||
|
headerText: "#122a42",
|
||||||
|
subText: "#c59b58",
|
||||||
|
dividerColor: "rgba(197, 155, 88, 0.3)",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user