React Native Expo app — full mobile client

- Expo SDK 54, expo-router, NativeWind
- 7 screens: login, tasks, calendar, goals, chat, settings, tabs
- API client (api.hasdo.info), SecureStore auth, AuthContext
- Tab navigation: Ukoly, Kalendar, Cile, Chat, Nastaveni
- Pull-to-refresh, FAB, group colors, priority dots
- Calendar grid with task dots
- AI chat with keyboard avoiding
- Web export verified (780 modules, 1.5MB bundle)
- Bundle ID: info.hasdo.taskteam

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-29 15:09:35 +00:00
parent 545cf245f0
commit db81100b5b
18 changed files with 2796 additions and 58 deletions

44
mobile/lib/useAuth.ts Normal file
View File

@@ -0,0 +1,44 @@
import { useState, useEffect, useCallback } from 'react';
import { getToken, setToken, removeToken, getUser, setUser, removeUser } from './auth';
import * as api from './api';
export function useAuth() {
const [token, setTokenState] = useState<string | null>(null);
const [user, setUserState] = useState<any>(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
(async () => {
const t = await getToken();
const u = await getUser();
setTokenState(t);
setUserState(u);
setLoading(false);
})();
}, []);
const loginFn = useCallback(async (email: string, password: string) => {
const res = await api.login({ email, password });
await setToken(res.data.token);
await setUser(res.data.user);
setTokenState(res.data.token);
setUserState(res.data.user);
}, []);
const registerFn = useCallback(async (email: string, name: string, password: string) => {
const res = await api.register({ email, name, password });
await setToken(res.data.token);
await setUser(res.data.user);
setTokenState(res.data.token);
setUserState(res.data.user);
}, []);
const logout = useCallback(async () => {
await removeToken();
await removeUser();
setTokenState(null);
setUserState(null);
}, []);
return { token, user, loading, login: loginFn, register: registerFn, logout };
}