zmiany w ustawieniach

This commit is contained in:
2026-08-12 17:03:22 +02:00
parent 1e361bde93
commit fbb7ab2d90
32 changed files with 2784 additions and 1194 deletions
+88 -12
View File
@@ -7,10 +7,45 @@ export type AccountType = 'PERSONAL' | 'COMPANY';
export type ContactPreference = 'EMAIL' | 'PHONE' | 'EMAIL_AND_PHONE';
export type PreferredLanguage = 'PL' | 'EN' | 'UK' | 'DE';
export type Currency = 'PLN' | 'EUR' | 'USD';
export type AreaUnit = 'M2' | 'FT2';
export type ProfileVisibility = 'PUBLIC' | 'CONTACTS' | 'PRIVATE';
/**
* Ustawienia konta trzymane na serwerze (/api/me/settings). Zgody marketingowe celowo tu nie leza -
* ich jedynym zrodlem jest /api/me/marketing, bo steruja kwalifikacja do kampanii.
*/
export type UserSettings = {
bio: string | null;
profileVisibility: ProfileVisibility;
avatarImage: string | null;
coverImage: string | null;
currency: Currency;
areaUnit: AreaUnit;
directOffersOnly: boolean;
hideInactiveOffers: boolean;
saveSearchesOnHome: boolean;
notifySavedSearches: boolean;
notifyPriceAlerts: boolean;
notifyMessages: boolean;
notifyProductNews: boolean;
searchLocations: string | null;
searchPropertyType: string | null;
searchBudgetMax: number | null;
searchAreaMin: number | null;
searchAreaMax: number | null;
searchRoomsMin: number | null;
searchRoomsMax: number | null;
};
// Zapis czesciowy: pominiete pole zostaje bez zmian, pusty tekst je czysci, liczba ujemna zeruje.
export type UserSettingsPatch = Partial<Record<keyof UserSettings, unknown>>;
export type AuthUser = {
id: number;
email: string;
fullName: string;
nick: string | null;
role: Role;
provider: AuthProviderName;
accountType: AccountType;
@@ -52,11 +87,29 @@ type AuthContextValue = {
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>;
updateProfile: (profile: ProfileUpdate) => Promise<AuthUser>;
changePassword: (currentPassword: string, newPassword: string) => Promise<void>;
deleteAccount: (password: string) => Promise<void>;
loadSettings: () => Promise<UserSettings>;
saveSettings: (patch: UserSettingsPatch) => Promise<UserSettings>;
refreshUser: () => Promise<AuthUser | null>;
logout: () => void;
};
/**
* PUT /auth/me nadpisuje caly profil, wiec wysylamy komplet pol, a nie tylko zmienione.
* Pusty nick oznacza "zostaw dotychczasowy" - backend nie zmienia wtedy nazwy uzytkownika.
*/
export type ProfileUpdate = {
fullName: string;
nick?: string;
phone?: string;
birthDate?: string;
address?: string;
contactPreference?: ContactPreference;
preferredLanguage?: PreferredLanguage;
};
const TOKEN_KEY = 'polskalokalnie-auth-token';
const API_BASE = '/api';
@@ -217,15 +270,38 @@ export function AuthProvider({ children }: { children: ReactNode }) {
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', {
method: 'PUT',
body: JSON.stringify({ fullName, phone, birthDate, address, contactPreference, preferredLanguage }),
});
setUser(updated);
return updated;
},
const updateProfile = useCallback(async (profile: ProfileUpdate) => {
const updated = await apiFetch<AuthUser>('/auth/me', {
method: 'PUT',
body: JSON.stringify(profile),
});
setUser(updated);
return updated;
}, []);
const changePassword = useCallback(async (currentPassword: string, newPassword: string) => {
await apiFetch<void>('/auth/change-password', {
method: 'POST',
body: JSON.stringify({ currentPassword, newPassword }),
});
}, []);
// Po usunieciu konta token jest bezuzyteczny - czyscimy sesje od razu, bez czekania na 401.
const deleteAccount = useCallback(async (password: string) => {
await apiFetch<void>('/auth/me', {
method: 'DELETE',
body: JSON.stringify({ password }),
});
window.localStorage.removeItem(TOKEN_KEY);
setToken(null);
setUser(null);
}, []);
const loadSettings = useCallback(async () => apiFetch<UserSettings>('/me/settings'), []);
const saveSettings = useCallback(
async (patch: UserSettingsPatch) =>
apiFetch<UserSettings>('/me/settings', { method: 'PUT', body: JSON.stringify(patch) }),
[],
);
@@ -253,11 +329,11 @@ export function AuthProvider({ children }: { children: ReactNode }) {
() => ({
user, token, loading, login, register, socialLogin,
activateAccount, resendActivation, forgotPassword, resetPassword, verifyPhone, resendPhoneOtp,
updateProfile, refreshUser, logout,
updateProfile, changePassword, deleteAccount, loadSettings, saveSettings, refreshUser, logout,
}),
[user, token, loading, login, register, socialLogin,
activateAccount, resendActivation, forgotPassword, resetPassword, verifyPhone, resendPhoneOtp,
updateProfile, refreshUser, logout],
updateProfile, changePassword, deleteAccount, loadSettings, saveSettings, refreshUser, logout],
);
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;