Autosave: 20260304-133057

This commit is contained in:
Flatlogic Bot 2026-03-04 13:30:57 +00:00
parent a23dcbb154
commit 0495927787
5 changed files with 30 additions and 60 deletions

View File

@ -1,5 +1,4 @@
VITE_SUPABASE_URL=https://ofqojaxiopqxahfvxpmx.supabase.co
VITE_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Im9mcW9qYXhpb3BxeGFoZnZ4cG14Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzIyODExMjAsImV4cCI6MjA4Nzg1NzEyMH0.CVyjWPp9ldCd5qxA4TbViD5MJ0axbEWfGr-1n1pPjn0
VITE_SUPABASE_URL=https://bhaumxerateojqvleoyw.supabase.co
VITE_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImJoYXVteGVyYXRlb2pxdmxlb3l3Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjczNTQ4OTksImV4cCI6MjA4MjkzMDg5OX0.uyF3i17AaNd6CN5yWrGMR4vFsJ-boPrfKZYByXKBqUE
VITE_GOOGLE_MAPS_API_KEY=AIzaSyBbXWk7VhZfzn9txrAr9N-faAPuKy_LnKw
VITE_APP_ID=app-9xzmfic2e4g1
VITE_FORM_ID=form-9xzmfic2e4g1
OPENAI_API_KEY=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

View File

@ -77,19 +77,8 @@ export function TripMap({ itinerary, activePlaceId, onMarkerClick, onAddPlace }:
const fetchPlaceDetail = useCallback(async (poi: SelectedPOI) => {
setDetailLoading(true);
setPlaceDetail(null);
setActiveTab('about');
try {
const data = await api.getPlaceDetails({
place_id: poi.place_id,
name: poi.name,
category: poi.category,
});
setPlaceDetail(data);
} catch (e) {
console.error('Place detail fetch error:', e);
} finally {
setDetailLoading(false);
}
setActiveTab("about");
setDetailLoading(false);
}, []);
// ── Handle add ────────────────────────────────────────────────────────────
@ -504,14 +493,14 @@ export function TripMap({ itinerary, activePlaceId, onMarkerClick, onAddPlace }:
)}
{/* Çalışma saatleri */}
{placeDetail.opening_hours?.length > 0 && (
{placeDetail.opening_hours && placeDetail.opening_hours.length > 0 && (
<div className="space-y-2">
<h4 className="text-[11px] font-black text-gray-900 uppercase tracking-widest flex items-center gap-1.5">
<Clock className="h-3.5 w-3.5 text-blue-500" />
Çalışma Saatleri
</h4>
<div className="space-y-1">
{placeDetail.opening_hours.map((h, i) => (
{placeDetail.opening_hours?.map((h, i) => (
<p key={i} className="text-[11px] text-gray-500">{h}</p>
))}
</div>

View File

@ -20,8 +20,8 @@ interface AuthContextType {
user: User | null;
profile: Profile | null;
loading: boolean;
signInWithUsername: (username: string, password: string) => Promise<{ error: Error | null }>;
signUpWithUsername: (username: string, password: string) => Promise<{ error: Error | null }>;
signIn: (email: string, password: string) => Promise<{ error: Error | null }>;
signUp: (email: string, password: string) => Promise<{ error: Error | null }>;
signOut: () => Promise<void>;
refreshProfile: () => Promise<void>;
}
@ -51,7 +51,7 @@ export function AuthProvider({ children }: { children: ReactNode }) {
}
setLoading(false);
});
// In this function, do NOT use any await calls. Use `.then()` instead to avoid deadlocks.
const { data: { subscription } } = supabase.auth.onAuthStateChange((_event, session) => {
setUser(session?.user ?? null);
if (session?.user) {
@ -64,9 +64,8 @@ export function AuthProvider({ children }: { children: ReactNode }) {
return () => subscription.unsubscribe();
}, []);
const signInWithUsername = async (username: string, password: string) => {
const signIn = async (email: string, password: string) => {
try {
const email = `${username}@miaoda.com`;
const { error } = await supabase.auth.signInWithPassword({
email,
password,
@ -79,9 +78,8 @@ export function AuthProvider({ children }: { children: ReactNode }) {
}
};
const signUpWithUsername = async (username: string, password: string) => {
const signUp = async (email: string, password: string) => {
try {
const email = `${username}@miaoda.com`;
const { error } = await supabase.auth.signUp({
email,
password,
@ -101,7 +99,7 @@ export function AuthProvider({ children }: { children: ReactNode }) {
};
return (
<AuthContext.Provider value={{ user, profile, loading, signInWithUsername, signUpWithUsername, signOut, refreshProfile }}>
<AuthContext.Provider value={{ user, profile, loading, signIn, signUp, signOut, refreshProfile }}>
{children}
</AuthContext.Provider>
);
@ -113,4 +111,4 @@ export function useAuth() {
throw new Error('useAuth must be used within an AuthProvider');
}
return context;
}
}

View File

@ -120,18 +120,6 @@ const api = {
return data;
},
async getPlaceDetails(params: {
place_id: string;
name?: string;
category?: string;
}) {
const { data, error } = await supabase.functions.invoke('get-place-details', {
body: params,
});
if (error) throw error;
return data;
},
getPhotoUrl(photoReference: string) {
const { data } = supabase.storage.from('dummy').getPublicUrl('dummy'); // Just to get the base URL
const baseUrl = data.publicUrl.split('/storage/v1')[0];

View File

@ -11,12 +11,12 @@ import { motion } from 'framer-motion';
export default function LoginPage() {
const [isLogin, setIsLogin] = useState(true);
const [username, setUsername] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [showPassword, setShowPassword] = useState(false);
const [rememberMe, setRememberMe] = useState(false);
const [loading, setLoading] = useState(false);
const { signInWithUsername, signUpWithUsername, user } = useAuth();
const { signIn, signUp, user } = useAuth();
const navigate = useNavigate();
const location = useLocation();
const from = location.state?.from || '/explore';
@ -27,12 +27,7 @@ export default function LoginPage() {
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!username || !password) return;
if (!/^[a-z0-9_]+$/.test(username)) {
toast.error('Kullanıcı adı sadece harf, rakam ve alt çizgi içerebilir');
return;
}
if (!email || !password) return;
if (password.length < 6) {
toast.error('Şifre en az 6 karakter olmalıdır');
@ -42,25 +37,25 @@ export default function LoginPage() {
setLoading(true);
try {
if (isLogin) {
const { error } = await signInWithUsername(username, password);
const { error } = await signIn(email, password);
if (error) {
if (error.message.includes('Invalid login credentials')) {
throw new Error('Kullanıcı adı veya şifre hatalı');
throw new Error('E-posta veya şifre hatalı');
}
throw error;
}
toast.success(`Hoşgeldin, ${username}!`);
toast.success(`Hoşgeldin!`);
navigate(from, { replace: true });
} else {
const { error } = await signUpWithUsername(username, password);
const { error } = await signUp(email, password);
if (error) {
if (error.message.includes('already registered')) {
throw new Error('Bu kullanıcı adı zaten kullanılıyor');
throw new Error('Bu e-posta zaten kullanılıyor');
}
throw error;
}
toast.success('Hesap oluşturuldu! Giriş yapılıyor...');
const { error: signInError } = await signInWithUsername(username, password);
const { error: signInError } = await signIn(email, password);
if (!signInError) {
navigate(from, { replace: true });
}
@ -141,13 +136,14 @@ export default function LoginPage() {
<form onSubmit={handleSubmit} className="space-y-6">
<div className="space-y-5">
<div className="space-y-2.5">
<Label htmlFor="username" className="text-[10px] font-black uppercase tracking-widest text-primary">Kullanıcı Kimliği</Label>
<Label htmlFor="email" className="text-[10px] font-black uppercase tracking-widest text-primary">E-posta Adresi</Label>
<Input
id="username"
placeholder="kullanici_adi"
id="email"
type="email"
placeholder="eposta@adresiniz.com"
required
value={username}
onChange={e => setUsername(e.target.value.toLowerCase().replace(/[^a-z0-9_]/g, ''))}
value={email}
onChange={e => setEmail(e.target.value)}
className="h-14 rounded-xl border-2 border-gray-100 bg-gray-50/50 focus:border-primary px-5 text-base font-bold transition-luxury"
/>
</div>
@ -234,4 +230,4 @@ export default function LoginPage() {
</div>
</div>
);
}
}