From 5b6ec0342bdb59e01f8eb5c9675bfdfb7d3d5eea Mon Sep 17 00:00:00 2001 From: Sabda Yagra Date: Thu, 29 Jan 2026 09:11:43 +0700 Subject: [PATCH] fix: all errors --- app/[locale]/(admin)/admin/dashboard/page.tsx | 2 +- .../(admin)/admin/management-user/page.tsx | 2 +- .../tenant-settings-content-table.tsx | 39 +- app/[locale]/auth/page.tsx | 4 +- components/auth/login-form.tsx | 22 +- components/auth/otp-form.tsx | 7 +- components/form/ApprovalWorkflowForm.tsx | 405 +++++++++++++----- components/loader.tsx | 2 +- .../management-user-internal-table.tsx | 2 +- hooks/use-auth.ts | 51 ++- types/auth.ts | 9 +- 11 files changed, 387 insertions(+), 158 deletions(-) diff --git a/app/[locale]/(admin)/admin/dashboard/page.tsx b/app/[locale]/(admin)/admin/dashboard/page.tsx index 61f32a6..938905c 100644 --- a/app/[locale]/(admin)/admin/dashboard/page.tsx +++ b/app/[locale]/(admin)/admin/dashboard/page.tsx @@ -21,7 +21,7 @@ export default function AdminPage() { return ( -
+

Data User diff --git a/app/[locale]/(admin)/admin/settings/tenant/component/tenant-settings-content-table.tsx b/app/[locale]/(admin)/admin/settings/tenant/component/tenant-settings-content-table.tsx index c15ae20..1e713f1 100644 --- a/app/[locale]/(admin)/admin/settings/tenant/component/tenant-settings-content-table.tsx +++ b/app/[locale]/(admin)/admin/settings/tenant/component/tenant-settings-content-table.tsx @@ -199,7 +199,7 @@ function TenantSettingsContentTable() {

-

Tenant Settings

+

Tenant Settings

Manage approval workflows and user levels for your tenant

@@ -255,7 +255,8 @@ function TenantSettingsContentTable() { Approval Workflow Setup {workflow && !isEditingWorkflow && ( -
- {isEditingWorkflow ? ( + {isEditingWorkflow && workflow && workflow.workflow?.id ? ( @@ -280,6 +281,8 @@ function TenantSettingsContentTable() { ({ stepOrder: step.stepOrder, @@ -372,12 +379,18 @@ function TenantSettingsContentTable() {
- {workflow.workflow.requiresApproval ? "Yes" : "No"} + { + // workflow.workflow.requiresApproval + workflow.clientSettings.requiresApproval + ? "Yes" + : "No" + }
Requires Approval @@ -387,12 +400,18 @@ function TenantSettingsContentTable() {
- {workflow.workflow.autoPublish ? "Yes" : "No"} + { + // workflow.workflow.autoPublish + workflow.clientSettings.autoPublishArticles + ? "Yes" + : "No" + }
Auto Publish
@@ -413,7 +432,7 @@ function TenantSettingsContentTable() { {step.stepOrder}
-
{step.stepName}
+
{step.stepName}
{step.conditionType && `Condition: ${step.conditionType}`} diff --git a/app/[locale]/auth/page.tsx b/app/[locale]/auth/page.tsx index 99325bc..be989f3 100644 --- a/app/[locale]/auth/page.tsx +++ b/app/[locale]/auth/page.tsx @@ -70,7 +70,9 @@ const AuthPage = () => { const handleOTPSuccess = async () => { if (loginCredentials) { try { - await login(loginCredentials); + await login(loginCredentials, { skipRedirect: false }); + + // await login(loginCredentials); } catch (error: any) { toast.error(error.message || "Login failed after OTP verification"); } diff --git a/components/auth/login-form.tsx b/components/auth/login-form.tsx index 431d574..2b152cc 100644 --- a/components/auth/login-form.tsx +++ b/components/auth/login-form.tsx @@ -28,7 +28,7 @@ export const LoginForm: React.FC = ({ const { login } = useAuth(); const t = useTranslations("MediaUpdate"); const [showPassword, setShowPassword] = useState(false); - const [rememberMe, setRememberMe] = useState(true); + const [rememberMe, setRememberMe] = useState(false); const [roles, setRoles] = useState([]); const [selectedCategory, setSelectedCategory] = useState("5"); const [isDialogOpen, setIsDialogOpen] = useState(false); @@ -62,7 +62,8 @@ export const LoginForm: React.FC = ({ const handleLogin = async (data: LoginFormData) => { try { - await login(data); + await login(data, { skipRedirect: true }); + // await login(data); onSuccess?.(data); } catch (error: any) { const message = getLoginErrorMessage(error); @@ -72,7 +73,6 @@ export const LoginForm: React.FC = ({ const onSubmit = async (data: LoginFormData) => { try { - // onSuccess?.(data); await handleLogin(data); } catch (error: any) { @@ -193,6 +193,20 @@ export const LoginForm: React.FC = ({ {/* Remember Me and Forgot Password */}
+ setRememberMe(e.target.checked)} + disabled={isSubmitting} + className="h-4 w-4 rounded border-gray-300 text-primary focus:ring-primary" + /> + +
+ + {/*
= ({ -
+
*/} = ({ const [otpValue, setOtpValue] = useState(""); const t = useTranslations("MediaUpdate"); + const handleTypeOTP = (event: React.KeyboardEvent) => { const { key } = event; const target = event.currentTarget; @@ -57,9 +58,12 @@ export const OTPForm: React.FC = ({ try { const isValid = await verifyOTP(loginCredentials.username, otpValue); + + if (isValid) { onSuccess?.(); - } else { + } + else { onError?.("Invalid OTP code"); } } catch (error: any) { @@ -154,7 +158,6 @@ export const OTPForm: React.FC = ({ {loading ? (
-
) : ( t("enterOTP4") diff --git a/components/form/ApprovalWorkflowForm.tsx b/components/form/ApprovalWorkflowForm.tsx index a2f5eb7..81039cf 100644 --- a/components/form/ApprovalWorkflowForm.tsx +++ b/components/form/ApprovalWorkflowForm.tsx @@ -33,6 +33,18 @@ interface ApprovalWorkflowFormProps { isLoading?: boolean; } +const normalizeClientSettings = (settings: ClientApprovalSettingsRequest) => ({ + approvalExemptCategories: settings.approvalExemptCategories ?? [], + approvalExemptRoles: settings.approvalExemptRoles ?? [], + approvalExemptUsers: settings.approvalExemptUsers ?? [], + requireApprovalFor: settings.requireApprovalFor ?? [], + skipApprovalFor: settings.skipApprovalFor ?? [], + + autoPublishArticles: settings.autoPublishArticles ?? false, + requiresApproval: settings.requiresApproval ?? false, + isActive: settings.isActive ?? false, +}); + export const ApprovalWorkflowForm: React.FC = ({ initialData, workflowId, @@ -41,31 +53,34 @@ export const ApprovalWorkflowForm: React.FC = ({ isLoading = false, }) => { // Form state - const [formData, setFormData] = useState({ - name: "", - description: "", - isActive: true, - isDefault: true, - requiresApproval: true, - autoPublish: false, - steps: [], - clientApprovalSettings: { - requiresApproval: true, - autoPublishArticles: false, - approvalExemptUsers: [], - approvalExemptRoles: [], - approvalExemptCategories: [], - requireApprovalFor: [], - skipApprovalFor: [], + const [formData, setFormData] = + useState({ + name: "", + description: "", isActive: true, - }, - }); + isDefault: true, + requiresApproval: true, + autoPublish: false, + steps: [], + clientApprovalSettings: { + requiresApproval: true, + autoPublishArticles: false, + approvalExemptUsers: [], + approvalExemptRoles: [], + approvalExemptCategories: [], + requireApprovalFor: [], + skipApprovalFor: [], + isActive: true, + }, + }); // API data const [userLevels, setUserLevels] = useState([]); const [users, setUsers] = useState([]); const [userRoles, setUserRoles] = useState([]); - const [articleCategories, setArticleCategories] = useState([]); + const [articleCategories, setArticleCategories] = useState( + [], + ); // UI state const [errors, setErrors] = useState>({}); @@ -76,25 +91,28 @@ export const ApprovalWorkflowForm: React.FC = ({ // Get available user levels for a specific step (excluding already selected ones) const getAvailableUserLevels = (currentStepIndex: number) => { const usedLevelIds = new Set(); - + // Collect all user level IDs that are already used by other steps formData.steps.forEach((step, stepIndex) => { if (stepIndex !== currentStepIndex && step.conditionValue) { try { const conditionData = JSON.parse(step.conditionValue); - if (conditionData.applies_to_levels && Array.isArray(conditionData.applies_to_levels)) { + if ( + conditionData.applies_to_levels && + Array.isArray(conditionData.applies_to_levels) + ) { conditionData.applies_to_levels.forEach((levelId: number) => { usedLevelIds.add(levelId); }); } } catch (error) { - console.error('Error parsing conditionValue:', error); + console.error("Error parsing conditionValue:", error); } } }); - + // Filter out used levels and return available ones - return userLevels.filter(level => !usedLevelIds.has(level.id)); + return userLevels.filter((level) => !usedLevelIds.has(level.id)); }; // Load initial data @@ -108,17 +126,20 @@ export const ApprovalWorkflowForm: React.FC = ({ useEffect(() => { const loadData = async () => { try { - const [userLevelsRes, usersRes, userRolesRes, categoriesRes] = await Promise.all([ - getUserLevels(), - getUsers(), - getUserRoles(), - getArticleCategories(), - ]); + const [userLevelsRes, usersRes, userRolesRes, categoriesRes] = + await Promise.all([ + getUserLevels(), + getUsers(), + getUserRoles(), + getArticleCategories(), + ]); - if (!userLevelsRes?.error) setUserLevels(userLevelsRes?.data?.data || []); + if (!userLevelsRes?.error) + setUserLevels(userLevelsRes?.data?.data || []); if (!usersRes?.error) setUsers(usersRes?.data || []); if (!userRolesRes?.error) setUserRoles(userRolesRes?.data || []); - if (!categoriesRes?.error) setArticleCategories(categoriesRes?.data || []); + if (!categoriesRes?.error) + setArticleCategories(categoriesRes?.data || []); } catch (error) { console.error("Error loading form data:", error); } finally { @@ -155,10 +176,12 @@ export const ApprovalWorkflowForm: React.FC = ({ newErrors[`steps.${index}.stepName`] = "Step name is required"; } if (!step.requiredUserLevelId) { - newErrors[`steps.${index}.requiredUserLevelId`] = "Required user level is required"; + newErrors[`steps.${index}.requiredUserLevelId`] = + "Required user level is required"; } if (step.stepOrder <= 0) { - newErrors[`steps.${index}.stepOrder`] = "Step order must be greater than 0"; + newErrors[`steps.${index}.stepOrder`] = + "Step order must be greater than 0"; } }); @@ -167,10 +190,13 @@ export const ApprovalWorkflowForm: React.FC = ({ }; // Form handlers - const handleBasicInfoChange = (field: keyof CreateApprovalWorkflowWithClientSettingsRequest, value: any) => { - setFormData(prev => ({ ...prev, [field]: value })); + const handleBasicInfoChange = ( + field: keyof CreateApprovalWorkflowWithClientSettingsRequest, + value: any, + ) => { + setFormData((prev) => ({ ...prev, [field]: value })); if (errors[field]) { - setErrors(prev => ({ ...prev, [field]: "" })); + setErrors((prev) => ({ ...prev, [field]: "" })); } }; @@ -188,17 +214,26 @@ export const ApprovalWorkflowForm: React.FC = ({ // Keep existing stepOrder if manually set return step; }); - - setFormData(prev => ({ ...prev, steps: updatedSteps })); + + setFormData((prev) => ({ ...prev, steps: updatedSteps })); }; - const renderStepForm = (step: ApprovalWorkflowStepRequest, index: number, onUpdate: (step: ApprovalWorkflowStepRequest) => void, onDelete: () => void) => { - const stepErrors = Object.keys(errors).filter(key => key.startsWith(`steps.${index}`)); - + const renderStepForm = ( + step: ApprovalWorkflowStepRequest, + index: number, + onUpdate: (step: ApprovalWorkflowStepRequest) => void, + onDelete: () => void, + ) => { + const stepErrors = Object.keys(errors).filter((key) => + key.startsWith(`steps.${index}`), + ); + // Check if this step has parallel steps (same stepOrder) - const parallelSteps = formData.steps.filter((s, i) => s.stepOrder === step.stepOrder && i !== index); + const parallelSteps = formData.steps.filter( + (s, i) => s.stepOrder === step.stepOrder && i !== index, + ); const isParallelStep = parallelSteps.length > 0; - + return (
{/* Parallel Step Indicator */} @@ -222,7 +257,12 @@ export const ApprovalWorkflowForm: React.FC = ({ type="number" placeholder="1" value={step.stepOrder} - onChange={(value) => onUpdate({ ...step, stepOrder: value ? Number(value) : index + 1 })} + onChange={(value) => + onUpdate({ + ...step, + stepOrder: value ? Number(value) : index + 1, + }) + } error={errors[`steps.${index}.stepOrder`]} min={1} helpText="Same order = parallel steps" @@ -243,17 +283,31 @@ export const ApprovalWorkflowForm: React.FC = ({ label="Required User Level" name={`requiredUserLevelId-${index}`} type="select" - placeholder={userLevels.length > 0 ? "Select user level" : "No user levels available"} + placeholder={ + userLevels.length > 0 + ? "Select user level" + : "No user levels available" + } value={step.requiredUserLevelId} - onChange={(value) => onUpdate({ ...step, requiredUserLevelId: Number(value) })} + onChange={(value) => + onUpdate({ ...step, requiredUserLevelId: Number(value) }) + } error={errors[`steps.${index}.requiredUserLevelId`]} - options={userLevels.length > 0 ? userLevels.map(level => ({ - value: level.id, - label: `${level.name} (Level ${level.levelNumber})`, - })) : []} + options={ + userLevels.length > 0 + ? userLevels.map((level) => ({ + value: level.id, + label: `${level.name} (Level ${level.levelNumber})`, + })) + : [] + } required disabled={userLevels.length === 0} - helpText={userLevels.length === 0 ? "No user levels found. Please create user levels first." : undefined} + helpText={ + userLevels.length === 0 + ? "No user levels found. Please create user levels first." + : undefined + } />
@@ -264,7 +318,12 @@ export const ApprovalWorkflowForm: React.FC = ({ type="number" placeholder="Leave empty for manual approval" value={step.autoApproveAfterHours} - onChange={(value) => onUpdate({ ...step, autoApproveAfterHours: value ? Number(value) : undefined })} + onChange={(value) => + onUpdate({ + ...step, + autoApproveAfterHours: value ? Number(value) : undefined, + }) + } helpText="Automatically approve after specified hours" min={1} /> @@ -277,7 +336,7 @@ export const ApprovalWorkflowForm: React.FC = ({ value={step.canSkip || false} onChange={(value) => onUpdate({ ...step, canSkip: value })} /> - + = ({ label="Applies to User Levels" placeholder={(() => { const availableLevels = getAvailableUserLevels(index); - return availableLevels.length > 0 ? "Select user levels..." : "No available user levels"; + return availableLevels.length > 0 + ? "Select user levels..." + : "No available user levels"; })()} options={(() => { const availableLevels = getAvailableUserLevels(index); - return availableLevels.map(level => ({ + return availableLevels.map((level) => ({ value: level.id, label: `${level.name} (Level ${level.levelNumber})`, })); })()} value={(() => { try { - return step.conditionValue ? JSON.parse(step.conditionValue).applies_to_levels || [] : []; + return step.conditionValue + ? JSON.parse(step.conditionValue).applies_to_levels || [] + : []; } catch { return []; } })()} onChange={(value) => { - const conditionValue = JSON.stringify({ applies_to_levels: value }); - onUpdate({ ...step, conditionType: "user_level_hierarchy", conditionValue }); + const conditionValue = JSON.stringify({ + applies_to_levels: value, + }); + onUpdate({ + ...step, + conditionType: "user_level_hierarchy", + conditionValue, + }); }} searchable={true} disabled={getAvailableUserLevels(index).length === 0} helpText={(() => { const availableLevels = getAvailableUserLevels(index); const usedLevels = userLevels.length - availableLevels.length; - + if (availableLevels.length === 0) { return "All user levels are already assigned to other steps"; } else if (usedLevels > 0) { @@ -334,9 +403,13 @@ export const ApprovalWorkflowForm: React.FC = ({ ); }; + function normalizeBoolean(value?: boolean): boolean { + return value ?? false; + } + const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); - + if (!validateForm()) { Swal.fire({ title: "Validation Error", @@ -344,14 +417,14 @@ export const ApprovalWorkflowForm: React.FC = ({ icon: "error", confirmButtonText: "OK", customClass: { - popup: 'swal-z-index-9999' - } + popup: "swal-z-index-9999", + }, }); return; } setIsSubmitting(true); - + try { // Hardcoded client approval settings const hardcodedClientSettings = { @@ -362,7 +435,23 @@ export const ApprovalWorkflowForm: React.FC = ({ isActive: true, requireApprovalFor: [], requiresApproval: true, - skipApprovalFor: [] + skipApprovalFor: [], + }; + + const clientSettingsPayload = { + approvalExemptCategories: [], + approvalExemptRoles: [], + approvalExemptUsers: [], + requireApprovalFor: [], + skipApprovalFor: [], + + autoPublishArticles: + formData.clientApprovalSettings.autoPublishArticles ?? false, + + requiresApproval: + formData.clientApprovalSettings.requiresApproval ?? false, + + isActive: formData.clientApprovalSettings.isActive ?? false, }; if (workflowId) { @@ -371,30 +460,60 @@ export const ApprovalWorkflowForm: React.FC = ({ workflowId, name: formData.name, description: formData.description, - isActive: formData.isActive || false, - isDefault: formData.isDefault || false, - steps: formData.steps.map(step => ({ + + isActive: normalizeBoolean(formData.isActive), + isDefault: normalizeBoolean(formData.isDefault), + + steps: formData.steps.map((step) => ({ ...step, - branchName: step.stepName, // branchName should be same as stepName + branchName: step.stepName, })), - clientSettings: hardcodedClientSettings + + clientSettings: { + approvalExemptCategories: [], + approvalExemptRoles: [], + approvalExemptUsers: [], + requireApprovalFor: [], + skipApprovalFor: [], + + // 🔥 AMBIL LANGSUNG DARI CHECKBOX UI + requiresApproval: normalizeBoolean(formData.requiresApproval), + autoPublishArticles: normalizeBoolean(formData.autoPublish), + isActive: normalizeBoolean(formData.isActive), + }, }; + // const updateData: UpdateApprovalWorkflowWithClientSettingsRequest = { + // workflowId, + // name: formData.name, + // description: formData.description, + // isActive: formData.isActive, + // isDefault: formData.isDefault, + // steps: formData.steps.map(step => ({ + // ...step, + // branchName: step.stepName, // branchName should be same as stepName + // })), + // clientSettings: hardcodedClientSettings + // }; + console.log("Update Data: ", updateData); - const response = await updateApprovalWorkflowWithClientSettings(updateData); - + const response = + await updateApprovalWorkflowWithClientSettings(updateData); + console.log("Update Response: ", response); if (response?.error) { Swal.fire({ title: "Error", - text: response?.message?.messages?.[0] || "Failed to update approval workflow", + text: + response?.message?.messages?.[0] || + "Failed to update approval workflow", icon: "error", confirmButtonText: "OK", customClass: { - popup: 'swal-z-index-9999' - } + popup: "swal-z-index-9999", + }, }); } else { Swal.fire({ @@ -403,8 +522,8 @@ export const ApprovalWorkflowForm: React.FC = ({ icon: "success", confirmButtonText: "OK", customClass: { - popup: 'swal-z-index-9999' - } + popup: "swal-z-index-9999", + }, }).then(() => { // Call onSave to trigger parent refresh if (onSave) { @@ -416,24 +535,27 @@ export const ApprovalWorkflowForm: React.FC = ({ // Create mode const submitData = { ...formData, - clientApprovalSettings: hardcodedClientSettings + clientApprovalSettings: hardcodedClientSettings, }; console.log("Create Data: ", submitData); - const response = await createApprovalWorkflowWithClientSettings(submitData); - + const response = + await createApprovalWorkflowWithClientSettings(submitData); + console.log("Create Response: ", response); if (response?.error) { Swal.fire({ title: "Error", - text: response?.message?.messages?.[0] || "Failed to create approval workflow", + text: + response?.message?.messages?.[0] || + "Failed to create approval workflow", icon: "error", confirmButtonText: "OK", customClass: { - popup: 'swal-z-index-9999' - } + popup: "swal-z-index-9999", + }, }); } else { Swal.fire({ @@ -442,8 +564,8 @@ export const ApprovalWorkflowForm: React.FC = ({ icon: "success", confirmButtonText: "OK", customClass: { - popup: 'swal-z-index-9999' - } + popup: "swal-z-index-9999", + }, }).then(() => { // Call onSave to trigger parent refresh if (onSave) { @@ -460,8 +582,8 @@ export const ApprovalWorkflowForm: React.FC = ({ icon: "error", confirmButtonText: "OK", customClass: { - popup: 'swal-z-index-9999' - } + popup: "swal-z-index-9999", + }, }); } finally { setIsSubmitting(false); @@ -477,8 +599,8 @@ export const ApprovalWorkflowForm: React.FC = ({ confirmButtonText: "Yes, reset", cancelButtonText: "Cancel", customClass: { - popup: 'swal-z-index-9999' - } + popup: "swal-z-index-9999", + }, }).then((result) => { if (result.isConfirmed) { setFormData({ @@ -513,12 +635,18 @@ export const ApprovalWorkflowForm: React.FC = ({ Loading form data...
)} - + - Basic Information - Workflow Steps - Client Settings + + Basic Information + + + Workflow Steps + + + Client Settings + {/* Basic Information Tab */} @@ -545,7 +673,9 @@ export const ApprovalWorkflowForm: React.FC = ({ type="textarea" placeholder="Describe the purpose and process of this workflow" value={formData.description} - onChange={(value) => handleBasicInfoChange("description", value)} + onChange={(value) => + handleBasicInfoChange("description", value) + } error={errors.description} required rows={4} @@ -565,7 +695,9 @@ export const ApprovalWorkflowForm: React.FC = ({ name="isDefault" type="checkbox" value={formData.isDefault} - onChange={(value) => handleBasicInfoChange("isDefault", value)} + onChange={(value) => + handleBasicInfoChange("isDefault", value) + } /> = ({ name="requiresApproval" type="checkbox" value={formData.requiresApproval} - onChange={(value) => handleBasicInfoChange("requiresApproval", value)} + onChange={(value) => + handleBasicInfoChange("requiresApproval", value) + } /> = ({ name="autoPublish" type="checkbox" value={formData.autoPublish} - onChange={(value) => handleBasicInfoChange("autoPublish", value)} + onChange={(value) => + handleBasicInfoChange("autoPublish", value) + } />
@@ -595,14 +731,22 @@ export const ApprovalWorkflowForm: React.FC = ({ Workflow Steps Configuration
- {formData.steps.length} step{formData.steps.length !== 1 ? 's' : ''} + {formData.steps.length} step + {formData.steps.length !== 1 ? "s" : ""} {(() => { - const parallelGroups = formData.steps.reduce((acc, step) => { - acc[step.stepOrder] = (acc[step.stepOrder] || 0) + 1; - return acc; - }, {} as Record); - const parallelCount = Object.values(parallelGroups).filter(count => count > 1).length; - return parallelCount > 0 ? ` • ${parallelCount} parallel group${parallelCount !== 1 ? 's' : ''}` : ''; + const parallelGroups = formData.steps.reduce( + (acc, step) => { + acc[step.stepOrder] = (acc[step.stepOrder] || 0) + 1; + return acc; + }, + {} as Record, + ); + const parallelCount = Object.values(parallelGroups).filter( + (count) => count > 1, + ).length; + return parallelCount > 0 + ? ` • ${parallelCount} parallel group${parallelCount !== 1 ? "s" : ""}` + : ""; })()}
@@ -636,21 +780,44 @@ export const ApprovalWorkflowForm: React.FC = ({
⚙️
-

Settings Pre-configured

+

+ Settings Pre-configured +

- Client approval settings are automatically configured with optimal defaults. + Client approval settings are automatically configured with + optimal defaults.

- +
-

Default Settings:

+

+ Default Settings: +

    -
  • • Requires Approval: Yes
  • -
  • • Auto Publish Articles: Yes
  • -
  • • Is Active: Yes
  • -
  • • Exempt Users: None
  • -
  • • Exempt Roles: None
  • -
  • • Exempt Categories: None
  • +
  • + • Requires Approval:{" "} + Yes +
  • +
  • + • Auto Publish Articles:{" "} + Yes +
  • +
  • + • Is Active:{" "} + Yes +
  • +
  • + • Exempt Users:{" "} + None +
  • +
  • + • Exempt Roles:{" "} + None +
  • +
  • + • Exempt Categories:{" "} + None +
@@ -684,7 +851,7 @@ export const ApprovalWorkflowForm: React.FC = ({ Cancel )} - +
diff --git a/components/loader.tsx b/components/loader.tsx index aeb8123..b09a3b3 100644 --- a/components/loader.tsx +++ b/components/loader.tsx @@ -12,7 +12,7 @@ const Loader = () => {
{/* */} { }; return ( -
+
{ }, []); const login = useCallback( - async (credentials: LoginFormData): Promise => { + async ( + credentials: LoginFormData, + options?: { skipRedirect?: boolean }, + ): Promise => { try { setState((prev) => ({ ...prev, loading: true, error: null })); // Check rate limiting if (!loginRateLimiter.canAttempt(credentials.username)) { const remainingTime = loginRateLimiter.getRemainingTime( - credentials.username + credentials.username, ); const minutes = Math.ceil(remainingTime / (60 * 1000)); throw new Error( - `Too many login attempts. Please try again in ${minutes} minutes.` + `Too many login attempts. Please try again in ${minutes} minutes.`, ); } @@ -119,10 +122,14 @@ export const useAuth = (): AuthContextType => { Cookies.set("time_refresh", newTime, { expires: 1, }); - if (response?.data?.data?.approvalWorkflowInfo?.hasWorkflowSetup) { - Cookies.set("default_workflow", response?.data?.data?.approvalWorkflowInfo?.defaultWorkflowId, { - expires: 1, - }); + if (response?.data?.data?.approvalWorkflowInfo?.hasWorkflowSetup) { + Cookies.set( + "default_workflow", + response?.data?.data?.approvalWorkflowInfo?.defaultWorkflowId, + { + expires: 1, + }, + ); } Cookies.set("is_first_login", "true", { @@ -176,12 +183,20 @@ export const useAuth = (): AuthContextType => { // Reset rate limiter on successful login loginRateLimiter.resetAttempts(credentials.username); - - if (profile?.userRoleId === 4 || profile?.userRoleId === 5) { - router.push("/"); - } else { - router.push("/admin/dashboard"); + + if (!options?.skipRedirect) { + if (profile?.userRoleId === 4 || profile?.userRoleId === 5) { + router.push("/"); + } else { + router.push("/admin/dashboard"); + } } + + // if (profile?.userRoleId === 4 || profile?.userRoleId === 5) { + // router.push("/"); + // } else { + // router.push("/admin/dashboard"); + // } } catch (error: any) { const errorMessage = error?.message || "Login failed"; setState((prev) => ({ @@ -192,7 +207,7 @@ export const useAuth = (): AuthContextType => { showAuthError(error, "Login failed"); } }, - [router] + [router], ); const logout = useCallback((): void => { @@ -266,7 +281,7 @@ export const useEmailValidation = () => { setLoading(false); } }, - [] + [], ); return { @@ -284,7 +299,7 @@ export const useEmailSetup = () => { const setupEmail = useCallback( async ( credentials: LoginFormData, - emailData: EmailValidationData + emailData: EmailValidationData, ): Promise => { try { setLoading(true); @@ -322,7 +337,7 @@ export const useEmailSetup = () => { setLoading(false); } }, - [] + [], ); return { @@ -349,7 +364,7 @@ export const useOTPVerification = () => { const data = { username: username, otpCode: otp, - } + }; const response = await verifyOTPByUsername(data); if (response?.error) { @@ -366,7 +381,7 @@ export const useOTPVerification = () => { setLoading(false); } }, - [] + [], ); return { diff --git a/types/auth.ts b/types/auth.ts index f3f1c36..f455965 100644 --- a/types/auth.ts +++ b/types/auth.ts @@ -53,7 +53,7 @@ export interface ProfileData { fullname: string; email: string; roleId: number; - userRoleId:number; + userRoleId: number; role: { name: string; }; @@ -131,7 +131,10 @@ export interface AuthState { } export interface AuthContextType extends AuthState { - login: (credentials: LoginFormData) => Promise; + login: ( + credentials: LoginFormData, + options?: { skipRedirect?: boolean }, + ) => Promise; logout: () => void; refreshToken: () => Promise; } @@ -171,4 +174,4 @@ export interface AuthCookies { uinse: string; // user institute id encrypted status: string; username: string; -} \ No newline at end of file +}