Adjusts
This commit is contained in:
parent
63c9f720ad
commit
227b492bc3
10 changed files with 115 additions and 24 deletions
9
.claude/settings.json
Normal file
9
.claude/settings.json
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(xargs cat *)",
|
||||
"Bash(python3 -c \"import json,sys; d=json.load\\(sys.stdin\\); print\\(json.dumps\\(d.get\\('exports', {}\\), indent=2\\)\\)\")",
|
||||
"Bash(python3 -c \"import json,sys; d=json.load\\(sys.stdin\\); print\\(json.dumps\\({k: v for k, v in d.items\\(\\) if k not in ['dependencies', 'devDependencies', 'peerDependencies']}, indent=2\\)\\)\")"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@ import { Response } from 'express';
|
|||
import { AuthRequest } from '../middlewares/auth.middleware.js';
|
||||
import * as usersService from '../services/users.service.js';
|
||||
|
||||
export async function getMe(req: AuthRequest, res: Response) {
|
||||
export async function get(req: AuthRequest, res: Response): Promise<void> {
|
||||
try {
|
||||
const user = await usersService.getUser(req.userId!);
|
||||
res.json(user);
|
||||
|
|
@ -11,7 +11,7 @@ export async function getMe(req: AuthRequest, res: Response) {
|
|||
}
|
||||
}
|
||||
|
||||
export async function updateMe(req: AuthRequest, res: Response) {
|
||||
export async function update(req: AuthRequest, res: Response): Promise<void> {
|
||||
const parsed = usersService.updateUserSchema.safeParse(req.body);
|
||||
if (!parsed.success) {
|
||||
res.status(400).json({ error: parsed.error.flatten() });
|
||||
|
|
@ -26,7 +26,8 @@ export async function updateMe(req: AuthRequest, res: Response) {
|
|||
}
|
||||
}
|
||||
|
||||
export async function deleteMe(req: AuthRequest, res: Response) {
|
||||
export async function remove(req: AuthRequest, res: Response): Promise<void> {
|
||||
|
||||
try {
|
||||
await usersService.deleteUser(req.userId!);
|
||||
res.status(204).send();
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ const router = Router();
|
|||
|
||||
router.use(authenticate);
|
||||
|
||||
router.get('/me', usersController.getMe);
|
||||
router.put('/me', usersController.updateMe);
|
||||
router.delete('/me', usersController.deleteMe);
|
||||
router.get('/me', usersController.get);
|
||||
router.put('/me', usersController.update);
|
||||
router.delete('/me', usersController.remove);
|
||||
|
||||
export default router;
|
||||
1
mobile/package-lock.json
generated
1
mobile/package-lock.json
generated
|
|
@ -30,7 +30,6 @@
|
|||
"react-native-worklets": "0.5.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "~19.1.0",
|
||||
"react-test-renderer": "19.1.0",
|
||||
"typescript": "~5.9.2"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@
|
|||
"react-native-worklets": "0.5.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "~19.1.0",
|
||||
"react-test-renderer": "19.1.0",
|
||||
"typescript": "~5.9.2"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -14,19 +14,29 @@ import {
|
|||
import { Button } from "@/components/Button";
|
||||
import { Input } from "@/components/Input";
|
||||
import { Link } from "expo-router";
|
||||
import { api, setAuthToken } from "@/server/api";
|
||||
|
||||
// Página de login
|
||||
export default function IndexPage() {
|
||||
const [email, setEmail] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
function handleSignIn() {
|
||||
async function handleSignIn() {
|
||||
if (!email.trim() || !password.trim()) {
|
||||
Alert.alert("Entrar", "Por favor, preencha todos os campos.");
|
||||
return;
|
||||
}
|
||||
|
||||
Alert.alert("Bem-vindo", `Acessando com o e-mail ${email}`);
|
||||
try {
|
||||
setLoading(true);
|
||||
const { data } = await api.post("/auth/login", { email, password });
|
||||
setAuthToken(data.accessToken);
|
||||
} catch (err: any) {
|
||||
const message = err.response?.data?.error ?? "Erro ao fazer login.";
|
||||
Alert.alert("Erro", message);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
@ -54,6 +64,7 @@ export default function IndexPage() {
|
|||
<Input
|
||||
placeholder="E-mail"
|
||||
keyboardType="email-address"
|
||||
autoCapitalize="none"
|
||||
onChangeText={setEmail}
|
||||
/>
|
||||
|
||||
|
|
@ -63,7 +74,11 @@ export default function IndexPage() {
|
|||
onChangeText={setPassword}
|
||||
/>
|
||||
|
||||
<Button label="Entrar" onPress={handleSignIn} />
|
||||
<Button
|
||||
label={loading ? "Entrando..." : "Entrar"}
|
||||
onPress={handleSignIn}
|
||||
disabled={loading}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<Text style={styles.footerText}>
|
||||
|
|
@ -93,7 +108,7 @@ const styles = StyleSheet.create({
|
|||
title: {
|
||||
marginTop: 62,
|
||||
fontSize: 32,
|
||||
fontWeight: 900,
|
||||
fontWeight: "900",
|
||||
color: "#e7e7e7",
|
||||
},
|
||||
subtitle: {
|
||||
|
|
@ -111,6 +126,6 @@ const styles = StyleSheet.create({
|
|||
},
|
||||
footerLink: {
|
||||
color: "#007AFF",
|
||||
fontWeight: 700,
|
||||
fontWeight: "700",
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
import { useState } from "react";
|
||||
|
||||
import {
|
||||
Alert,
|
||||
Image,
|
||||
KeyboardAvoidingView,
|
||||
Platform,
|
||||
|
|
@ -10,14 +13,46 @@ import {
|
|||
|
||||
import { Button } from "@/components/Button";
|
||||
import { Input } from "@/components/Input";
|
||||
import { Link } from "expo-router";
|
||||
import { Link, useRouter } from "expo-router";
|
||||
import { api } from "@/server/api";
|
||||
|
||||
// Página de cadastro
|
||||
export default function Signup() {
|
||||
const router = useRouter();
|
||||
const [name, setName] = useState("");
|
||||
const [email, setEmail] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [confirmPassword, setConfirmPassword] = useState("");
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
async function handleSignUp() {
|
||||
if (!name.trim() || !email.trim() || !password.trim() || !confirmPassword.trim()) {
|
||||
Alert.alert("Cadastrar", "Por favor, preencha todos os campos.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (password !== confirmPassword) {
|
||||
Alert.alert("Cadastrar", "As senhas não coincidem.");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
setLoading(true);
|
||||
await api.post("/auth/register", { name, email, password });
|
||||
Alert.alert("Sucesso", "Conta criada com sucesso!", [
|
||||
{ text: "OK", onPress: () => router.replace("/") },
|
||||
]);
|
||||
} catch (err: any) {
|
||||
const message = err.response?.data?.error ?? "Erro ao criar conta.";
|
||||
Alert.alert("Erro", message);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<KeyboardAvoidingView
|
||||
style={{ flex: 1 }}
|
||||
behavior={Platform.select({ ios: "padding", android: "height" })}
|
||||
behavior={Platform.OS === "ios" ? "padding" : "height"}
|
||||
>
|
||||
<ScrollView
|
||||
contentContainerStyle={{ flexGrow: 1 }}
|
||||
|
|
@ -34,11 +69,24 @@ export default function Signup() {
|
|||
<Text style={styles.subtitle}>Crie sua conta para acessar.</Text>
|
||||
|
||||
<View style={styles.form}>
|
||||
<Input placeholder="Nome" />
|
||||
<Input placeholder="E-mail" keyboardType="email-address" />
|
||||
<Input placeholder="Senha" secureTextEntry />
|
||||
<Input placeholder="Confirmar Senha" secureTextEntry />
|
||||
<Button label="Cadastrar" />
|
||||
<Input placeholder="Nome" onChangeText={setName} />
|
||||
<Input
|
||||
placeholder="E-mail"
|
||||
keyboardType="email-address"
|
||||
autoCapitalize="none"
|
||||
onChangeText={setEmail}
|
||||
/>
|
||||
<Input placeholder="Senha" secureTextEntry onChangeText={setPassword} />
|
||||
<Input
|
||||
placeholder="Confirmar Senha"
|
||||
secureTextEntry
|
||||
onChangeText={setConfirmPassword}
|
||||
/>
|
||||
<Button
|
||||
label={loading ? "Cadastrando..." : "Cadastrar"}
|
||||
onPress={handleSignUp}
|
||||
disabled={loading}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<Text style={styles.footerText}>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
import axios from 'axios';
|
||||
import { Platform } from 'react-native';
|
||||
|
||||
const BASE_URL = Platform.OS === 'android'
|
||||
? 'http://10.0.2.2:4000'
|
||||
: 'http://localhost:4000';
|
||||
|
||||
export const api = axios.create({
|
||||
baseURL: BASE_URL,
|
||||
});
|
||||
|
||||
export function setAuthToken(token: string | null) {
|
||||
if (token) {
|
||||
api.defaults.headers.common.Authorization = `Bearer ${token}`;
|
||||
} else {
|
||||
delete api.defaults.headers.common.Authorization;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,8 +2,10 @@
|
|||
"extends": "expo/tsconfig.base",
|
||||
"compilerOptions": {
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
"@/*": ["./src/*"],
|
||||
"expo-router/src/*": ["./node_modules/expo-router/build/*"]
|
||||
}
|
||||
},
|
||||
"include": ["**/*.ts", "**/*.tsx", ".expo/types/**/*.ts", "expo-env.d.ts"]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue