Extract admin dashboard from ghabilee-frontend2 into a dedicated Next.js app for backoffice.ghabilee.ir (no SEO indexing / Clarity).
210 lines
4.8 KiB
TypeScript
210 lines
4.8 KiB
TypeScript
import type React from 'react'
|
|
|
|
import type { AlertModalContextType, ShowAlertOptions } from '@/types/alertModal'
|
|
import type { ApiWithParams, PaginationListColumnType } from '@/types/pagination'
|
|
|
|
// ==================== Route & Navigation Types ====================
|
|
interface SidebarRoute {
|
|
title?: string
|
|
icon?: (className?: string) => React.ReactNode
|
|
link?: string
|
|
subLink?: string
|
|
matchPaths?: string[]
|
|
children?: SidebarRoute[]
|
|
target?: string
|
|
}
|
|
|
|
// ==================== Project Types ====================
|
|
interface Project {
|
|
id: string
|
|
image: string
|
|
projectName: string
|
|
city: string
|
|
startDate: number
|
|
endDate: number
|
|
progressPlan: number
|
|
progressReal: number
|
|
contractAmount: number
|
|
customerName: string
|
|
contractorName: string
|
|
location?: {
|
|
lat: number
|
|
lng: number
|
|
}
|
|
}
|
|
|
|
interface WBSItem {
|
|
id: string
|
|
name: string
|
|
type: 'branch' | 'activity'
|
|
weight?: number
|
|
budget?: number
|
|
children?: WBSItem[]
|
|
}
|
|
|
|
// ==================== Auth Types ====================
|
|
interface SendOtpData {
|
|
mobile: string
|
|
}
|
|
|
|
interface CheckOtpData {
|
|
mobile: string
|
|
code: string
|
|
termsAccepted?: boolean
|
|
}
|
|
|
|
interface User {
|
|
accessToken: string
|
|
userId: string
|
|
AccessTokenExpireTime: number
|
|
refreshTokenExpireTime?: number
|
|
role?: 'user' | 'admin'
|
|
sessionId?: string
|
|
status?: UserAccountStatus
|
|
avatarUrl?: string | null
|
|
imageId?: string | null
|
|
gender?: UserGender | null
|
|
firstName?: string | null
|
|
lastName?: string | null
|
|
mobile?: string | null
|
|
cityId?: number | null
|
|
}
|
|
|
|
interface SaveUserData {
|
|
accessToken: string
|
|
sessionId?: string
|
|
expiresAt?: string
|
|
status?: UserAccountStatus
|
|
}
|
|
|
|
interface AuthContextType {
|
|
user: User | null
|
|
/** True after the first localStorage session sync — not the same as logged-in. */
|
|
isSessionHydrated: boolean
|
|
sendLoginOtp: (data: SendOtpData) => Promise<{
|
|
purpose: 'login' | 'register'
|
|
expiresIn: number
|
|
resendIn: number
|
|
alreadySent: boolean
|
|
}>
|
|
checkLoginOtp: (data: CheckOtpData) => Promise<UserAccountStatus | undefined>
|
|
completeProfile: (data: CompleteProfileData) => Promise<void>
|
|
logout: () => Promise<void>
|
|
saveUser: (data: SaveUserData) => void
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
updateUserFromOutside: (data: any) => void
|
|
}
|
|
|
|
interface CompleteProfileData {
|
|
firstName: string
|
|
lastName: string
|
|
gender: UserGender
|
|
dateOfBirth: string
|
|
cityId: number
|
|
}
|
|
|
|
// ==================== Global Context Types ====================
|
|
export interface StatusType {
|
|
code: string | number | boolean | null
|
|
name: string
|
|
color?: string
|
|
icon?: React.ReactNode
|
|
}
|
|
|
|
interface DataState {
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
data: any
|
|
navbar: {
|
|
title: string
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
[key: string]: any
|
|
}
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
[key: string]: any
|
|
}
|
|
|
|
interface GlobalContextType {
|
|
data: DataState
|
|
activeRoute: SidebarRoute | undefined
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
setData: (section: string, value: any) => void
|
|
getDataByCode: (section: string, code: string) => StatusType | undefined
|
|
reset: () => void
|
|
}
|
|
|
|
// ==================== Loading Context Types ====================
|
|
interface LoadingContextType {
|
|
loading: boolean
|
|
setLoading: (loading: boolean) => void
|
|
}
|
|
|
|
// ==================== Axios Types ====================
|
|
interface UserStorageData {
|
|
accessToken: string
|
|
userId: string
|
|
AccessTokenExpireTime: number
|
|
refreshTokenExpireTime?: number
|
|
role?: 'user' | 'admin'
|
|
sessionId?: string
|
|
}
|
|
|
|
interface DecodedToken {
|
|
exp: number
|
|
sub: string
|
|
sessionId?: string
|
|
role?: 'user' | 'admin'
|
|
/** @deprecated Legacy token claim */
|
|
u_id?: string
|
|
}
|
|
|
|
// ==================== Domain User Types ====================
|
|
type UserRole = 'user' | 'admin'
|
|
type UserAccountStatus = 'active' | 'pending' | 'suspended' | 'deleted'
|
|
type IdentityStatus = 'none' | 'pending' | 'verified' | 'rejected'
|
|
type UserGender = 'male' | 'female' | 'other'
|
|
|
|
interface AdminUserListItem {
|
|
id: string
|
|
mobile: string
|
|
firstName: string
|
|
lastName: string
|
|
gender: UserGender
|
|
cityId?: number | null
|
|
avatarUrl?: string | null
|
|
bio?: string | null
|
|
status: UserAccountStatus
|
|
identityStatus: IdentityStatus
|
|
role: UserRole
|
|
mobileVerifiedAt?: string | null
|
|
lastLoginAt?: string | null
|
|
createdAt: string
|
|
updatedAt: string
|
|
}
|
|
|
|
export type {
|
|
AdminUserListItem,
|
|
AlertModalContextType,
|
|
ApiWithParams,
|
|
AuthContextType,
|
|
CheckOtpData,
|
|
CompleteProfileData,
|
|
DataState,
|
|
DecodedToken,
|
|
GlobalContextType,
|
|
IdentityStatus,
|
|
LoadingContextType,
|
|
PaginationListColumnType,
|
|
Project,
|
|
SaveUserData,
|
|
SendOtpData,
|
|
ShowAlertOptions,
|
|
SidebarRoute,
|
|
User,
|
|
UserAccountStatus,
|
|
UserGender,
|
|
UserRole,
|
|
UserStorageData,
|
|
WBSItem,
|
|
}
|