SMPT, SMS, Rejestracja + GUS

This commit is contained in:
2026-08-09 21:12:16 +02:00
parent a0c9d7947b
commit c464c5f708
78 changed files with 5841 additions and 258 deletions
+64 -6
View File
@@ -21,16 +21,22 @@ export type AuthUser = {
nip: string | null;
birthDate: string | null;
verified: boolean;
phoneVerified: boolean;
blocked: boolean;
promotionCredits: number;
createdAt: string;
};
type AuthResponse = { token: string; user: AuthUser };
// Po rejestracji konto wymaga aktywacji linkiem e-mail - nie logujemy od razu.
export type RegisterPending = { email: string; phoneVerificationRequired: boolean };
export type RegisterDetails = {
accountType: AccountType;
phone?: string;
nip?: string;
address?: string;
};
type AuthContextValue = {
@@ -38,9 +44,16 @@ type AuthContextValue = {
token: string | null;
loading: boolean;
login: (email: string, password: string) => Promise<AuthUser>;
register: (email: string, password: string, fullName: string, details?: RegisterDetails) => Promise<AuthUser>;
register: (email: string, password: string, fullName: string, details?: RegisterDetails) => Promise<RegisterPending>;
socialLogin: (provider: Exclude<AuthProviderName, 'LOCAL'>) => Promise<AuthUser>;
activateAccount: (token: string) => Promise<void>;
resendActivation: (email: string) => Promise<void>;
forgotPassword: (email: string) => Promise<void>;
resetPassword: (token: string, password: string) => Promise<void>;
verifyPhone: (email: string, code: string) => Promise<void>;
resendPhoneOtp: (email: string) => Promise<void>;
updateProfile: (fullName: string, phone?: string, birthDate?: string, address?: string, contactPreference?: ContactPreference, preferredLanguage?: PreferredLanguage) => Promise<AuthUser>;
refreshUser: () => Promise<AuthUser | null>;
logout: () => void;
};
@@ -161,13 +174,14 @@ export function AuthProvider({ children }: { children: ReactNode }) {
[applyAuth],
);
// Rejestracja NIE loguje od razu - konto wymaga aktywacji linkiem z e-maila.
const register = useCallback(
async (email: string, password: string, fullName: string, details?: RegisterDetails) =>
applyAuth(await apiFetch<AuthResponse>('/auth/register', {
apiFetch<RegisterPending>('/auth/register', {
method: 'POST',
body: JSON.stringify({ email, password, fullName, ...details }),
})),
[applyAuth],
}),
[],
);
const socialLogin = useCallback(
@@ -179,6 +193,30 @@ export function AuthProvider({ children }: { children: ReactNode }) {
[applyAuth],
);
const activateAccount = useCallback(async (token: string) => {
await apiFetch<void>('/auth/activate', { method: 'POST', body: JSON.stringify({ token }) });
}, []);
const resendActivation = useCallback(async (email: string) => {
await apiFetch<void>('/auth/resend-activation', { method: 'POST', body: JSON.stringify({ email }) });
}, []);
const forgotPassword = useCallback(async (email: string) => {
await apiFetch<void>('/auth/forgot-password', { method: 'POST', body: JSON.stringify({ email }) });
}, []);
const resetPassword = useCallback(async (token: string, password: string) => {
await apiFetch<void>('/auth/reset-password', { method: 'POST', body: JSON.stringify({ token, password }) });
}, []);
const verifyPhone = useCallback(async (email: string, code: string) => {
await apiFetch<void>('/auth/verify-phone', { method: 'POST', body: JSON.stringify({ email, code }) });
}, []);
const resendPhoneOtp = useCallback(async (email: string) => {
await apiFetch<void>('/auth/resend-phone-otp', { method: 'POST', body: JSON.stringify({ email }) });
}, []);
const updateProfile = useCallback(
async (fullName: string, phone?: string, birthDate?: string, address?: string, contactPreference?: ContactPreference, preferredLanguage?: PreferredLanguage) => {
const updated = await apiFetch<AuthUser>('/auth/me', {
@@ -191,6 +229,20 @@ export function AuthProvider({ children }: { children: ReactNode }) {
[],
);
// Ponowne pobranie danych uzytkownika (np. po zakupie promowania - odswieza saldo kredytow).
const refreshUser = useCallback(async () => {
if (!getToken()) {
return null;
}
try {
const fresh = await apiFetch<AuthUser>('/auth/me');
setUser(fresh);
return fresh;
} catch {
return null;
}
}, []);
const logout = useCallback(() => {
window.localStorage.removeItem(TOKEN_KEY);
setToken(null);
@@ -198,8 +250,14 @@ export function AuthProvider({ children }: { children: ReactNode }) {
}, []);
const value = useMemo<AuthContextValue>(
() => ({ user, token, loading, login, register, socialLogin, updateProfile, logout }),
[user, token, loading, login, register, socialLogin, updateProfile, logout],
() => ({
user, token, loading, login, register, socialLogin,
activateAccount, resendActivation, forgotPassword, resetPassword, verifyPhone, resendPhoneOtp,
updateProfile, refreshUser, logout,
}),
[user, token, loading, login, register, socialLogin,
activateAccount, resendActivation, forgotPassword, resetPassword, verifyPhone, resendPhoneOtp,
updateProfile, refreshUser, logout],
);
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;