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 { AuthRequest } from '../middlewares/auth.middleware.js';
|
||||||
import * as usersService from '../services/users.service.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 {
|
try {
|
||||||
const user = await usersService.getUser(req.userId!);
|
const user = await usersService.getUser(req.userId!);
|
||||||
res.json(user);
|
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);
|
const parsed = usersService.updateUserSchema.safeParse(req.body);
|
||||||
if (!parsed.success) {
|
if (!parsed.success) {
|
||||||
res.status(400).json({ error: parsed.error.flatten() });
|
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 {
|
try {
|
||||||
await usersService.deleteUser(req.userId!);
|
await usersService.deleteUser(req.userId!);
|
||||||
res.status(204).send();
|
res.status(204).send();
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ const router = Router();
|
||||||
|
|
||||||
router.use(authenticate);
|
router.use(authenticate);
|
||||||
|
|
||||||
router.get('/me', usersController.getMe);
|
router.get('/me', usersController.get);
|
||||||
router.put('/me', usersController.updateMe);
|
router.put('/me', usersController.update);
|
||||||
router.delete('/me', usersController.deleteMe);
|
router.delete('/me', usersController.remove);
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|
@ -14,4 +14,4 @@ app.use('/users', usersRoutes);
|
||||||
|
|
||||||
app.listen(port, '0.0.0.0', () => {
|
app.listen(port, '0.0.0.0', () => {
|
||||||
console.log(`Server is running on port ${port}`);
|
console.log(`Server is running on port ${port}`);
|
||||||
});
|
});
|
||||||
1
mobile/package-lock.json
generated
1
mobile/package-lock.json
generated
|
|
@ -30,7 +30,6 @@
|
||||||
"react-native-worklets": "0.5.1"
|
"react-native-worklets": "0.5.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/react": "~19.1.0",
|
|
||||||
"react-test-renderer": "19.1.0",
|
"react-test-renderer": "19.1.0",
|
||||||
"typescript": "~5.9.2"
|
"typescript": "~5.9.2"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@
|
||||||
"react-native-worklets": "0.5.1"
|
"react-native-worklets": "0.5.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/react": "~19.1.0",
|
|
||||||
"react-test-renderer": "19.1.0",
|
"react-test-renderer": "19.1.0",
|
||||||
"typescript": "~5.9.2"
|
"typescript": "~5.9.2"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -14,19 +14,29 @@ import {
|
||||||
import { Button } from "@/components/Button";
|
import { Button } from "@/components/Button";
|
||||||
import { Input } from "@/components/Input";
|
import { Input } from "@/components/Input";
|
||||||
import { Link } from "expo-router";
|
import { Link } from "expo-router";
|
||||||
|
import { api, setAuthToken } from "@/server/api";
|
||||||
|
|
||||||
// Página de login
|
|
||||||
export default function IndexPage() {
|
export default function IndexPage() {
|
||||||
const [email, setEmail] = useState("");
|
const [email, setEmail] = useState("");
|
||||||
const [password, setPassword] = useState("");
|
const [password, setPassword] = useState("");
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
function handleSignIn() {
|
async function handleSignIn() {
|
||||||
if (!email.trim() || !password.trim()) {
|
if (!email.trim() || !password.trim()) {
|
||||||
Alert.alert("Entrar", "Por favor, preencha todos os campos.");
|
Alert.alert("Entrar", "Por favor, preencha todos os campos.");
|
||||||
return;
|
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 (
|
return (
|
||||||
|
|
@ -54,6 +64,7 @@ export default function IndexPage() {
|
||||||
<Input
|
<Input
|
||||||
placeholder="E-mail"
|
placeholder="E-mail"
|
||||||
keyboardType="email-address"
|
keyboardType="email-address"
|
||||||
|
autoCapitalize="none"
|
||||||
onChangeText={setEmail}
|
onChangeText={setEmail}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
@ -63,7 +74,11 @@ export default function IndexPage() {
|
||||||
onChangeText={setPassword}
|
onChangeText={setPassword}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Button label="Entrar" onPress={handleSignIn} />
|
<Button
|
||||||
|
label={loading ? "Entrando..." : "Entrar"}
|
||||||
|
onPress={handleSignIn}
|
||||||
|
disabled={loading}
|
||||||
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<Text style={styles.footerText}>
|
<Text style={styles.footerText}>
|
||||||
|
|
@ -93,7 +108,7 @@ const styles = StyleSheet.create({
|
||||||
title: {
|
title: {
|
||||||
marginTop: 62,
|
marginTop: 62,
|
||||||
fontSize: 32,
|
fontSize: 32,
|
||||||
fontWeight: 900,
|
fontWeight: "900",
|
||||||
color: "#e7e7e7",
|
color: "#e7e7e7",
|
||||||
},
|
},
|
||||||
subtitle: {
|
subtitle: {
|
||||||
|
|
@ -111,6 +126,6 @@ const styles = StyleSheet.create({
|
||||||
},
|
},
|
||||||
footerLink: {
|
footerLink: {
|
||||||
color: "#007AFF",
|
color: "#007AFF",
|
||||||
fontWeight: 700,
|
fontWeight: "700",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
Alert,
|
||||||
Image,
|
Image,
|
||||||
KeyboardAvoidingView,
|
KeyboardAvoidingView,
|
||||||
Platform,
|
Platform,
|
||||||
|
|
@ -10,14 +13,46 @@ import {
|
||||||
|
|
||||||
import { Button } from "@/components/Button";
|
import { Button } from "@/components/Button";
|
||||||
import { Input } from "@/components/Input";
|
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() {
|
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 (
|
return (
|
||||||
<KeyboardAvoidingView
|
<KeyboardAvoidingView
|
||||||
style={{ flex: 1 }}
|
style={{ flex: 1 }}
|
||||||
behavior={Platform.select({ ios: "padding", android: "height" })}
|
behavior={Platform.OS === "ios" ? "padding" : "height"}
|
||||||
>
|
>
|
||||||
<ScrollView
|
<ScrollView
|
||||||
contentContainerStyle={{ flexGrow: 1 }}
|
contentContainerStyle={{ flexGrow: 1 }}
|
||||||
|
|
@ -34,11 +69,24 @@ export default function Signup() {
|
||||||
<Text style={styles.subtitle}>Crie sua conta para acessar.</Text>
|
<Text style={styles.subtitle}>Crie sua conta para acessar.</Text>
|
||||||
|
|
||||||
<View style={styles.form}>
|
<View style={styles.form}>
|
||||||
<Input placeholder="Nome" />
|
<Input placeholder="Nome" onChangeText={setName} />
|
||||||
<Input placeholder="E-mail" keyboardType="email-address" />
|
<Input
|
||||||
<Input placeholder="Senha" secureTextEntry />
|
placeholder="E-mail"
|
||||||
<Input placeholder="Confirmar Senha" secureTextEntry />
|
keyboardType="email-address"
|
||||||
<Button label="Cadastrar" />
|
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>
|
</View>
|
||||||
|
|
||||||
<Text style={styles.footerText}>
|
<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",
|
"extends": "expo/tsconfig.base",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"strict": true,
|
"strict": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": ["./src/*"]
|
"@/*": ["./src/*"],
|
||||||
|
"expo-router/src/*": ["./node_modules/expo-router/build/*"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"include": ["**/*.ts", "**/*.tsx", ".expo/types/**/*.ts", "expo-env.d.ts"]
|
"include": ["**/*.ts", "**/*.tsx", ".expo/types/**/*.ts", "expo-env.d.ts"]
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue