From f89537473a5237b97f503ecec5dd442c9950712c Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Fri, 6 Mar 2026 15:19:00 +0000 Subject: [PATCH] Edit app-9xzmfic2e4g1/src/pages/GuidesPage.tsx via Editor --- app-9xzmfic2e4g1/src/pages/GuidesPage.tsx | 241 ++++++++++++++++++++++ 1 file changed, 241 insertions(+) create mode 100644 app-9xzmfic2e4g1/src/pages/GuidesPage.tsx diff --git a/app-9xzmfic2e4g1/src/pages/GuidesPage.tsx b/app-9xzmfic2e4g1/src/pages/GuidesPage.tsx new file mode 100644 index 0000000..56ee01d --- /dev/null +++ b/app-9xzmfic2e4g1/src/pages/GuidesPage.tsx @@ -0,0 +1,241 @@ +import { useEffect, useState } from 'react'; +import { Link, useNavigate } from 'react-router-dom'; +import api from '@/db/api'; +import { Button } from '@/components/ui/button'; +import { Badge } from '@/components/ui/badge'; +import { motion } from 'framer-motion'; +import { Heart, Eye, MapPin, Calendar, ArrowRight, Compass, Loader2 } from 'lucide-react'; +import { format } from 'date-fns'; +import { tr } from 'date-fns/locale'; +import { useAuth } from '@/contexts/AuthContext'; +import { cn } from '@/lib/utils'; + +export default function GuidesPage() { + const [guides, setGuides] = useState([]); + const [loading, setLoading] = useState(true); + const [myLikes, setMyLikes] = useState>(new Set()); + const { user } = useAuth(); + const navigate = useNavigate(); + + useEffect(() => { + load(); + }, []); + + const load = async () => { + try { + const [data, likes] = await Promise.all([ + api.getPublicGuides(50), + user ? api.getMyLikes() : Promise.resolve([]), + ]); + setGuides(data); + setMyLikes(new Set(likes)); + } catch { + // silent + } finally { + setLoading(false); + } + }; + + const handleLike = async (e: React.MouseEvent, guideId: string) => { + e.preventDefault(); + if (!user) { navigate('/login'); return; } + const wasLiked = myLikes.has(guideId); + // optimistic + setMyLikes(prev => { + const next = new Set(prev); + wasLiked ? next.delete(guideId) : next.add(guideId); + return next; + }); + setGuides(prev => prev.map(g => g.id === guideId + ? { ...g, likes_count: g.likes_count + (wasLiked ? -1 : 1) } + : g + )); + try { + await api.toggleLike(guideId); + } catch { + // revert + setMyLikes(prev => { + const next = new Set(prev); + wasLiked ? next.add(guideId) : next.delete(guideId); + return next; + }); + } + }; + + const getGuidePhoto = (guide: any) => { + const first = guide.itinerary?.days?.[0]?.items?.[0]; + if (first?.photo_reference) { + return first.photo_reference.startsWith('http') + ? first.photo_reference + : api.getPhotoUrl(first.photo_reference); + } + return 'https://images.unsplash.com/photo-1541167760496-1628856ab772?auto=format&fit=crop&q=80&w=800'; + }; + + const getDayCount = (guide: any) => guide.itinerary?.days?.length || 0; + const getPlaceCount = (guide: any) => + (guide.itinerary?.days || []).reduce((s: number, d: any) => s + (d.items?.length || 0), 0); + + return ( +
+ + {/* Hero */} +
+
+ +
+
+
+ +
+ + Topluluk Rehberleri +
+

+ REHBERLERİM +

+

+ Gerçek gezginlerin oluşturduğu Kapadokya rotaları. Beğen, kopyala, yola çık. +

+
+
+
+ + {/* Content */} +
+ {loading ? ( +
+ +

Rehberler yükleniyor...

+
+ ) : guides.length === 0 ? ( +
+
+ +
+
+

Henüz rehber yok

+

İlk rehberi siz oluşturun.

+
+ +
+ ) : ( + <> +
+

{guides.length} rehber

+
+ +
+ {guides.map((guide, idx) => ( + + +
+ + {/* Cover image */} +
+ {guide.title} { + (e.target as HTMLImageElement).src = 'https://images.unsplash.com/photo-1541167760496-1628856ab772?w=800&q=80'; + }} + /> +
+ + {/* Stats overlay */} +
+ + {getDayCount(guide)} GÜN + + + {getPlaceCount(guide)} DURAK + +
+ + {/* Like button */} + + + {/* Title */} +
+

+ {guide.title} +

+
+
+ + {/* Body */} +
+ {/* Author intro */} + {guide.guide_intro && ( +

+ "{guide.guide_intro}" +

+ )} + + {/* Meta */} +
+ + + {guide.destination || 'Kapadokya'} + + {guide.start_date && ( + + + {format(new Date(guide.start_date), 'd MMM yyyy', { locale: tr })} + + )} +
+ + {/* Footer */} +
+
+ + + {guide.likes_count || 0} + + + + {guide.views_count || 0} + + {guide.profiles?.username && ( + @{guide.profiles.username} + )} +
+ + İncele + +
+
+
+ + + ))} +
+ + )} +
+
+ ); +} \ No newline at end of file