Autosave: 20260304-133057
This commit is contained in:
parent
a23dcbb154
commit
0495927787
@ -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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
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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];
|
||||
|
||||
@ -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>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user