@myrjfa/state 1.1.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +34 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -18
- package/dist/lib/actions/actions.d.ts +170 -170
- package/dist/lib/actions/actions.js +307 -307
- package/dist/lib/actions/auth.d.ts +20 -0
- package/dist/lib/actions/auth.d.ts.map +1 -1
- package/dist/lib/actions/booking.d.ts +30 -0
- package/dist/lib/actions/booking.d.ts.map +1 -0
- package/dist/lib/actions/booking.js +77 -0
- package/dist/lib/actions/fetcher.js +84 -84
- package/dist/lib/actions/severActions.js +2 -2
- package/dist/lib/authSessionManager.js +34 -34
- package/dist/lib/context/ChatContext.js +338 -338
- package/dist/lib/models/adventure.d.ts +75 -0
- package/dist/lib/models/adventure.d.ts.map +1 -0
- package/dist/lib/models/adventure.js +1 -0
- package/dist/lib/models/blog.d.ts +4 -4
- package/dist/lib/models/booking.d.ts +47 -0
- package/dist/lib/models/booking.d.ts.map +1 -0
- package/dist/lib/models/booking.js +1 -0
- package/dist/lib/models/guide.d.ts +43 -0
- package/dist/lib/models/guide.d.ts.map +1 -0
- package/dist/lib/models/guide.js +1 -0
- package/dist/lib/models/notfications.d.ts +93 -93
- package/dist/lib/models/opportunities/freelance.d.ts +74 -6
- package/dist/lib/models/opportunities/freelance.d.ts.map +1 -1
- package/dist/lib/models/opportunities/internship.d.ts +74 -6
- package/dist/lib/models/opportunities/internship.d.ts.map +1 -1
- package/dist/lib/models/opportunities/job.d.ts +74 -6
- package/dist/lib/models/opportunities/job.d.ts.map +1 -1
- package/dist/lib/models/opportunities/opportunity.d.ts +74 -6
- package/dist/lib/models/opportunities/opportunity.d.ts.map +1 -1
- package/dist/lib/models/opportunities/volunteerJob.d.ts +74 -6
- package/dist/lib/models/opportunities/volunteerJob.d.ts.map +1 -1
- package/dist/lib/models/package.d.ts +264 -0
- package/dist/lib/models/package.d.ts.map +1 -0
- package/dist/lib/models/package.js +58 -0
- package/dist/lib/models/portfolio.d.ts +42 -42
- package/dist/lib/models/props.d.ts +3 -0
- package/dist/lib/models/props.d.ts.map +1 -1
- package/dist/lib/models/props.js +36 -0
- package/dist/lib/models/rental.d.ts +85 -0
- package/dist/lib/models/rental.d.ts.map +1 -0
- package/dist/lib/models/rental.js +1 -0
- package/dist/lib/models/review.d.ts +1 -1
- package/dist/lib/models/review.d.ts.map +1 -1
- package/dist/lib/models/stay.d.ts +459 -0
- package/dist/lib/models/stay.d.ts.map +1 -0
- package/dist/lib/models/stay.js +214 -0
- package/dist/lib/models/tile.d.ts +53 -28
- package/dist/lib/models/tile.d.ts.map +1 -1
- package/dist/lib/models/user.d.ts +48 -0
- package/dist/lib/models/user.d.ts.map +1 -1
- package/dist/lib/models/user.js +10 -0
- package/dist/lib/userAtom.d.ts +238 -198
- package/dist/lib/userAtom.d.ts.map +1 -1
- package/dist/lib/userAtom.js +127 -127
- package/package.json +6 -1
- package/dist/lib/actions/property.d.ts +0 -77
- package/dist/lib/actions/property.d.ts.map +0 -1
- package/dist/lib/actions/property.js +0 -133
- package/dist/lib/actions.d.ts +0 -141
- package/dist/lib/actions.d.ts.map +0 -1
- package/dist/lib/actions.js +0 -307
- package/dist/lib/auth.d.ts +0 -150
- package/dist/lib/auth.d.ts.map +0 -1
- package/dist/lib/auth.js +0 -125
- package/dist/lib/fetcher.d.ts +0 -9
- package/dist/lib/fetcher.d.ts.map +0 -1
- package/dist/lib/fetcher.js +0 -84
- package/dist/lib/models/property.d.ts +0 -79
- package/dist/lib/models/property.d.ts.map +0 -1
- package/dist/lib/models/property.js +0 -134
- package/dist/lib/models/volunteerJob.d.ts +0 -398
- package/dist/lib/models/volunteerJob.d.ts.map +0 -1
- package/dist/lib/models/volunteerJob.js +0 -152
- package/dist/lib/severActions.d.ts +0 -3
- package/dist/lib/severActions.d.ts.map +0 -1
- package/dist/lib/severActions.js +0 -19
- package/dist/lib/socket.d.ts +0 -7
- package/dist/lib/socket.d.ts.map +0 -1
- package/dist/lib/socket.js +0 -22
- package/dist/lib/utils/socialMediaUrl.d.ts +0 -25
- package/dist/lib/utils/socialMediaUrl.d.ts.map +0 -1
- package/dist/lib/utils/socialMediaUrl.js +0 -97
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Booking, CreateBookingRequest } from "../models/booking";
|
|
2
|
+
export declare function createBooking(bookingData: CreateBookingRequest): Promise<{
|
|
3
|
+
success: boolean;
|
|
4
|
+
booking: Booking | null;
|
|
5
|
+
message?: string;
|
|
6
|
+
error?: string;
|
|
7
|
+
}>;
|
|
8
|
+
export declare function getMyBookings(): Promise<{
|
|
9
|
+
success: boolean;
|
|
10
|
+
bookings: Booking[];
|
|
11
|
+
message?: string;
|
|
12
|
+
error?: string;
|
|
13
|
+
}>;
|
|
14
|
+
export declare function getBookingById(bookingId: string): Promise<{
|
|
15
|
+
success: boolean;
|
|
16
|
+
booking: Booking | null;
|
|
17
|
+
message?: string;
|
|
18
|
+
error?: string;
|
|
19
|
+
}>;
|
|
20
|
+
export declare function updateBookingStatus(bookingId: string, statusData: {
|
|
21
|
+
status?: string;
|
|
22
|
+
paymentStatus?: string;
|
|
23
|
+
paymentId?: string;
|
|
24
|
+
}): Promise<{
|
|
25
|
+
success: boolean;
|
|
26
|
+
booking: Booking | null;
|
|
27
|
+
message?: string;
|
|
28
|
+
error?: string;
|
|
29
|
+
}>;
|
|
30
|
+
//# sourceMappingURL=booking.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"booking.d.ts","sourceRoot":"","sources":["../../../src/lib/actions/booking.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAElE,wBAAsB,aAAa,CAAC,WAAW,EAAE,oBAAoB,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAiB/J;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,OAAO,EAAE,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAiB1H;AAED,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAiBhJ;AAED,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAiBlO"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { get, patch, post } from "./fetcher";
|
|
2
|
+
export async function createBooking(bookingData) {
|
|
3
|
+
try {
|
|
4
|
+
const endpoint = `/bookings/create`;
|
|
5
|
+
const data = await post(endpoint, bookingData);
|
|
6
|
+
return {
|
|
7
|
+
success: true,
|
|
8
|
+
booking: data.data,
|
|
9
|
+
message: data.message,
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
catch (error) {
|
|
13
|
+
console.error('Failed to create booking: ', error);
|
|
14
|
+
return {
|
|
15
|
+
success: false,
|
|
16
|
+
booking: null,
|
|
17
|
+
error: error.message,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export async function getMyBookings() {
|
|
22
|
+
try {
|
|
23
|
+
const endpoint = `/bookings/my`;
|
|
24
|
+
const data = await get(endpoint);
|
|
25
|
+
return {
|
|
26
|
+
success: true,
|
|
27
|
+
bookings: data.data,
|
|
28
|
+
message: data.message,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
console.error('Failed to fetch bookings: ', error);
|
|
33
|
+
return {
|
|
34
|
+
success: false,
|
|
35
|
+
bookings: [],
|
|
36
|
+
error: error.message,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export async function getBookingById(bookingId) {
|
|
41
|
+
try {
|
|
42
|
+
const endpoint = `/bookings/${bookingId}`;
|
|
43
|
+
const data = await get(endpoint);
|
|
44
|
+
return {
|
|
45
|
+
success: true,
|
|
46
|
+
booking: data.data,
|
|
47
|
+
message: data.message,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
console.error('Failed to fetch booking by id: ', error);
|
|
52
|
+
return {
|
|
53
|
+
success: false,
|
|
54
|
+
booking: null,
|
|
55
|
+
error: error.message,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export async function updateBookingStatus(bookingId, statusData) {
|
|
60
|
+
try {
|
|
61
|
+
const endpoint = `/bookings/${bookingId}/status`;
|
|
62
|
+
const data = await patch(endpoint, statusData);
|
|
63
|
+
return {
|
|
64
|
+
success: true,
|
|
65
|
+
booking: data.data,
|
|
66
|
+
message: data.message,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
console.error('Failed to update booking status: ', error);
|
|
71
|
+
return {
|
|
72
|
+
success: false,
|
|
73
|
+
booking: null,
|
|
74
|
+
error: error.message,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -1,84 +1,84 @@
|
|
|
1
|
-
import { ApiError } from "next/dist/server/api-utils";
|
|
2
|
-
import { getCookieHeader, getRole } from "./severActions";
|
|
3
|
-
const baseURL = process.env.NEXT_PUBLIC_API_URL;
|
|
4
|
-
async function customFetch(input, method, body, options = {}) {
|
|
5
|
-
const { includeAuth = false, retry = true } = options;
|
|
6
|
-
const url = `${baseURL}${input}`;
|
|
7
|
-
const isFormData = typeof FormData !== 'undefined' && body instanceof FormData;
|
|
8
|
-
let headers = isFormData
|
|
9
|
-
? { Accept: 'application/json' }
|
|
10
|
-
: { 'Content-Type': 'application/json', Accept: 'application/json' };
|
|
11
|
-
if (includeAuth) {
|
|
12
|
-
try {
|
|
13
|
-
const cookieHeader = await getCookieHeader();
|
|
14
|
-
headers = { ...headers, Cookie: cookieHeader };
|
|
15
|
-
}
|
|
16
|
-
catch (error) {
|
|
17
|
-
// If we can't get cookies (CSR context), credentials: 'include' will handle it
|
|
18
|
-
console.warn('Could not get cookies for auth header:', error);
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
const init = {
|
|
22
|
-
method,
|
|
23
|
-
credentials: 'include',
|
|
24
|
-
headers,
|
|
25
|
-
...(body ? { body: isFormData ? body : JSON.stringify(body) } : {}),
|
|
26
|
-
};
|
|
27
|
-
const response = await fetch(url, init);
|
|
28
|
-
if (response.ok) {
|
|
29
|
-
return response.status !== 204 ? (await response.json()) : {};
|
|
30
|
-
}
|
|
31
|
-
// Token refresh logic on 401 (only for authenticated requests)
|
|
32
|
-
if (response.status === 401 && retry && includeAuth && !input.includes('/login')) {
|
|
33
|
-
return await refreshToken(input, method, body);
|
|
34
|
-
}
|
|
35
|
-
// Error handling
|
|
36
|
-
let errorBody;
|
|
37
|
-
try {
|
|
38
|
-
errorBody = (await response.json());
|
|
39
|
-
}
|
|
40
|
-
catch (error) {
|
|
41
|
-
errorBody = {
|
|
42
|
-
statusCode: response.status,
|
|
43
|
-
error: typeof error === 'string' ? error : 'Unknown error',
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
throw new ApiError(errorBody.statusCode, errorBody.error);
|
|
47
|
-
}
|
|
48
|
-
// Token refresh function
|
|
49
|
-
export async function refreshToken(input, method, body) {
|
|
50
|
-
const role = await getRole();
|
|
51
|
-
try {
|
|
52
|
-
const roleForEndpoint = role == "admin" ? "user" : role;
|
|
53
|
-
const response = await fetch(`${baseURL}/${roleForEndpoint}s/refresh-token`, {
|
|
54
|
-
method: 'POST',
|
|
55
|
-
credentials: 'include',
|
|
56
|
-
});
|
|
57
|
-
const data = await response.json();
|
|
58
|
-
if (response.ok) {
|
|
59
|
-
return customFetch(input, method, body, { includeAuth: true, retry: false });
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
throw { statusCode: 401, error: data.error };
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
catch (error) {
|
|
66
|
-
throw new ApiError(error.statusCode ?? 500, error.error);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
// ✅ Sever-safe exported functions
|
|
70
|
-
export async function get(url, includeAuth = true) {
|
|
71
|
-
return customFetch(url, 'GET', undefined, { includeAuth });
|
|
72
|
-
}
|
|
73
|
-
export async function post(url, body) {
|
|
74
|
-
return customFetch(url, 'POST', body, { includeAuth: true });
|
|
75
|
-
}
|
|
76
|
-
export async function put(url, body) {
|
|
77
|
-
return customFetch(url, 'PUT', body, { includeAuth: true });
|
|
78
|
-
}
|
|
79
|
-
export async function patch(url, body) {
|
|
80
|
-
return customFetch(url, 'PATCH', body, { includeAuth: true });
|
|
81
|
-
}
|
|
82
|
-
export async function del(url, body) {
|
|
83
|
-
return customFetch(url, 'DELETE', body, { includeAuth: true });
|
|
84
|
-
}
|
|
1
|
+
import { ApiError } from "next/dist/server/api-utils";
|
|
2
|
+
import { getCookieHeader, getRole } from "./severActions";
|
|
3
|
+
const baseURL = process.env.NEXT_PUBLIC_API_URL;
|
|
4
|
+
async function customFetch(input, method, body, options = {}) {
|
|
5
|
+
const { includeAuth = false, retry = true } = options;
|
|
6
|
+
const url = `${baseURL}${input}`;
|
|
7
|
+
const isFormData = typeof FormData !== 'undefined' && body instanceof FormData;
|
|
8
|
+
let headers = isFormData
|
|
9
|
+
? { Accept: 'application/json' }
|
|
10
|
+
: { 'Content-Type': 'application/json', Accept: 'application/json' };
|
|
11
|
+
if (includeAuth) {
|
|
12
|
+
try {
|
|
13
|
+
const cookieHeader = await getCookieHeader();
|
|
14
|
+
headers = { ...headers, Cookie: cookieHeader };
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
// If we can't get cookies (CSR context), credentials: 'include' will handle it
|
|
18
|
+
console.warn('Could not get cookies for auth header:', error);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
const init = {
|
|
22
|
+
method,
|
|
23
|
+
credentials: 'include',
|
|
24
|
+
headers,
|
|
25
|
+
...(body ? { body: isFormData ? body : JSON.stringify(body) } : {}),
|
|
26
|
+
};
|
|
27
|
+
const response = await fetch(url, init);
|
|
28
|
+
if (response.ok) {
|
|
29
|
+
return response.status !== 204 ? (await response.json()) : {};
|
|
30
|
+
}
|
|
31
|
+
// Token refresh logic on 401 (only for authenticated requests)
|
|
32
|
+
if (response.status === 401 && retry && includeAuth && !input.includes('/login')) {
|
|
33
|
+
return await refreshToken(input, method, body);
|
|
34
|
+
}
|
|
35
|
+
// Error handling
|
|
36
|
+
let errorBody;
|
|
37
|
+
try {
|
|
38
|
+
errorBody = (await response.json());
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
errorBody = {
|
|
42
|
+
statusCode: response.status,
|
|
43
|
+
error: typeof error === 'string' ? error : 'Unknown error',
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
throw new ApiError(errorBody.statusCode, errorBody.error);
|
|
47
|
+
}
|
|
48
|
+
// Token refresh function
|
|
49
|
+
export async function refreshToken(input, method, body) {
|
|
50
|
+
const role = await getRole();
|
|
51
|
+
try {
|
|
52
|
+
const roleForEndpoint = role == "admin" ? "user" : role;
|
|
53
|
+
const response = await fetch(`${baseURL}/${roleForEndpoint}s/refresh-token`, {
|
|
54
|
+
method: 'POST',
|
|
55
|
+
credentials: 'include',
|
|
56
|
+
});
|
|
57
|
+
const data = await response.json();
|
|
58
|
+
if (response.ok) {
|
|
59
|
+
return customFetch(input, method, body, { includeAuth: true, retry: false });
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
throw { statusCode: 401, error: data.error };
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
throw new ApiError(error.statusCode ?? 500, error.error);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// ✅ Sever-safe exported functions
|
|
70
|
+
export async function get(url, includeAuth = true) {
|
|
71
|
+
return customFetch(url, 'GET', undefined, { includeAuth });
|
|
72
|
+
}
|
|
73
|
+
export async function post(url, body) {
|
|
74
|
+
return customFetch(url, 'POST', body, { includeAuth: true });
|
|
75
|
+
}
|
|
76
|
+
export async function put(url, body) {
|
|
77
|
+
return customFetch(url, 'PUT', body, { includeAuth: true });
|
|
78
|
+
}
|
|
79
|
+
export async function patch(url, body) {
|
|
80
|
+
return customFetch(url, 'PATCH', body, { includeAuth: true });
|
|
81
|
+
}
|
|
82
|
+
export async function del(url, body) {
|
|
83
|
+
return customFetch(url, 'DELETE', body, { includeAuth: true });
|
|
84
|
+
}
|
|
@@ -3,8 +3,8 @@ import { cookies } from 'next/headers';
|
|
|
3
3
|
import { validRoles } from '../utils';
|
|
4
4
|
export async function getCookieHeader() {
|
|
5
5
|
const cookieStore = await cookies();
|
|
6
|
-
return
|
|
7
|
-
.map((
|
|
6
|
+
return cookieStore.getAll()
|
|
7
|
+
.map((cookie) => `${cookie.name}=${cookie.value}`)
|
|
8
8
|
.join('; ');
|
|
9
9
|
}
|
|
10
10
|
export async function getRole() {
|
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { useAtom } from 'jotai'; // Import useSetAtom
|
|
3
|
-
import { useEffect } from 'react';
|
|
4
|
-
import { useQuery } from '@tanstack/react-query';
|
|
5
|
-
import { initializeAuthSessionAtom, resetAuthState } from './userAtom'; // Import the atom itself
|
|
6
|
-
import { validateSession } from './actions/auth';
|
|
7
|
-
export default function AuthSessionManager() {
|
|
8
|
-
const [, initializeAuthSession] = useAtom(initializeAuthSessionAtom);
|
|
9
|
-
// --- Initial Session Load ---
|
|
10
|
-
useEffect(() => {
|
|
11
|
-
initializeAuthSession();
|
|
12
|
-
}, [initializeAuthSession]);
|
|
13
|
-
// --- Continuous Background Re-validation ---
|
|
14
|
-
const { isError } = useQuery({
|
|
15
|
-
queryKey: ['session'],
|
|
16
|
-
queryFn: validateSession,
|
|
17
|
-
// --- Configuration for a seamless experience ---
|
|
18
|
-
refetchOnWindowFocus: true,
|
|
19
|
-
refetchOnReconnect: true,
|
|
20
|
-
retry: (failureCount, error) => {
|
|
21
|
-
if (error.response?.status === 401)
|
|
22
|
-
return false;
|
|
23
|
-
return failureCount < 2;
|
|
24
|
-
},
|
|
25
|
-
staleTime: 15 * 60 * 1000,
|
|
26
|
-
});
|
|
27
|
-
useEffect(() => {
|
|
28
|
-
if (isError) {
|
|
29
|
-
console.log("Session validation failed. Logging out.");
|
|
30
|
-
resetAuthState();
|
|
31
|
-
}
|
|
32
|
-
}, [isError, resetAuthState]);
|
|
33
|
-
return null;
|
|
34
|
-
}
|
|
1
|
+
'use client';
|
|
2
|
+
import { useAtom } from 'jotai'; // Import useSetAtom
|
|
3
|
+
import { useEffect } from 'react';
|
|
4
|
+
import { useQuery } from '@tanstack/react-query';
|
|
5
|
+
import { initializeAuthSessionAtom, resetAuthState } from './userAtom'; // Import the atom itself
|
|
6
|
+
import { validateSession } from './actions/auth';
|
|
7
|
+
export default function AuthSessionManager() {
|
|
8
|
+
const [, initializeAuthSession] = useAtom(initializeAuthSessionAtom);
|
|
9
|
+
// --- Initial Session Load ---
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
initializeAuthSession();
|
|
12
|
+
}, [initializeAuthSession]);
|
|
13
|
+
// --- Continuous Background Re-validation ---
|
|
14
|
+
const { isError } = useQuery({
|
|
15
|
+
queryKey: ['session'],
|
|
16
|
+
queryFn: validateSession,
|
|
17
|
+
// --- Configuration for a seamless experience ---
|
|
18
|
+
refetchOnWindowFocus: true,
|
|
19
|
+
refetchOnReconnect: true,
|
|
20
|
+
retry: (failureCount, error) => {
|
|
21
|
+
if (error.response?.status === 401)
|
|
22
|
+
return false;
|
|
23
|
+
return failureCount < 2;
|
|
24
|
+
},
|
|
25
|
+
staleTime: 15 * 60 * 1000,
|
|
26
|
+
});
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
if (isError) {
|
|
29
|
+
console.log("Session validation failed. Logging out.");
|
|
30
|
+
resetAuthState();
|
|
31
|
+
}
|
|
32
|
+
}, [isError, resetAuthState]);
|
|
33
|
+
return null;
|
|
34
|
+
}
|