mojmajstor/app/(auth)/login.tsx
2026-06-04 20:37:09 +02:00

136 lines
4.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useState } from "react";
import {
View,
Text,
KeyboardAvoidingView,
Platform,
ScrollView,
Alert,
} from "react-native";
import { useRouter } from "expo-router";
import { useMutation, useAction } from "convex/react";
import { api } from "../../convex/_generated/api";
import { Input } from "../../components/ui/input";
import { Button } from "../../components/ui/button";
import { useTheme } from "../../components/theme";
import { useAuth } from "../_layout";
export default function LoginScreen() {
const theme = useTheme();
const router = useRouter();
const { login } = useAuth();
const loginMutation = useMutation(api.auth.login);
const hashPassword = useAction(api.auth.hashPassword);
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [loading, setLoading] = useState(false);
async function handleLogin() {
if (!email || !password) {
Alert.alert("Грешка", "Пополнете ги сите полиња");
return;
}
setLoading(true);
try {
const passwordHash = await hashPassword({ password });
const result = await loginMutation({ email, passwordHash });
await login(result.token, result.user._id);
router.replace("/(tabs)/(home)");
} catch (e: any) {
Alert.alert("Најава неуспешна", "Погрешна е-пошта или лозинка");
} finally {
setLoading(false);
}
}
return (
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : "height"}
style={{ flex: 1, backgroundColor: theme.colors.background }}
>
<ScrollView
contentContainerStyle={{ flexGrow: 1, justifyContent: "center", padding: theme.spacing.lg }}
keyboardShouldPersistTaps="handled"
>
<View
style={{
backgroundColor: theme.colors.card,
borderRadius: theme.radius.xl,
padding: theme.spacing.lg,
borderWidth: 1,
borderColor: theme.colors.borderLight,
...theme.shadows.md,
gap: theme.spacing.md,
}}
>
<View style={{ alignItems: "center", marginBottom: theme.spacing.sm }}>
<View
style={{
width: 72,
height: 72,
borderRadius: 36,
backgroundColor: theme.colors.primaryLight,
alignItems: "center",
justifyContent: "center",
marginBottom: theme.spacing.md,
}}
>
<Text style={{ fontSize: 36 }}>🔧</Text>
</View>
<Text style={{ ...theme.typography.h1, color: theme.colors.text }}>
МојМајстор
</Text>
<Text selectable style={{ ...theme.typography.body, color: theme.colors.textSecondary, marginTop: theme.spacing.xs }}>
Најдете мајстор во вашата близина
</Text>
</View>
<Input
placeholder="Е-пошта"
value={email}
onChangeText={setEmail}
autoCapitalize="none"
keyboardType="email-address"
accessibilityLabel="Е-пошта"
label="Е-пошта"
/>
<Input
placeholder="Лозинка"
value={password}
onChangeText={setPassword}
secureTextEntry
accessibilityLabel="Лозинка"
label="Лозинка"
/>
<Button
loading={loading}
onPress={handleLogin}
accessibilityLabel="Најави се"
fullWidth
size="lg"
>
Најави се
</Button>
<View style={{ flexDirection: "row", justifyContent: "center", marginTop: theme.spacing.sm }}>
<Text style={{ color: theme.colors.textSecondary }}>Немате профил? </Text>
<Text
accessible
accessibilityLabel="Регистрирајте се"
accessibilityRole="link"
style={{ color: theme.colors.primary, fontWeight: "600" }}
onPress={() => router.push("/(auth)/register")}
>
Регистрирајте се
</Text>
</View>
</View>
</ScrollView>
</KeyboardAvoidingView>
);
}