bug reg
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
import { useEffect, useState} from "react";
|
import { useEffect, useState, type SubmitEvent } from "react";
|
||||||
import { useSearchParams, Link } from "react-router-dom";
|
import { useSearchParams, Link } from "react-router-dom";
|
||||||
import * as React from "react";
|
|
||||||
|
|
||||||
function saveTokensAndRedirect(token: string, refreshToken: string, redirect: string) {
|
function saveTokensAndRedirect(token: string, refreshToken: string, redirect: string) {
|
||||||
localStorage.setItem("token", token);
|
localStorage.setItem("token", token);
|
||||||
@@ -26,7 +25,7 @@ export default function LoginPage() {
|
|||||||
}
|
}
|
||||||
}, [searchParams, redirect]);
|
}, [searchParams, redirect]);
|
||||||
|
|
||||||
async function handleSubmit(e: React.SyntheticEvent<HTMLFormElement>) {
|
async function handleSubmit(e: SubmitEvent<HTMLFormElement>) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setError("");
|
setError("");
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useState, FormEvent } from "react";
|
import { useState, type SubmitEvent } from "react";
|
||||||
import { useSearchParams, Link } from "react-router-dom";
|
import { useSearchParams, Link } from "react-router-dom";
|
||||||
|
|
||||||
function saveTokensAndRedirect(token: string, refreshToken: string, redirect: string) {
|
function saveTokensAndRedirect(token: string, refreshToken: string, redirect: string) {
|
||||||
@@ -18,7 +18,7 @@ export default function RegisterPage() {
|
|||||||
const [error, setError] = useState("");
|
const [error, setError] = useState("");
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
async function handleSubmit(e: FormEvent) {
|
async function handleSubmit(e: SubmitEvent<HTMLFormElement>) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setError("");
|
setError("");
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ export default function RegisterPage() {
|
|||||||
const res = await fetch("/api/auth/register", {
|
const res = await fetch("/api/auth/register", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify({ username, email, password }),
|
body: JSON.stringify({ username, email, password, confirmPassword }),
|
||||||
});
|
});
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
if (data.success && data.payload?.token) {
|
if (data.success && data.payload?.token) {
|
||||||
|
|||||||
@@ -1,333 +0,0 @@
|
|||||||
import { createSlice } from "@reduxjs/toolkit";
|
|
||||||
//import { addLoadedFiles } from "./slices/details-slice";
|
|
||||||
import fetchUserProfile from "./fetch-async/fetchUserProfile";
|
|
||||||
import {
|
|
||||||
BASE_URL,
|
|
||||||
METHOD_POST_QUERY,
|
|
||||||
PREFIX_DOCUMENT,
|
|
||||||
PREFIX_UPLOAD_STREAM,
|
|
||||||
FORM_DATA_FILES,
|
|
||||||
DEFAULT_ERROR_STATUS,
|
|
||||||
PROGRESS_STATUS_COMPLETED,
|
|
||||||
PROGRESS_STATUS_ERROR,
|
|
||||||
ERROR_NO_RESPONSE,
|
|
||||||
UNKNOWN_ERROR,
|
|
||||||
MAX_FILES_TO_UPLOAD,
|
|
||||||
} from "./constants";
|
|
||||||
|
|
||||||
const initialState = {
|
|
||||||
uploading: false,
|
|
||||||
error: {
|
|
||||||
status: null,
|
|
||||||
message: "",
|
|
||||||
},
|
|
||||||
success: false,
|
|
||||||
areFilesValid: true,
|
|
||||||
quotaError: null,
|
|
||||||
uploadedFiles: [],
|
|
||||||
progress: {
|
|
||||||
percent: 0,
|
|
||||||
processedFiles: 0,
|
|
||||||
totalFiles: 0,
|
|
||||||
currentFile: "",
|
|
||||||
status: "",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Store AbortController outside Redux state
|
|
||||||
let currentAbortController = null;
|
|
||||||
|
|
||||||
const uploadFilesSlice = createSlice({
|
|
||||||
name: "uploadFiles",
|
|
||||||
initialState,
|
|
||||||
reducers: {
|
|
||||||
resetUploadState() {
|
|
||||||
// Abort any ongoing upload when resetting
|
|
||||||
if (currentAbortController) {
|
|
||||||
currentAbortController.abort();
|
|
||||||
currentAbortController = null;
|
|
||||||
}
|
|
||||||
return initialState;
|
|
||||||
},
|
|
||||||
setAreFilesValid(state, action) {
|
|
||||||
state.areFilesValid = action.payload;
|
|
||||||
},
|
|
||||||
setQuotaError(state, action) {
|
|
||||||
state.quotaError = action.payload;
|
|
||||||
},
|
|
||||||
clearQuotaError(state) {
|
|
||||||
state.quotaError = null;
|
|
||||||
},
|
|
||||||
uploadStarted(state, action) {
|
|
||||||
state.uploading = true;
|
|
||||||
state.error = { status: null, message: "" };
|
|
||||||
state.success = false;
|
|
||||||
state.quotaError = null;
|
|
||||||
state.progress = {
|
|
||||||
percent: 0,
|
|
||||||
processedFiles: 0,
|
|
||||||
totalFiles: action.payload.totalFiles,
|
|
||||||
currentFile: "",
|
|
||||||
status: "starting",
|
|
||||||
};
|
|
||||||
},
|
|
||||||
progressUpdated(state, action) {
|
|
||||||
state.progress = action.payload;
|
|
||||||
},
|
|
||||||
uploadCompleted(state, action) {
|
|
||||||
state.uploading = false;
|
|
||||||
state.success = true;
|
|
||||||
state.uploadedFiles = action.payload.fileNames;
|
|
||||||
},
|
|
||||||
uploadFailed(state, action) {
|
|
||||||
state.uploading = false;
|
|
||||||
state.success = false;
|
|
||||||
state.error = {
|
|
||||||
status: action.payload.status ?? DEFAULT_ERROR_STATUS,
|
|
||||||
message: action.payload.message ?? UNKNOWN_ERROR,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
uploadCancelled(state) {
|
|
||||||
state.uploading = false;
|
|
||||||
state.success = false;
|
|
||||||
state.error = { status: null, message: "" };
|
|
||||||
state.progress = initialState.progress;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const {
|
|
||||||
resetUploadState,
|
|
||||||
setAreFilesValid,
|
|
||||||
setQuotaError,
|
|
||||||
clearQuotaError,
|
|
||||||
uploadStarted,
|
|
||||||
progressUpdated,
|
|
||||||
uploadCompleted,
|
|
||||||
uploadFailed,
|
|
||||||
uploadCancelled,
|
|
||||||
} = uploadFilesSlice.actions;
|
|
||||||
|
|
||||||
export const cancelUpload = () => (dispatch) => {
|
|
||||||
if (currentAbortController) {
|
|
||||||
currentAbortController.abort();
|
|
||||||
currentAbortController = null;
|
|
||||||
}
|
|
||||||
dispatch(uploadCancelled());
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate files against quota limits
|
|
||||||
* Returns { valid: boolean, error: string | null }
|
|
||||||
*/
|
|
||||||
export const validateFilesQuota = (files) => (dispatch, getState) => {
|
|
||||||
const state = getState();
|
|
||||||
const loadedFiles = state.userDetails?.loadedFiles || [];
|
|
||||||
const maxFilesToLoad = state.userDetails?.maxFilesToLoad || 0;
|
|
||||||
|
|
||||||
const loadedCount = loadedFiles.length;
|
|
||||||
const remainingSlots = Math.max(0, maxFilesToLoad - loadedCount);
|
|
||||||
const filesCount = files.length;
|
|
||||||
|
|
||||||
// Check max files per upload
|
|
||||||
if (filesCount > MAX_FILES_TO_UPLOAD) {
|
|
||||||
const errorMsg = `You can upload maximum ${MAX_FILES_TO_UPLOAD} files at once`;
|
|
||||||
dispatch(setQuotaError(errorMsg));
|
|
||||||
dispatch(setAreFilesValid(false));
|
|
||||||
return { valid: false, error: errorMsg };
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check remaining slots
|
|
||||||
if (filesCount > remainingSlots) {
|
|
||||||
const errorMsg =
|
|
||||||
remainingSlots === 0
|
|
||||||
? `You have reached the maximum number of files (${maxFilesToLoad})`
|
|
||||||
: `You can only upload ${remainingSlots} more file(s). Already loaded: ${loadedCount}/${maxFilesToLoad}`;
|
|
||||||
dispatch(setQuotaError(errorMsg));
|
|
||||||
dispatch(setAreFilesValid(false));
|
|
||||||
return { valid: false, error: errorMsg };
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch(clearQuotaError());
|
|
||||||
dispatch(setAreFilesValid(true));
|
|
||||||
return { valid: true, error: null };
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if user can upload files (has remaining slots)
|
|
||||||
*/
|
|
||||||
export const canUploadFiles = () => (dispatch, getState) => {
|
|
||||||
const state = getState();
|
|
||||||
const loadedFiles = state.userDetails?.loadedFiles || [];
|
|
||||||
const maxFilesToLoad = state.userDetails?.maxFilesToLoad || 0;
|
|
||||||
|
|
||||||
const remainingSlots = Math.max(0, maxFilesToLoad - loadedFiles.length);
|
|
||||||
return remainingSlots > 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get remaining upload slots
|
|
||||||
*/
|
|
||||||
export const getRemainingSlots = () => (dispatch, getState) => {
|
|
||||||
const state = getState();
|
|
||||||
const loadedFiles = state.userDetails?.loadedFiles || [];
|
|
||||||
const maxFilesToLoad = state.userDetails?.maxFilesToLoad || 0;
|
|
||||||
|
|
||||||
return Math.max(0, maxFilesToLoad - loadedFiles.length);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Thunk for uploading files with SSE progress streaming.
|
|
||||||
*/
|
|
||||||
export const uploadFilesWithProgress =
|
|
||||||
(files) => async (dispatch, getState) => {
|
|
||||||
const filesArray = Array.from(files);
|
|
||||||
const fileNames = filesArray.map((f) => f.name);
|
|
||||||
|
|
||||||
// Validate quota before upload
|
|
||||||
const state = getState();
|
|
||||||
const loadedFiles = state.userDetails?.loadedFiles || [];
|
|
||||||
const maxFilesToLoad = state.userDetails?.maxFilesToLoad || 0;
|
|
||||||
const loadedCount = loadedFiles.length;
|
|
||||||
const remainingSlots = Math.max(0, maxFilesToLoad - loadedCount);
|
|
||||||
|
|
||||||
// Check max files per upload
|
|
||||||
if (filesArray.length > MAX_FILES_TO_UPLOAD) {
|
|
||||||
dispatch(
|
|
||||||
uploadFailed({
|
|
||||||
status: 400,
|
|
||||||
message: `You can upload maximum ${MAX_FILES_TO_UPLOAD} files at once`,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check remaining slots
|
|
||||||
if (filesArray.length > remainingSlots) {
|
|
||||||
dispatch(
|
|
||||||
uploadFailed({
|
|
||||||
status: 400,
|
|
||||||
message:
|
|
||||||
remainingSlots === 0
|
|
||||||
? `You have reached the maximum number of files (${maxFilesToLoad})`
|
|
||||||
: `You can only upload ${remainingSlots} more file(s). Already loaded: ${loadedCount}/${maxFilesToLoad}`,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create new AbortController for this upload
|
|
||||||
currentAbortController = new AbortController();
|
|
||||||
const signal = currentAbortController.signal;
|
|
||||||
|
|
||||||
dispatch(uploadStarted({ totalFiles: filesArray.length }));
|
|
||||||
|
|
||||||
const formData = new FormData();
|
|
||||||
filesArray.forEach((file) => {
|
|
||||||
formData.append(FORM_DATA_FILES, file);
|
|
||||||
});
|
|
||||||
|
|
||||||
const token = state.userDetails?.token;
|
|
||||||
|
|
||||||
const headers = {};
|
|
||||||
if (token) {
|
|
||||||
headers.Authorization = `Bearer ${token}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await fetch(
|
|
||||||
`${BASE_URL}${PREFIX_DOCUMENT}${PREFIX_UPLOAD_STREAM}`,
|
|
||||||
{
|
|
||||||
method: METHOD_POST_QUERY,
|
|
||||||
headers,
|
|
||||||
body: formData,
|
|
||||||
signal,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
dispatch(
|
|
||||||
uploadFailed({
|
|
||||||
status: response.status,
|
|
||||||
message: `Server error: ${response.statusText}`,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const reader = response.body.getReader();
|
|
||||||
const decoder = new TextDecoder();
|
|
||||||
let buffer = "";
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
// Check if aborted before reading
|
|
||||||
if (signal.aborted) {
|
|
||||||
reader.cancel();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { done, value } = await reader.read();
|
|
||||||
|
|
||||||
if (done) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer += decoder.decode(value, { stream: true });
|
|
||||||
|
|
||||||
const lines = buffer.split("\n");
|
|
||||||
buffer = lines.pop() || "";
|
|
||||||
|
|
||||||
for (const line of lines) {
|
|
||||||
if (line.startsWith("data:")) {
|
|
||||||
const jsonStr = line.slice(5).trim();
|
|
||||||
if (jsonStr && jsonStr.startsWith("{")) {
|
|
||||||
try {
|
|
||||||
const progressData = JSON.parse(jsonStr);
|
|
||||||
dispatch(progressUpdated(progressData));
|
|
||||||
|
|
||||||
if (progressData.status === PROGRESS_STATUS_COMPLETED) {
|
|
||||||
dispatch(uploadCompleted({ fileNames }));
|
|
||||||
dispatch(fetchUserProfile());
|
|
||||||
//dispatch(addLoadedFiles(fileNames));
|
|
||||||
} else if (progressData.status === PROGRESS_STATUS_ERROR) {
|
|
||||||
dispatch(
|
|
||||||
uploadFailed({
|
|
||||||
status: DEFAULT_ERROR_STATUS,
|
|
||||||
message: `Error processing file: ${progressData.currentFile}`,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} catch (parseError) {
|
|
||||||
console.error("Failed to parse SSE data:", parseError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure completion if stream ended without explicit completed status
|
|
||||||
const currentState = getState();
|
|
||||||
if (currentState.uploadFiles.uploading) {
|
|
||||||
dispatch(uploadCompleted({ fileNames }));
|
|
||||||
dispatch(addLoadedFiles(fileNames));
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
// Don't dispatch error if it was an intentional abort
|
|
||||||
if (err.name === "AbortError") {
|
|
||||||
console.log("Upload cancelled by user");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.error("Upload stream error:", err);
|
|
||||||
dispatch(
|
|
||||||
uploadFailed({
|
|
||||||
status: DEFAULT_ERROR_STATUS,
|
|
||||||
message: `${ERROR_NO_RESPONSE}: ${err.message}`,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
} finally {
|
|
||||||
currentAbortController = null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//export default uploadFilesSlice.reducer;
|
|
||||||
@@ -1,199 +0,0 @@
|
|||||||
import { createSlice } from "@reduxjs/toolkit";
|
|
||||||
import fetchLoginUser from "./fetch-async/fetchLoginUser";
|
|
||||||
import fetchRegisterUser from "./fetch-async/fetchRegisterUser";
|
|
||||||
import fetchRefreshToken from "./fetch-async/fetchRefreshToken";
|
|
||||||
import fetchUserProfile from "./fetch-async/fetchUserProfile";
|
|
||||||
import fetchDeleteUploaded from "./fetch-async/fetchDeleteUploaded";
|
|
||||||
|
|
||||||
import {
|
|
||||||
USER_NAME_UNDEFINED,
|
|
||||||
USER_EMAIL_UNDEFINED,
|
|
||||||
JWT_TOKEN,
|
|
||||||
JWT_REFRESH_TOKEN,
|
|
||||||
TYPE_WINDOW_UNDEFINED,
|
|
||||||
TOKEN_UNDEFINED,
|
|
||||||
UNKNOWN_ERROR,
|
|
||||||
} from "./constants";
|
|
||||||
|
|
||||||
const getInitialToken = () => {
|
|
||||||
if (typeof window === TYPE_WINDOW_UNDEFINED) return null;
|
|
||||||
|
|
||||||
const token = localStorage.getItem(JWT_TOKEN);
|
|
||||||
if (!token || token === TOKEN_UNDEFINED) return null;
|
|
||||||
return token;
|
|
||||||
};
|
|
||||||
|
|
||||||
const initialState = {
|
|
||||||
userId: null,
|
|
||||||
userName: USER_NAME_UNDEFINED,
|
|
||||||
userEmail: USER_EMAIL_UNDEFINED,
|
|
||||||
loadedFiles: [],
|
|
||||||
maxFilesToLoad: 0,
|
|
||||||
token: getInitialToken(),
|
|
||||||
refreshToken: localStorage.getItem(JWT_REFRESH_TOKEN),
|
|
||||||
loading: false,
|
|
||||||
deleting: false,
|
|
||||||
deleteSuccess: false,
|
|
||||||
deletedCount: 0,
|
|
||||||
error: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
const userDetailsSlice = createSlice({
|
|
||||||
name: "userDetails",
|
|
||||||
initialState,
|
|
||||||
reducers: {
|
|
||||||
logoutUser(state) {
|
|
||||||
state.userId = null;
|
|
||||||
state.userName = USER_NAME_UNDEFINED;
|
|
||||||
state.userEmail = USER_EMAIL_UNDEFINED;
|
|
||||||
state.loadedFiles = [];
|
|
||||||
state.maxFilesToLoad = 0;
|
|
||||||
state.token = null;
|
|
||||||
state.refreshToken = null;
|
|
||||||
state.loading = false;
|
|
||||||
state.deleting = false;
|
|
||||||
state.deleteSuccess = false;
|
|
||||||
state.deletedCount = 0;
|
|
||||||
state.error = null;
|
|
||||||
localStorage.removeItem(JWT_TOKEN);
|
|
||||||
localStorage.removeItem(JWT_REFRESH_TOKEN);
|
|
||||||
},
|
|
||||||
clearError(state) {
|
|
||||||
state.error = null;
|
|
||||||
},
|
|
||||||
clearDeleteStatus(state) {
|
|
||||||
state.deleteSuccess = false;
|
|
||||||
state.deletedCount = 0;
|
|
||||||
},
|
|
||||||
addLoadedFiles(state, action) {
|
|
||||||
state.loadedFiles = [...state.loadedFiles, ...action.payload];
|
|
||||||
},
|
|
||||||
},
|
|
||||||
extraReducers: (builder) => {
|
|
||||||
builder.addCase(fetchRegisterUser.pending, (state) => {
|
|
||||||
state.loading = true;
|
|
||||||
state.error = null;
|
|
||||||
});
|
|
||||||
builder.addCase(fetchRegisterUser.fulfilled, (state, action) => {
|
|
||||||
state.loading = false;
|
|
||||||
state.error = null;
|
|
||||||
state.userName = action.payload.payload.username;
|
|
||||||
state.userEmail = action.payload.payload.email;
|
|
||||||
const token = action.payload.payload.token;
|
|
||||||
state.token = token || null;
|
|
||||||
if (token) {
|
|
||||||
localStorage.setItem(JWT_TOKEN, token);
|
|
||||||
} else {
|
|
||||||
localStorage.removeItem(JWT_TOKEN);
|
|
||||||
}
|
|
||||||
const refreshToken = action.payload.payload.refreshToken;
|
|
||||||
state.refreshToken = refreshToken || null;
|
|
||||||
if (refreshToken) {
|
|
||||||
localStorage.setItem(JWT_REFRESH_TOKEN, refreshToken);
|
|
||||||
} else {
|
|
||||||
localStorage.removeItem(JWT_REFRESH_TOKEN);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
builder.addCase(fetchRegisterUser.rejected, (state, action) => {
|
|
||||||
state.loading = false;
|
|
||||||
state.error = action.payload?.status ?? 500;
|
|
||||||
});
|
|
||||||
|
|
||||||
builder.addCase(fetchLoginUser.pending, (state) => {
|
|
||||||
state.loading = true;
|
|
||||||
state.error = null;
|
|
||||||
});
|
|
||||||
builder.addCase(fetchLoginUser.fulfilled, (state, action) => {
|
|
||||||
state.loading = false;
|
|
||||||
state.error = null;
|
|
||||||
state.userName = action.payload.payload.username;
|
|
||||||
state.userEmail = action.payload.payload.email;
|
|
||||||
|
|
||||||
const token = action.payload.payload.token;
|
|
||||||
state.token = token || null;
|
|
||||||
if (token) {
|
|
||||||
localStorage.setItem(JWT_TOKEN, token);
|
|
||||||
} else {
|
|
||||||
localStorage.removeItem(JWT_TOKEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
const refreshToken = action.payload.payload.refreshToken;
|
|
||||||
state.refreshToken = refreshToken || null;
|
|
||||||
if (refreshToken) {
|
|
||||||
localStorage.setItem(JWT_REFRESH_TOKEN, refreshToken);
|
|
||||||
} else {
|
|
||||||
localStorage.removeItem(JWT_REFRESH_TOKEN);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
builder.addCase(fetchLoginUser.rejected, (state, action) => {
|
|
||||||
state.loading = false;
|
|
||||||
state.error = action.payload ?? { status: 500, message: "Unknown error" };
|
|
||||||
});
|
|
||||||
|
|
||||||
builder.addCase(fetchRefreshToken.fulfilled, (state, action) => {
|
|
||||||
const token = action.payload?.payload?.token;
|
|
||||||
const refreshToken = action.payload?.payload?.refreshToken;
|
|
||||||
|
|
||||||
state.token = token || null;
|
|
||||||
state.refreshToken = refreshToken || null;
|
|
||||||
|
|
||||||
if (token) localStorage.setItem(JWT_TOKEN, token);
|
|
||||||
else localStorage.removeItem(JWT_TOKEN);
|
|
||||||
|
|
||||||
if (refreshToken) localStorage.setItem(JWT_REFRESH_TOKEN, refreshToken);
|
|
||||||
else localStorage.removeItem(JWT_REFRESH_TOKEN);
|
|
||||||
});
|
|
||||||
|
|
||||||
builder.addCase(fetchRefreshToken.rejected, (state, action) => {
|
|
||||||
state.error = action.payload ?? { status: 500, message: UNKNOWN_ERROR };
|
|
||||||
});
|
|
||||||
|
|
||||||
builder.addCase(fetchUserProfile.pending, (state) => {
|
|
||||||
state.loading = true;
|
|
||||||
state.error = null;
|
|
||||||
});
|
|
||||||
|
|
||||||
builder.addCase(fetchUserProfile.fulfilled, (state, action) => {
|
|
||||||
state.loading = false;
|
|
||||||
state.error = null;
|
|
||||||
|
|
||||||
const p = action.payload?.payload;
|
|
||||||
|
|
||||||
if (p?.id) state.userId = p.id;
|
|
||||||
if (p?.username) state.userName = p.username;
|
|
||||||
if (p?.email) state.userEmail = p.email;
|
|
||||||
if (p?.loadedFiles) state.loadedFiles = p.loadedFiles;
|
|
||||||
if (p?.maxLoadedFiles != null) state.maxFilesToLoad = p.maxLoadedFiles;
|
|
||||||
});
|
|
||||||
|
|
||||||
builder.addCase(fetchUserProfile.rejected, (state, action) => {
|
|
||||||
state.loading = false;
|
|
||||||
state.error = action.payload ?? { status: 500, message: "Unknown error" };
|
|
||||||
});
|
|
||||||
|
|
||||||
// Delete uploaded files
|
|
||||||
builder.addCase(fetchDeleteUploaded.pending, (state) => {
|
|
||||||
state.deleting = true;
|
|
||||||
state.deleteSuccess = false;
|
|
||||||
state.deletedCount = 0;
|
|
||||||
state.error = null;
|
|
||||||
});
|
|
||||||
|
|
||||||
builder.addCase(fetchDeleteUploaded.fulfilled, (state, action) => {
|
|
||||||
state.deleting = false;
|
|
||||||
state.deleteSuccess = true;
|
|
||||||
state.deletedCount = action.payload?.payload ?? 0;
|
|
||||||
state.loadedFiles = [];
|
|
||||||
state.error = null;
|
|
||||||
});
|
|
||||||
|
|
||||||
builder.addCase(fetchDeleteUploaded.rejected, (state, action) => {
|
|
||||||
state.deleting = false;
|
|
||||||
state.deleteSuccess = false;
|
|
||||||
state.error = action.payload ?? { status: 500, message: "Unknown error" };
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
//export const { logoutUser, clearError, clearDeleteStatus, addLoadedFiles } = userDetailsSlice.actions;
|
|
||||||
//export default userDetailsSlice.reducer;
|
|
||||||
Reference in New Issue
Block a user