This commit is contained in:
@@ -35,6 +35,7 @@ type SiteSettings = {
|
|||||||
logoUrl: string
|
logoUrl: string
|
||||||
location: string
|
location: string
|
||||||
restaurantName: string
|
restaurantName: string
|
||||||
|
googleReviewUrl?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function MenuClient({ initialCategories, siteSettings }: { initialCategories: MenuCategory[], siteSettings: SiteSettings }) {
|
export default function MenuClient({ initialCategories, siteSettings }: { initialCategories: MenuCategory[], siteSettings: SiteSettings }) {
|
||||||
@@ -42,6 +43,7 @@ export default function MenuClient({ initialCategories, siteSettings }: { initia
|
|||||||
initialCategories[0]?.id || ""
|
initialCategories[0]?.id || ""
|
||||||
);
|
);
|
||||||
const [selectedItem, setSelectedItem] = useState<MenuItemType | null>(null);
|
const [selectedItem, setSelectedItem] = useState<MenuItemType | null>(null);
|
||||||
|
const [showReviewModal, setShowReviewModal] = useState<boolean>(false);
|
||||||
const sectionRefs = useRef<(HTMLElement | null)[]>([]);
|
const sectionRefs = useRef<(HTMLElement | null)[]>([]);
|
||||||
const t = useTranslations("Menu");
|
const t = useTranslations("Menu");
|
||||||
const locale = useLocale();
|
const locale = useLocale();
|
||||||
@@ -61,6 +63,19 @@ export default function MenuClient({ initialCategories, siteSettings }: { initia
|
|||||||
return () => observer.disconnect();
|
return () => observer.disconnect();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (siteSettings.googleReviewUrl) {
|
||||||
|
const hasSeenModal = sessionStorage.getItem('hasSeenReviewModal');
|
||||||
|
if (!hasSeenModal) {
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
setShowReviewModal(true);
|
||||||
|
sessionStorage.setItem('hasSeenReviewModal', 'true');
|
||||||
|
}, 1500);
|
||||||
|
return () => clearTimeout(timer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [siteSettings.googleReviewUrl]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedItem) {
|
if (selectedItem) {
|
||||||
document.body.style.overflow = "hidden";
|
document.body.style.overflow = "hidden";
|
||||||
@@ -301,6 +316,66 @@ export default function MenuClient({ initialCategories, siteSettings }: { initia
|
|||||||
</motion.div>
|
</motion.div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Google Review Modal */}
|
||||||
|
{showReviewModal && siteSettings.googleReviewUrl && (
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
animate={{ opacity: 1 }}
|
||||||
|
exit={{ opacity: 0 }}
|
||||||
|
className="fixed inset-0 z-[60] flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm"
|
||||||
|
onClick={() => setShowReviewModal(false)}
|
||||||
|
>
|
||||||
|
<motion.div
|
||||||
|
initial={{ y: 50, opacity: 0, scale: 0.95 }}
|
||||||
|
animate={{ y: 0, opacity: 1, scale: 1 }}
|
||||||
|
exit={{ y: 20, opacity: 0, scale: 0.95 }}
|
||||||
|
className="bg-white rounded-2xl overflow-hidden w-full max-w-sm shadow-xl p-6 text-center relative"
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
className="absolute top-3 right-3 text-gray-400 hover:text-gray-600 transition-colors"
|
||||||
|
onClick={() => setShowReviewModal(false)}
|
||||||
|
>
|
||||||
|
✕
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div className="w-16 h-16 bg-white rounded-full flex items-center justify-center mx-auto mb-4 shadow-sm border border-gray-100">
|
||||||
|
<svg viewBox="0 0 48 48" className="w-8 h-8">
|
||||||
|
<path fill="#EA4335" d="M24 9.5c3.54 0 6.71 1.22 9.21 3.6l6.85-6.85C35.9 2.38 30.47 0 24 0 14.62 0 6.51 5.38 2.56 13.22l7.98 6.19C12.43 13.72 17.74 9.5 24 9.5z"/>
|
||||||
|
<path fill="#4285F4" d="M46.98 24.55c0-1.57-.15-3.09-.38-4.55H24v9.02h12.94c-.58 2.96-2.26 5.48-4.78 7.18l7.73 6c4.51-4.18 7.09-10.36 7.09-17.65z"/>
|
||||||
|
<path fill="#FBBC05" d="M10.53 28.59c-.48-1.45-.76-2.99-.76-4.59s.27-3.14.76-4.59l-7.98-6.19C.92 16.46 0 20.12 0 24c0 3.88.92 7.54 2.56 10.78l7.97-6.19z"/>
|
||||||
|
<path fill="#34A853" d="M24 48c6.48 0 11.93-2.13 15.89-5.81l-7.73-6c-2.15 1.45-4.92 2.3-8.16 2.3-6.26 0-11.57-4.22-13.47-9.91l-7.98 6.19C6.51 42.62 14.62 48 24 48z"/>
|
||||||
|
<path fill="none" d="M0 0h48v48H0z"/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3 className="text-xl font-bold font-sans text-gray-900 mb-2">
|
||||||
|
Bizi Değerlendirin
|
||||||
|
</h3>
|
||||||
|
<p className="text-sm text-gray-600 mb-6 font-sans">
|
||||||
|
Deneyiminizi önemsiyoruz! Bize Google üzerinde yorum yaparak destek olabilirsiniz.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<a
|
||||||
|
href={siteSettings.googleReviewUrl}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
onClick={() => setShowReviewModal(false)}
|
||||||
|
className="block w-full py-3 px-4 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-xl transition-colors font-sans"
|
||||||
|
>
|
||||||
|
Google'da Yorum Yap
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<button
|
||||||
|
onClick={() => setShowReviewModal(false)}
|
||||||
|
className="mt-4 text-sm font-medium text-gray-400 hover:text-gray-600 font-sans"
|
||||||
|
>
|
||||||
|
Daha Sonra
|
||||||
|
</button>
|
||||||
|
</motion.div>
|
||||||
|
</motion.div>
|
||||||
|
)}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ async function getSiteSettings() {
|
|||||||
logoUrl: settings['logo_url'] || '/logo.png',
|
logoUrl: settings['logo_url'] || '/logo.png',
|
||||||
location: settings['location'] || 'Akyaka · Muğla',
|
location: settings['location'] || 'Akyaka · Muğla',
|
||||||
restaurantName: settings['restaurant_name'] || 'Moy Beach',
|
restaurantName: settings['restaurant_name'] || 'Moy Beach',
|
||||||
|
googleReviewUrl: settings['google_review_url'] || '',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,10 +9,12 @@ export default function SettingsForm({
|
|||||||
defaultRestaurantName,
|
defaultRestaurantName,
|
||||||
defaultLocation,
|
defaultLocation,
|
||||||
defaultLogoUrl,
|
defaultLogoUrl,
|
||||||
|
defaultGoogleReviewUrl,
|
||||||
}: {
|
}: {
|
||||||
defaultRestaurantName: string
|
defaultRestaurantName: string
|
||||||
defaultLocation: string
|
defaultLocation: string
|
||||||
defaultLogoUrl: string
|
defaultLogoUrl: string
|
||||||
|
defaultGoogleReviewUrl?: string
|
||||||
}) {
|
}) {
|
||||||
const [state, action, isPending] = useActionState(saveSettings, undefined)
|
const [state, action, isPending] = useActionState(saveSettings, undefined)
|
||||||
const [logoUrl, setLogoUrl] = useState(defaultLogoUrl)
|
const [logoUrl, setLogoUrl] = useState(defaultLogoUrl)
|
||||||
@@ -146,6 +148,21 @@ export default function SettingsForm({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Google Review Url */}
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||||
|
Google Yorum Linki
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="url"
|
||||||
|
name="google_review_url"
|
||||||
|
defaultValue={defaultGoogleReviewUrl}
|
||||||
|
placeholder="https://g.page/r/..."
|
||||||
|
className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none transition-colors"
|
||||||
|
/>
|
||||||
|
<p className="text-xs text-gray-500 mt-1">Eğer buraya link eklerseniz site açılışında ziyaretçilere yorum yapmaları için popup gösterilir.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={isPending || uploading}
|
disabled={isPending || uploading}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ export async function saveSettings(_prevState: unknown, formData: FormData) {
|
|||||||
const restaurant_name = formData.get('restaurant_name') as string
|
const restaurant_name = formData.get('restaurant_name') as string
|
||||||
const location = formData.get('location') as string
|
const location = formData.get('location') as string
|
||||||
const logo_url = formData.get('logo_url') as string
|
const logo_url = formData.get('logo_url') as string
|
||||||
|
const google_review_url = formData.get('google_review_url') as string
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await prisma.$transaction([
|
await prisma.$transaction([
|
||||||
@@ -25,6 +26,11 @@ export async function saveSettings(_prevState: unknown, formData: FormData) {
|
|||||||
update: { value: logo_url || '' },
|
update: { value: logo_url || '' },
|
||||||
create: { key: 'logo_url', value: logo_url || '' },
|
create: { key: 'logo_url', value: logo_url || '' },
|
||||||
}),
|
}),
|
||||||
|
prisma.settings.upsert({
|
||||||
|
where: { key: 'google_review_url' },
|
||||||
|
update: { value: google_review_url || '' },
|
||||||
|
create: { key: 'google_review_url', value: google_review_url || '' },
|
||||||
|
}),
|
||||||
])
|
])
|
||||||
|
|
||||||
revalidatePath('/', 'layout')
|
revalidatePath('/', 'layout')
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ export default async function SettingsPage() {
|
|||||||
const restaurantName = settings['restaurant_name'] || 'Moy Beach'
|
const restaurantName = settings['restaurant_name'] || 'Moy Beach'
|
||||||
const location = settings['location'] || 'Akyaka · Muğla'
|
const location = settings['location'] || 'Akyaka · Muğla'
|
||||||
const logoUrl = settings['logo_url'] || ''
|
const logoUrl = settings['logo_url'] || ''
|
||||||
|
const googleReviewUrl = settings['google_review_url'] || ''
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
@@ -25,6 +26,7 @@ export default async function SettingsPage() {
|
|||||||
defaultRestaurantName={restaurantName}
|
defaultRestaurantName={restaurantName}
|
||||||
defaultLocation={location}
|
defaultLocation={location}
|
||||||
defaultLogoUrl={logoUrl}
|
defaultLogoUrl={logoUrl}
|
||||||
|
defaultGoogleReviewUrl={googleReviewUrl}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user