2026-02-24 20:44:16 +00:00
|
|
|
|
import {
|
|
|
|
|
|
Button,
|
|
|
|
|
|
Checkbox,
|
|
|
|
|
|
DatePicker,
|
|
|
|
|
|
FormContainer,
|
|
|
|
|
|
FormItem,
|
|
|
|
|
|
Input,
|
|
|
|
|
|
Notification,
|
|
|
|
|
|
Select,
|
|
|
|
|
|
Tabs,
|
|
|
|
|
|
toast,
|
2026-05-27 22:30:13 +00:00
|
|
|
|
Upload,
|
2026-02-24 20:44:16 +00:00
|
|
|
|
} from '@/components/ui'
|
|
|
|
|
|
import Dialog from '@/components/ui/Dialog'
|
|
|
|
|
|
import DateTimepicker from '@/components/ui/DatePicker/DateTimepicker'
|
|
|
|
|
|
import Table from '@/components/ui/Table'
|
|
|
|
|
|
import TBody from '@/components/ui/Table/TBody'
|
|
|
|
|
|
import Td from '@/components/ui/Table/Td'
|
|
|
|
|
|
import Th from '@/components/ui/Table/Th'
|
|
|
|
|
|
import THead from '@/components/ui/Table/THead'
|
|
|
|
|
|
import Tr from '@/components/ui/Table/Tr'
|
|
|
|
|
|
import TabContent from '@/components/ui/Tabs/TabContent'
|
|
|
|
|
|
import TabList from '@/components/ui/Tabs/TabList'
|
|
|
|
|
|
import TabNav from '@/components/ui/Tabs/TabNav'
|
|
|
|
|
|
import {
|
|
|
|
|
|
deleteClaimUser,
|
|
|
|
|
|
getUserDetail,
|
|
|
|
|
|
postClaimUser,
|
|
|
|
|
|
putUserDetail,
|
|
|
|
|
|
putUserLookout,
|
2026-05-04 14:35:18 +00:00
|
|
|
|
putUserPermission,
|
2026-02-24 20:44:16 +00:00
|
|
|
|
} from '@/services/identity.service'
|
2026-05-27 22:30:13 +00:00
|
|
|
|
import { updateProfile } from '@/services/account.service'
|
2026-05-05 07:23:02 +00:00
|
|
|
|
import { CountryDto, getCountry } from '@/services/home.service'
|
2026-02-24 20:44:16 +00:00
|
|
|
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
|
|
|
|
|
import dayjs from 'dayjs'
|
|
|
|
|
|
import { Field, FieldArray, FieldProps, Form, Formik, FormikHelpers } from 'formik'
|
2026-05-27 22:30:13 +00:00
|
|
|
|
import { useEffect, useRef, useState } from 'react'
|
2026-02-24 20:44:16 +00:00
|
|
|
|
import { Helmet } from 'react-helmet'
|
2026-05-05 07:23:02 +00:00
|
|
|
|
import {
|
|
|
|
|
|
FaBuilding,
|
|
|
|
|
|
FaLockOpen,
|
|
|
|
|
|
FaUser,
|
|
|
|
|
|
FaFileAlt,
|
|
|
|
|
|
FaTrashAlt,
|
|
|
|
|
|
FaCheckCircle,
|
|
|
|
|
|
FaUserAstronaut,
|
2026-05-27 22:30:13 +00:00
|
|
|
|
FaEnvelope,
|
|
|
|
|
|
FaPhone,
|
|
|
|
|
|
FaUserCircle,
|
|
|
|
|
|
FaFacebookMessenger,
|
|
|
|
|
|
FaHome,
|
|
|
|
|
|
FaUniversity,
|
|
|
|
|
|
FaCalendarAlt,
|
|
|
|
|
|
FaBriefcase,
|
|
|
|
|
|
FaIdCard,
|
|
|
|
|
|
FaMapMarkerAlt,
|
|
|
|
|
|
FaCity,
|
|
|
|
|
|
FaBook,
|
|
|
|
|
|
FaHashtag,
|
|
|
|
|
|
FaMapPin,
|
|
|
|
|
|
FaUserTie,
|
|
|
|
|
|
FaFemale,
|
|
|
|
|
|
FaHeart,
|
|
|
|
|
|
FaExclamationTriangle,
|
|
|
|
|
|
FaUsers,
|
|
|
|
|
|
FaPlus,
|
2026-05-05 07:23:02 +00:00
|
|
|
|
} from 'react-icons/fa'
|
2026-05-27 22:30:13 +00:00
|
|
|
|
import {
|
|
|
|
|
|
CircleStencil,
|
|
|
|
|
|
Cropper,
|
|
|
|
|
|
CropperPreview,
|
|
|
|
|
|
CropperPreviewRef,
|
|
|
|
|
|
CropperRef,
|
|
|
|
|
|
} from 'react-advanced-cropper'
|
|
|
|
|
|
import 'react-advanced-cropper/dist/style.css'
|
2026-02-24 20:44:16 +00:00
|
|
|
|
import { useParams } from 'react-router-dom'
|
|
|
|
|
|
import * as Yup from 'yup'
|
2026-05-04 14:35:18 +00:00
|
|
|
|
import { SelectBoxOption, SelectBoxOptionWithGroup } from '@/types/shared'
|
2026-05-27 22:30:13 +00:00
|
|
|
|
import { AdaptableCard, ConfirmDialog, Container } from '@/components/shared'
|
2026-02-24 20:44:16 +00:00
|
|
|
|
import { AssignedClaimViewModel, UserInfoViewModel } from '@/proxy/admin/models'
|
2026-05-27 22:30:13 +00:00
|
|
|
|
import { APP_NAME, AVATAR_URL } from '@/constants/app.constant'
|
|
|
|
|
|
import { useStoreActions, useStoreState } from '@/store'
|
2026-06-03 14:43:41 +00:00
|
|
|
|
import { useSetting } from '@/utils/hooks/useSetting'
|
2026-02-24 20:44:16 +00:00
|
|
|
|
|
|
|
|
|
|
export interface ClaimTypeDto {
|
|
|
|
|
|
claimType: string
|
|
|
|
|
|
claimValue: string
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function UserDetails() {
|
|
|
|
|
|
const { userId } = useParams()
|
|
|
|
|
|
const { translate } = useLocalization()
|
|
|
|
|
|
const [userDetails, setUserDetails] = useState<UserInfoViewModel>()
|
|
|
|
|
|
const [loading, setLoading] = useState(true)
|
|
|
|
|
|
const [open, setOpen] = useState(false)
|
|
|
|
|
|
const [confirmDeleteClaim, setConfirmDeleteClaim] = useState<AssignedClaimViewModel | null>(null)
|
2026-05-05 07:23:02 +00:00
|
|
|
|
const [countries, setCountries] = useState<CountryDto[]>([])
|
2026-05-27 22:30:13 +00:00
|
|
|
|
const [image, setImage] = useState<string | undefined>()
|
|
|
|
|
|
const cropperRef = useRef<CropperRef>(null)
|
|
|
|
|
|
const previewRef = useRef<CropperPreviewRef>(null)
|
|
|
|
|
|
const auth = useStoreState((state) => state.auth)
|
2026-06-03 21:38:21 +00:00
|
|
|
|
|
2026-05-27 22:30:13 +00:00
|
|
|
|
const { setUser } = useStoreActions((actions) => actions.auth.user)
|
2026-06-03 14:43:41 +00:00
|
|
|
|
const { setting } = useSetting()
|
2026-06-03 21:38:21 +00:00
|
|
|
|
|
2026-06-03 14:43:41 +00:00
|
|
|
|
const isEmailUpdateEnabled = setting('Abp.Identity.User.IsEmailUpdateEnabled')
|
2026-06-03 21:38:21 +00:00
|
|
|
|
const isRequireVerifiedAccount = setting('Abp.Identity.Profile.General.RequireVerifiedAccount')
|
|
|
|
|
|
const isRequireConfirmedEmail = setting('Abp.Identity.SignIn.RequireConfirmedEmail')
|
|
|
|
|
|
const isRequireConfirmedPhoneNumber = setting('Abp.Identity.SignIn.RequireConfirmedPhoneNumber')
|
|
|
|
|
|
const isTwoFactorEnabled = setting('Abp.Account.TwoFactor.Enabled')
|
2026-02-24 20:44:16 +00:00
|
|
|
|
|
2026-05-27 22:30:13 +00:00
|
|
|
|
const getUser = async (syncAvatar = true) => {
|
2026-02-24 20:44:16 +00:00
|
|
|
|
const { data } = await getUserDetail(userId || '')
|
|
|
|
|
|
setUserDetails(data)
|
2026-05-27 22:30:13 +00:00
|
|
|
|
if (syncAvatar) {
|
|
|
|
|
|
setImage(`${AVATAR_URL(data.id, data.tenantId)}?${dayjs().unix()}`)
|
|
|
|
|
|
}
|
2026-02-24 20:44:16 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
getUser()
|
2026-05-05 07:23:02 +00:00
|
|
|
|
getCountry().then(({ data }) => setCountries(data))
|
2026-02-24 20:44:16 +00:00
|
|
|
|
}, [])
|
|
|
|
|
|
|
|
|
|
|
|
const scheme = Yup.object().shape({
|
|
|
|
|
|
claimType: Yup.string().required(),
|
|
|
|
|
|
claimValue: Yup.string().required(),
|
|
|
|
|
|
})
|
|
|
|
|
|
|
2026-05-27 22:30:13 +00:00
|
|
|
|
const onChooseImage = async (file: File[]) => {
|
|
|
|
|
|
if (file[0]) {
|
|
|
|
|
|
setImage(URL.createObjectURL(file[0]))
|
|
|
|
|
|
} else {
|
|
|
|
|
|
setImage(undefined)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const beforeUpload = (files: FileList | null, fileList: File[]) => {
|
|
|
|
|
|
let valid: string | boolean = true
|
|
|
|
|
|
|
|
|
|
|
|
const allowedFileType = ['image/jpeg', 'image/png', 'image/gif']
|
|
|
|
|
|
const maxFileSize = 2000000
|
|
|
|
|
|
|
|
|
|
|
|
if (fileList.length >= 1) {
|
|
|
|
|
|
return `Sadece bir dosya seçebilirsiniz`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (files) {
|
|
|
|
|
|
for (const f of files) {
|
|
|
|
|
|
if (!allowedFileType.includes(f.type)) {
|
|
|
|
|
|
valid = '.jpg, .jpeg, .gif veya .png yükleyebilirsiniz'
|
|
|
|
|
|
} else if (f.size >= maxFileSize) {
|
|
|
|
|
|
valid = 'En fazla 2mb dosya yükleyebilirsiniz'
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return valid
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const getCroppedAvatar = () =>
|
|
|
|
|
|
new Promise<Blob | null>((resolve, reject) => {
|
|
|
|
|
|
const canvas = cropperRef.current?.getCanvas({
|
|
|
|
|
|
minHeight: 100,
|
|
|
|
|
|
minWidth: 100,
|
|
|
|
|
|
maxHeight: 300,
|
|
|
|
|
|
maxWidth: 300,
|
|
|
|
|
|
})
|
|
|
|
|
|
if (canvas) {
|
|
|
|
|
|
canvas.toBlob((blob) => {
|
|
|
|
|
|
if (blob) {
|
|
|
|
|
|
resolve(blob)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
reject()
|
|
|
|
|
|
}
|
|
|
|
|
|
}, 'image/jpeg')
|
|
|
|
|
|
} else {
|
|
|
|
|
|
resolve(null)
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
|
2026-02-24 20:44:16 +00:00
|
|
|
|
const handleSubmit = async (
|
|
|
|
|
|
values: ClaimTypeDto,
|
|
|
|
|
|
{ setSubmitting }: FormikHelpers<ClaimTypeDto>,
|
|
|
|
|
|
) => {
|
|
|
|
|
|
setLoading(true)
|
|
|
|
|
|
setSubmitting(true)
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
await postClaimUser({ userId, claimType: values.claimType, claimValue: values.claimValue })
|
|
|
|
|
|
toast.push(
|
|
|
|
|
|
<Notification type="success" duration={2000}>
|
|
|
|
|
|
{translate('::Kaydet')}
|
|
|
|
|
|
</Notification>,
|
|
|
|
|
|
{
|
|
|
|
|
|
placement: 'top-end',
|
|
|
|
|
|
},
|
|
|
|
|
|
)
|
|
|
|
|
|
setOpen(false)
|
|
|
|
|
|
getUser()
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
toast.push(
|
|
|
|
|
|
<Notification type="danger" duration={2000}>
|
|
|
|
|
|
{'Hata'}
|
|
|
|
|
|
</Notification>,
|
|
|
|
|
|
{
|
|
|
|
|
|
placement: 'top-end',
|
|
|
|
|
|
},
|
|
|
|
|
|
)
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
setLoading(false)
|
|
|
|
|
|
setSubmitting(false)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return userDetails ? (
|
|
|
|
|
|
<>
|
|
|
|
|
|
<Helmet
|
|
|
|
|
|
titleTemplate={`%s | ${APP_NAME}`}
|
|
|
|
|
|
title={userDetails.email}
|
|
|
|
|
|
defaultTitle={APP_NAME}
|
|
|
|
|
|
></Helmet>
|
2026-05-27 22:30:13 +00:00
|
|
|
|
<AdaptableCard>
|
2026-02-24 20:44:16 +00:00
|
|
|
|
<Tabs defaultValue="user">
|
|
|
|
|
|
<TabList>
|
2026-05-27 22:30:13 +00:00
|
|
|
|
<TabNav value="user" icon={<FaUser className="text-sm" />}>
|
2026-02-24 20:44:16 +00:00
|
|
|
|
{translate('::Abp.Identity.User.UserInformation')}
|
|
|
|
|
|
</TabNav>
|
2026-05-27 22:30:13 +00:00
|
|
|
|
<TabNav value="permission" icon={<FaCheckCircle className="text-sm" />}>
|
2026-05-04 14:35:18 +00:00
|
|
|
|
{translate('::Abp.Identity.User.Permissions')}
|
|
|
|
|
|
</TabNav>
|
2026-05-27 22:30:13 +00:00
|
|
|
|
<TabNav value="work" icon={<FaBuilding className="text-sm" />}>
|
2026-05-05 07:23:02 +00:00
|
|
|
|
{translate('::Abp.Identity.User.WorkInformation')}
|
|
|
|
|
|
</TabNav>
|
2026-05-27 22:30:13 +00:00
|
|
|
|
<TabNav value="identity" icon={<FaUserAstronaut className="text-sm" />}>
|
2026-05-05 07:23:02 +00:00
|
|
|
|
{translate('::Abp.Identity.User.IndentityInformation')}
|
|
|
|
|
|
</TabNav>
|
2026-05-27 22:30:13 +00:00
|
|
|
|
<TabNav value="lockout" icon={<FaLockOpen className="text-sm" />}>
|
2026-02-24 20:44:16 +00:00
|
|
|
|
{translate('::Abp.Identity.User.LockoutManagement')}
|
|
|
|
|
|
</TabNav>
|
2026-05-27 22:30:13 +00:00
|
|
|
|
<TabNav value="claimTypes" icon={<FaFileAlt className="text-sm" />}>
|
2026-02-24 20:44:16 +00:00
|
|
|
|
{translate('::Abp.Identity.User.ClaimTypes')}
|
|
|
|
|
|
</TabNav>
|
|
|
|
|
|
</TabList>
|
|
|
|
|
|
<TabContent value="user">
|
2026-05-27 22:30:13 +00:00
|
|
|
|
<div className="px-4 py-6">
|
2026-02-24 20:44:16 +00:00
|
|
|
|
<Formik
|
|
|
|
|
|
initialValues={userDetails}
|
|
|
|
|
|
onSubmit={async (values, { resetForm, setSubmitting }) => {
|
|
|
|
|
|
setSubmitting(true)
|
|
|
|
|
|
await putUserDetail({ ...values })
|
2026-05-27 22:30:13 +00:00
|
|
|
|
let keepCurrentAvatar = false
|
|
|
|
|
|
|
|
|
|
|
|
const avatar = await getCroppedAvatar()
|
|
|
|
|
|
const resp = await updateProfile({
|
|
|
|
|
|
name: values.name ?? '',
|
|
|
|
|
|
surname: values.surname ?? '',
|
|
|
|
|
|
avatar: avatar ? new File([avatar], 'avatar') : undefined,
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
if (resp.status === 200) {
|
|
|
|
|
|
const avatarUrl =
|
|
|
|
|
|
AVATAR_URL(auth.user.id, auth.tenant?.tenantId) + `?${dayjs().unix()}`
|
|
|
|
|
|
|
|
|
|
|
|
setUser({
|
|
|
|
|
|
...auth.user,
|
|
|
|
|
|
name: `${resp.data.name} ${resp.data.surname}`.trim(),
|
|
|
|
|
|
avatar: avatarUrl,
|
|
|
|
|
|
})
|
|
|
|
|
|
setImage(avatarUrl)
|
|
|
|
|
|
keepCurrentAvatar = true
|
|
|
|
|
|
} else {
|
|
|
|
|
|
toast.push(<Notification title={resp?.error?.message} type="danger" />, {
|
|
|
|
|
|
placement: 'top-end',
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
2026-02-24 20:44:16 +00:00
|
|
|
|
|
|
|
|
|
|
toast.push(
|
|
|
|
|
|
<Notification type="success" duration={2000}>
|
2026-05-05 07:23:02 +00:00
|
|
|
|
{translate('::Kaydet')}
|
2026-02-24 20:44:16 +00:00
|
|
|
|
</Notification>,
|
|
|
|
|
|
{
|
|
|
|
|
|
placement: 'top-end',
|
|
|
|
|
|
},
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2026-05-27 22:30:13 +00:00
|
|
|
|
getUser(!keepCurrentAvatar)
|
2026-02-24 20:44:16 +00:00
|
|
|
|
setSubmitting(false)
|
|
|
|
|
|
}}
|
|
|
|
|
|
>
|
2026-04-26 19:05:19 +00:00
|
|
|
|
{({ isSubmitting, values }) => {
|
2026-02-24 20:44:16 +00:00
|
|
|
|
return (
|
|
|
|
|
|
<Form>
|
2026-05-25 09:14:42 +00:00
|
|
|
|
<div>
|
2026-02-24 20:44:16 +00:00
|
|
|
|
<FormContainer size="md">
|
2026-05-27 22:30:13 +00:00
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5 w-full">
|
2026-02-24 20:44:16 +00:00
|
|
|
|
{/* Personal Information */}
|
|
|
|
|
|
<div>
|
2026-05-25 09:14:42 +00:00
|
|
|
|
<h6 className="mb-4">
|
|
|
|
|
|
{translate(
|
|
|
|
|
|
'::Abp.Identity.User.UserInformation.ContactInformation',
|
|
|
|
|
|
)}
|
|
|
|
|
|
</h6>
|
2026-05-27 22:30:13 +00:00
|
|
|
|
<FormItem label={translate('::Abp.Account.EmailAddress')}>
|
|
|
|
|
|
<Field
|
|
|
|
|
|
type="text"
|
2026-06-03 14:43:41 +00:00
|
|
|
|
disabled={isEmailUpdateEnabled?.toLowerCase() !== 'true'}
|
2026-05-27 22:30:13 +00:00
|
|
|
|
name="email"
|
|
|
|
|
|
placeholder="Email Address"
|
|
|
|
|
|
prefix={<FaEnvelope className="text-xl" />}
|
|
|
|
|
|
component={Input}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
|
2026-02-24 20:44:16 +00:00
|
|
|
|
<FormItem
|
|
|
|
|
|
label={translate('::Abp.Identity.User.UserInformation.Name')}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
name="name"
|
|
|
|
|
|
placeholder="Name"
|
|
|
|
|
|
component={Input}
|
2026-05-27 22:30:13 +00:00
|
|
|
|
prefix={<FaUserCircle className="text-xl" />}
|
2026-02-24 20:44:16 +00:00
|
|
|
|
/>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
label={translate('::Abp.Identity.User.UserInformation.Surname')}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
name="surname"
|
|
|
|
|
|
placeholder="Surname"
|
|
|
|
|
|
component={Input}
|
2026-05-27 22:30:13 +00:00
|
|
|
|
prefix={<FaUserCircle className="text-xl" />}
|
2026-02-24 20:44:16 +00:00
|
|
|
|
/>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
label={translate('::Abp.Identity.User.UserInformation.PhoneNumber')}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
name="phoneNumber"
|
2026-04-26 19:05:19 +00:00
|
|
|
|
placeholder={translate(
|
|
|
|
|
|
'::Abp.Identity.User.UserInformation.PhoneNumber',
|
|
|
|
|
|
)}
|
2026-05-27 22:30:13 +00:00
|
|
|
|
prefix={<FaPhone className="text-xl" />}
|
2026-02-24 20:44:16 +00:00
|
|
|
|
component={Input}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</FormItem>
|
2026-05-25 09:14:42 +00:00
|
|
|
|
|
2026-05-05 17:59:30 +00:00
|
|
|
|
<FormItem size="sm" label={translate('::RocketUsername')}>
|
2026-02-24 20:44:16 +00:00
|
|
|
|
<Field
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
name="rocketUsername"
|
|
|
|
|
|
placeholder={translate('::RocketUsername')}
|
|
|
|
|
|
component={Input}
|
2026-05-27 22:30:13 +00:00
|
|
|
|
prefix={<FaFacebookMessenger className="text-xl" />}
|
2026-02-24 20:44:16 +00:00
|
|
|
|
/>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-05-05 07:23:02 +00:00
|
|
|
|
<div>
|
|
|
|
|
|
<h6 className="mb-4">
|
|
|
|
|
|
{translate(
|
|
|
|
|
|
'::Abp.Identity.User.UserInformation.AdditionalInformation',
|
|
|
|
|
|
)}
|
|
|
|
|
|
</h6>
|
2026-05-27 22:30:13 +00:00
|
|
|
|
<FormItem label={translate('::Abp.Account.HomeAddress')}>
|
|
|
|
|
|
<Field
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
name="homeAddress"
|
|
|
|
|
|
placeholder={translate('::Abp.Account.HomeAddress')}
|
|
|
|
|
|
component={Input}
|
|
|
|
|
|
prefix={<FaHome className="text-xl" />}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
|
2026-05-05 07:23:02 +00:00
|
|
|
|
<FormItem label={translate('::Abp.Account.Nationality')}>
|
|
|
|
|
|
<Field type="text" name="nationality">
|
|
|
|
|
|
{({ field, form }: FieldProps<SelectBoxOption>) => {
|
|
|
|
|
|
const nationalityOptions: SelectBoxOption[] = countries.map(
|
|
|
|
|
|
(c) => ({ value: c.name, label: c.name }),
|
|
|
|
|
|
)
|
|
|
|
|
|
return (
|
|
|
|
|
|
<Select
|
|
|
|
|
|
field={field}
|
|
|
|
|
|
form={form}
|
|
|
|
|
|
options={nationalityOptions}
|
|
|
|
|
|
isClearable={true}
|
|
|
|
|
|
value={nationalityOptions.filter(
|
|
|
|
|
|
(o) => o.value === values.nationality,
|
|
|
|
|
|
)}
|
|
|
|
|
|
onChange={(option) =>
|
|
|
|
|
|
form.setFieldValue(field.name, option?.value ?? null)
|
|
|
|
|
|
}
|
|
|
|
|
|
/>
|
|
|
|
|
|
)
|
|
|
|
|
|
}}
|
|
|
|
|
|
</Field>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
<FormItem label={translate('::Abp.Account.EducationLevel')}>
|
|
|
|
|
|
<Field type="text" name="educationLevel">
|
|
|
|
|
|
{({ field, form }: FieldProps<SelectBoxOption>) => {
|
|
|
|
|
|
const educationOptions: SelectBoxOption[] = [
|
|
|
|
|
|
{
|
|
|
|
|
|
value: 'İlkokul',
|
|
|
|
|
|
label:
|
|
|
|
|
|
translate('::App.EducationLevel.Primary') || 'İlkokul',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
value: 'Ortaokul',
|
|
|
|
|
|
label:
|
|
|
|
|
|
translate('::App.EducationLevel.MiddleSchool') ||
|
|
|
|
|
|
'Ortaokul',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
value: 'Lise',
|
|
|
|
|
|
label:
|
|
|
|
|
|
translate('::App.EducationLevel.HighSchool') || 'Lise',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
value: 'Ön Lisans',
|
|
|
|
|
|
label:
|
|
|
|
|
|
translate('::App.EducationLevel.Associate') ||
|
|
|
|
|
|
'Ön Lisans',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
value: 'Lisans',
|
|
|
|
|
|
label:
|
|
|
|
|
|
translate('::App.EducationLevel.Bachelor') || 'Lisans',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
value: 'Yüksek Lisans',
|
|
|
|
|
|
label:
|
|
|
|
|
|
translate('::App.EducationLevel.Master') ||
|
|
|
|
|
|
'Yüksek Lisans',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
value: 'Doktora',
|
|
|
|
|
|
label: translate('::App.EducationLevel.PhD') || 'Doktora',
|
|
|
|
|
|
},
|
|
|
|
|
|
]
|
|
|
|
|
|
return (
|
|
|
|
|
|
<Select
|
|
|
|
|
|
field={field}
|
|
|
|
|
|
form={form}
|
|
|
|
|
|
options={educationOptions}
|
|
|
|
|
|
isClearable={true}
|
|
|
|
|
|
value={educationOptions.filter(
|
|
|
|
|
|
(o) => o.value === values.educationLevel,
|
|
|
|
|
|
)}
|
|
|
|
|
|
onChange={(option) =>
|
|
|
|
|
|
form.setFieldValue(field.name, option?.value ?? null)
|
|
|
|
|
|
}
|
|
|
|
|
|
/>
|
|
|
|
|
|
)
|
|
|
|
|
|
}}
|
|
|
|
|
|
</Field>
|
|
|
|
|
|
</FormItem>
|
2026-05-27 22:30:13 +00:00
|
|
|
|
|
2026-05-05 07:23:02 +00:00
|
|
|
|
<FormItem label={translate('::Abp.Account.GraduationSchool')}>
|
|
|
|
|
|
<Field
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
name="graduationSchool"
|
|
|
|
|
|
placeholder={translate('::GraduationSchool')}
|
|
|
|
|
|
component={Input}
|
2026-05-27 22:30:13 +00:00
|
|
|
|
prefix={<FaUniversity className="text-xl" />}
|
2026-05-05 07:23:02 +00:00
|
|
|
|
/>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
<FormItem label={translate('::Abp.Account.BloodType')}>
|
|
|
|
|
|
<Field type="text" name="bloodType">
|
|
|
|
|
|
{({ field, form }: FieldProps<SelectBoxOption>) => {
|
|
|
|
|
|
const bloodTypeOptions: SelectBoxOption[] = [
|
|
|
|
|
|
{ value: 'A Rh+', label: 'A Rh+' },
|
|
|
|
|
|
{ value: 'A Rh-', label: 'A Rh-' },
|
|
|
|
|
|
{ value: 'B Rh+', label: 'B Rh+' },
|
|
|
|
|
|
{ value: 'B Rh-', label: 'B Rh-' },
|
|
|
|
|
|
{ value: 'AB Rh+', label: 'AB Rh+' },
|
|
|
|
|
|
{ value: 'AB Rh-', label: 'AB Rh-' },
|
|
|
|
|
|
{ value: '0 Rh+', label: '0 Rh+' },
|
|
|
|
|
|
{ value: '0 Rh-', label: '0 Rh-' },
|
|
|
|
|
|
]
|
|
|
|
|
|
return (
|
|
|
|
|
|
<Select
|
|
|
|
|
|
field={field}
|
|
|
|
|
|
form={form}
|
|
|
|
|
|
options={bloodTypeOptions}
|
|
|
|
|
|
isClearable={true}
|
|
|
|
|
|
value={bloodTypeOptions.filter(
|
|
|
|
|
|
(o) => o.value === values.bloodType,
|
|
|
|
|
|
)}
|
|
|
|
|
|
onChange={(option) =>
|
|
|
|
|
|
form.setFieldValue(field.name, option?.value ?? null)
|
|
|
|
|
|
}
|
|
|
|
|
|
/>
|
|
|
|
|
|
)
|
|
|
|
|
|
}}
|
|
|
|
|
|
</Field>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-02-24 20:44:16 +00:00
|
|
|
|
<div>
|
2026-05-27 22:30:13 +00:00
|
|
|
|
<h6 className="mb-4">Avatar</h6>
|
|
|
|
|
|
|
|
|
|
|
|
<FormItem>
|
|
|
|
|
|
<div className="flex flex-col gap-4">
|
|
|
|
|
|
{image ? (
|
|
|
|
|
|
<Cropper
|
|
|
|
|
|
ref={cropperRef}
|
|
|
|
|
|
src={image}
|
|
|
|
|
|
onUpdate={(cropper) => {
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
previewRef.current?.update(cropper)
|
|
|
|
|
|
}, 100)
|
2026-02-24 20:44:16 +00:00
|
|
|
|
}}
|
2026-05-27 22:30:13 +00:00
|
|
|
|
className="cropper max-h-[300px] max-w-[300px]"
|
|
|
|
|
|
stencilComponent={CircleStencil}
|
|
|
|
|
|
minHeight={100}
|
|
|
|
|
|
minWidth={100}
|
2026-02-24 20:44:16 +00:00
|
|
|
|
/>
|
2026-05-27 22:30:13 +00:00
|
|
|
|
) : (
|
|
|
|
|
|
<img
|
|
|
|
|
|
className="cropper max-h-[300px] max-w-[300px]"
|
2026-06-03 14:43:41 +00:00
|
|
|
|
src={image || AVATAR_URL(values.id, values.tenantId)}
|
2026-02-24 20:44:16 +00:00
|
|
|
|
/>
|
|
|
|
|
|
)}
|
2026-05-27 22:30:13 +00:00
|
|
|
|
<div className="flex items-start gap-4">
|
|
|
|
|
|
<div className="flex flex-col gap-2">
|
|
|
|
|
|
<Upload
|
|
|
|
|
|
className="cursor-pointer"
|
|
|
|
|
|
showList={false}
|
|
|
|
|
|
multiple={false}
|
|
|
|
|
|
uploadLimit={1}
|
|
|
|
|
|
beforeUpload={beforeUpload}
|
|
|
|
|
|
onChange={onChooseImage}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Button icon={<FaPlus />} type="button"></Button>
|
|
|
|
|
|
</Upload>
|
|
|
|
|
|
<Button
|
|
|
|
|
|
type="button"
|
|
|
|
|
|
icon={<FaTrashAlt />}
|
|
|
|
|
|
onClick={() => setImage(undefined)}
|
|
|
|
|
|
></Button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
{image && (
|
|
|
|
|
|
<CropperPreview
|
|
|
|
|
|
ref={previewRef}
|
|
|
|
|
|
className="preview max-w-[100px] avatar-img avatar-circle"
|
|
|
|
|
|
/>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2026-02-24 20:44:16 +00:00
|
|
|
|
</FormItem>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</FormContainer>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-05-27 22:30:13 +00:00
|
|
|
|
<div className="mt-4 ltr:text-right">
|
|
|
|
|
|
<Button variant="solid" loading={isSubmitting} type="submit">
|
|
|
|
|
|
{isSubmitting ? translate('::SavingWithThreeDot') : translate('::Save')}
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</div>
|
2026-02-24 20:44:16 +00:00
|
|
|
|
</Form>
|
|
|
|
|
|
)
|
|
|
|
|
|
}}
|
|
|
|
|
|
</Formik>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</TabContent>
|
2026-05-04 14:35:18 +00:00
|
|
|
|
|
|
|
|
|
|
<TabContent value="permission">
|
2026-05-27 22:30:13 +00:00
|
|
|
|
<div className="px-4 py-6">
|
2026-05-04 14:35:18 +00:00
|
|
|
|
<Formik
|
|
|
|
|
|
initialValues={userDetails}
|
|
|
|
|
|
onSubmit={async (values, { setSubmitting }) => {
|
|
|
|
|
|
setSubmitting(true)
|
|
|
|
|
|
|
|
|
|
|
|
await putUserPermission({ ...values })
|
|
|
|
|
|
|
|
|
|
|
|
toast.push(
|
|
|
|
|
|
<Notification type="success" duration={2000}>
|
|
|
|
|
|
{translate('::Abp.Identity.User.SavePermission')}
|
|
|
|
|
|
</Notification>,
|
|
|
|
|
|
{
|
|
|
|
|
|
placement: 'top-end',
|
|
|
|
|
|
},
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
getUser()
|
|
|
|
|
|
|
|
|
|
|
|
setSubmitting(false)
|
|
|
|
|
|
}}
|
|
|
|
|
|
>
|
|
|
|
|
|
{({ isSubmitting, values }) => {
|
|
|
|
|
|
const roles = values.roles
|
|
|
|
|
|
const branches = values.branches
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<Form>
|
2026-05-25 09:14:42 +00:00
|
|
|
|
<div>
|
2026-05-04 14:35:18 +00:00
|
|
|
|
<FormContainer size="md">
|
|
|
|
|
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4 w-full">
|
|
|
|
|
|
{/* Şube Management */}
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<h6 className="mb-4">
|
|
|
|
|
|
{translate('::Abp.Identity.User.UserInformation.BranchManagement')}
|
|
|
|
|
|
</h6>
|
|
|
|
|
|
<div className="border-2 rounded-lg p-4">
|
|
|
|
|
|
<FieldArray name="branches">
|
|
|
|
|
|
{({ form, remove, push }) => (
|
|
|
|
|
|
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-2 text-center">
|
|
|
|
|
|
{branches && branches.length > 0
|
|
|
|
|
|
? branches.map((_, index: number) => (
|
|
|
|
|
|
<div key={index} className="p-2">
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
labelClass="block text-center"
|
|
|
|
|
|
className="mb-0 justify-center"
|
|
|
|
|
|
label={branches[index].name}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field
|
|
|
|
|
|
className="mr-0"
|
|
|
|
|
|
name={`branches[${index}].isAssigned`}
|
|
|
|
|
|
component={Checkbox}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
))
|
|
|
|
|
|
: null}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</FieldArray>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
{/* Role Management */}
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<h6 className="mb-4">
|
|
|
|
|
|
{translate('::Abp.Identity.User.UserInformation.RoleManagement')}
|
|
|
|
|
|
</h6>
|
|
|
|
|
|
<div className="border-2 rounded-lg p-4">
|
|
|
|
|
|
<FieldArray name="roles">
|
|
|
|
|
|
{({ form, remove, push }) => (
|
|
|
|
|
|
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-2 text-center">
|
|
|
|
|
|
{roles && roles.length > 0
|
|
|
|
|
|
? roles.map((_, index: number) => (
|
|
|
|
|
|
<div key={index} className="p-2">
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
labelClass="block text-center"
|
|
|
|
|
|
className="mb-0 justify-center"
|
|
|
|
|
|
label={roles[index].name}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field
|
|
|
|
|
|
className="mr-0"
|
|
|
|
|
|
name={`roles[${index}].isAssigned`}
|
|
|
|
|
|
component={Checkbox}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
))
|
|
|
|
|
|
: null}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</FieldArray>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</FormContainer>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-05-27 22:30:13 +00:00
|
|
|
|
<div className="mt-4 ltr:text-right">
|
|
|
|
|
|
<Button variant="solid" loading={isSubmitting} type="submit">
|
2026-05-04 14:35:18 +00:00
|
|
|
|
{isSubmitting ? translate('::SavingWithThreeDot') : translate('::Save')}
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</Form>
|
|
|
|
|
|
)
|
|
|
|
|
|
}}
|
|
|
|
|
|
</Formik>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</TabContent>
|
|
|
|
|
|
|
2026-05-05 07:23:02 +00:00
|
|
|
|
<TabContent value="work">
|
2026-05-27 22:30:13 +00:00
|
|
|
|
<div className="px-4 py-6">
|
2026-05-05 07:23:02 +00:00
|
|
|
|
<Formik
|
|
|
|
|
|
initialValues={userDetails}
|
|
|
|
|
|
onSubmit={async (values, { resetForm, setSubmitting }) => {
|
|
|
|
|
|
setSubmitting(true)
|
|
|
|
|
|
await putUserDetail({ ...values })
|
|
|
|
|
|
|
|
|
|
|
|
toast.push(
|
|
|
|
|
|
<Notification type="success" duration={2000}>
|
|
|
|
|
|
{translate('::Kaydet')}
|
|
|
|
|
|
</Notification>,
|
|
|
|
|
|
{
|
|
|
|
|
|
placement: 'top-end',
|
|
|
|
|
|
},
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
getUser()
|
|
|
|
|
|
setSubmitting(false)
|
|
|
|
|
|
}}
|
|
|
|
|
|
>
|
|
|
|
|
|
{({ isSubmitting, values }) => {
|
|
|
|
|
|
const departments = values.departments
|
|
|
|
|
|
const jobPositions = values.jobPositions
|
|
|
|
|
|
|
|
|
|
|
|
const departmentOptions: SelectBoxOption[] = departments.map((department) => ({
|
|
|
|
|
|
value: department.id,
|
|
|
|
|
|
label: department.name,
|
|
|
|
|
|
}))
|
|
|
|
|
|
|
|
|
|
|
|
const jobPositionOptions: SelectBoxOptionWithGroup[] = jobPositions.map(
|
|
|
|
|
|
(jobPosition) => ({
|
|
|
|
|
|
value: jobPosition.id,
|
|
|
|
|
|
label: jobPosition.name,
|
|
|
|
|
|
group: jobPosition.departmentId,
|
|
|
|
|
|
}),
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<Form>
|
2026-05-25 09:14:42 +00:00
|
|
|
|
<div>
|
2026-05-05 07:23:02 +00:00
|
|
|
|
<FormContainer size="md">
|
2026-05-27 22:30:13 +00:00
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5 w-full">
|
2026-05-05 07:23:02 +00:00
|
|
|
|
<div>
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
label={translate(
|
|
|
|
|
|
'::Abp.Identity.User.UserInformation.DepartmentId',
|
|
|
|
|
|
)}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field type="text" name="departmentId">
|
|
|
|
|
|
{({ field, form }: FieldProps<SelectBoxOption>) => (
|
|
|
|
|
|
<Select
|
|
|
|
|
|
field={field}
|
|
|
|
|
|
form={form}
|
|
|
|
|
|
options={departmentOptions}
|
|
|
|
|
|
isClearable={true}
|
|
|
|
|
|
value={departmentOptions.filter(
|
|
|
|
|
|
(option) => option.value === values.departmentId,
|
|
|
|
|
|
)}
|
|
|
|
|
|
onChange={(option) => {
|
|
|
|
|
|
form.setFieldValue(field.name, option?.value)
|
|
|
|
|
|
form.setFieldValue('jobPositionId', null)
|
|
|
|
|
|
}}
|
|
|
|
|
|
/>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</Field>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
label={translate(
|
|
|
|
|
|
'::Abp.Identity.User.UserInformation.JobPositionId',
|
|
|
|
|
|
)}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field type="text" name="jobPositionId">
|
|
|
|
|
|
{({ field, form }: FieldProps<SelectBoxOptionWithGroup>) => (
|
|
|
|
|
|
<Select
|
|
|
|
|
|
field={field}
|
|
|
|
|
|
form={form}
|
|
|
|
|
|
options={jobPositionOptions.filter(
|
|
|
|
|
|
(option) => option.group === values.departmentId,
|
|
|
|
|
|
)}
|
|
|
|
|
|
isClearable={true}
|
|
|
|
|
|
value={jobPositionOptions.filter(
|
|
|
|
|
|
(option) => option.value === values.jobPositionId,
|
|
|
|
|
|
)}
|
|
|
|
|
|
onChange={(option) =>
|
|
|
|
|
|
form.setFieldValue(field.name, option?.value)
|
|
|
|
|
|
}
|
|
|
|
|
|
/>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</Field>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
label={translate('::Abp.Identity.User.UserInformation.SskNo')}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
name="sskNo"
|
2026-05-25 09:14:42 +00:00
|
|
|
|
placeholder={translate(
|
|
|
|
|
|
'::Abp.Identity.User.UserInformation.SskNo',
|
|
|
|
|
|
)}
|
2026-05-05 07:23:02 +00:00
|
|
|
|
component={Input}
|
2026-05-27 22:30:13 +00:00
|
|
|
|
prefix={<FaIdCard className="text-xl" />}
|
2026-05-05 07:23:02 +00:00
|
|
|
|
/>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
label={translate('::Abp.Identity.User.UserInformation.HireDate')}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field name="hireDate">
|
|
|
|
|
|
{({ field, form }: FieldProps) => (
|
|
|
|
|
|
<DatePicker
|
|
|
|
|
|
field={field}
|
|
|
|
|
|
form={form}
|
|
|
|
|
|
value={field.value ? dayjs(field.value).toDate() : null}
|
2026-05-25 09:14:42 +00:00
|
|
|
|
placeholder={translate(
|
|
|
|
|
|
'::Abp.Identity.User.UserInformation.HireDate',
|
|
|
|
|
|
)}
|
2026-05-27 22:30:13 +00:00
|
|
|
|
inputPrefix={<FaBriefcase className="text-xl" />}
|
2026-05-05 07:23:02 +00:00
|
|
|
|
onChange={(date) => {
|
|
|
|
|
|
form.setFieldValue(
|
|
|
|
|
|
field.name,
|
|
|
|
|
|
date ? dayjs(date).format('YYYY-MM-DDTHH:mm:ss') : null,
|
|
|
|
|
|
)
|
|
|
|
|
|
}}
|
|
|
|
|
|
/>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</Field>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<FormItem
|
2026-05-25 09:14:42 +00:00
|
|
|
|
label={translate(
|
|
|
|
|
|
'::Abp.Identity.User.UserInformation.TerminationDate',
|
|
|
|
|
|
)}
|
2026-05-05 07:23:02 +00:00
|
|
|
|
>
|
|
|
|
|
|
<Field name="terminationDate">
|
|
|
|
|
|
{({ field, form }: FieldProps) => (
|
|
|
|
|
|
<DatePicker
|
|
|
|
|
|
field={field}
|
|
|
|
|
|
form={form}
|
|
|
|
|
|
value={field.value ? dayjs(field.value).toDate() : null}
|
2026-05-25 09:14:42 +00:00
|
|
|
|
placeholder={translate(
|
|
|
|
|
|
'::Abp.Identity.User.UserInformation.TerminationDate',
|
|
|
|
|
|
)}
|
2026-05-27 22:30:13 +00:00
|
|
|
|
inputPrefix={<FaCalendarAlt className="text-xl" />}
|
2026-05-05 07:23:02 +00:00
|
|
|
|
onChange={(date) => {
|
|
|
|
|
|
form.setFieldValue(
|
|
|
|
|
|
field.name,
|
|
|
|
|
|
date ? dayjs(date).format('YYYY-MM-DDTHH:mm:ss') : null,
|
|
|
|
|
|
)
|
|
|
|
|
|
}}
|
|
|
|
|
|
/>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</Field>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</FormContainer>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-05-27 22:30:13 +00:00
|
|
|
|
<div className="mt-4 ltr:text-right">
|
|
|
|
|
|
<Button variant="solid" loading={isSubmitting} type="submit">
|
|
|
|
|
|
{isSubmitting ? translate('::SavingWithThreeDot') : translate('::Save')}
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</div>
|
2026-05-05 07:23:02 +00:00
|
|
|
|
</Form>
|
|
|
|
|
|
)
|
|
|
|
|
|
}}
|
|
|
|
|
|
</Formik>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</TabContent>
|
|
|
|
|
|
|
|
|
|
|
|
<TabContent value="identity">
|
2026-05-27 22:30:13 +00:00
|
|
|
|
<div className="px-4 py-6">
|
2026-05-05 07:23:02 +00:00
|
|
|
|
<Formik
|
|
|
|
|
|
initialValues={userDetails}
|
|
|
|
|
|
onSubmit={async (values, { resetForm, setSubmitting }) => {
|
|
|
|
|
|
setSubmitting(true)
|
|
|
|
|
|
await putUserDetail({ ...values })
|
|
|
|
|
|
|
|
|
|
|
|
toast.push(
|
|
|
|
|
|
<Notification type="success" duration={2000}>
|
|
|
|
|
|
{translate('::Kaydet')}
|
|
|
|
|
|
</Notification>,
|
|
|
|
|
|
{
|
|
|
|
|
|
placement: 'top-end',
|
|
|
|
|
|
},
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
getUser()
|
|
|
|
|
|
setSubmitting(false)
|
|
|
|
|
|
}}
|
|
|
|
|
|
>
|
|
|
|
|
|
{({ isSubmitting, values }) => {
|
|
|
|
|
|
const maritalStatusOptions: SelectBoxOption[] = [
|
|
|
|
|
|
{
|
|
|
|
|
|
value: 'Bekar',
|
|
|
|
|
|
label: translate('::App.MaritalStatus.Single') || 'Bekar',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
value: 'Evli',
|
|
|
|
|
|
label: translate('::App.MaritalStatus.Married') || 'Evli',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
value: 'Boşanmış',
|
|
|
|
|
|
label: translate('::App.MaritalStatus.Divorced') || 'Boşanmış',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
value: 'Dul',
|
|
|
|
|
|
label: translate('::App.MaritalStatus.Widowed') || 'Dul',
|
|
|
|
|
|
},
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<Form>
|
2026-05-25 09:14:42 +00:00
|
|
|
|
<FormContainer size="md">
|
2026-05-27 22:30:13 +00:00
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-x-5 w-full">
|
2026-05-25 09:14:42 +00:00
|
|
|
|
<div>
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
label={translate(
|
|
|
|
|
|
'::Abp.Identity.User.UserInformation.IdentityNumber',
|
|
|
|
|
|
)}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
name="identityNumber"
|
|
|
|
|
|
placeholder={translate(
|
|
|
|
|
|
'::Abp.Identity.User.UserInformation.IdentityNumber',
|
|
|
|
|
|
)}
|
|
|
|
|
|
component={Input}
|
2026-05-27 22:30:13 +00:00
|
|
|
|
prefix={<FaIdCard className="text-xl" />}
|
2026-05-25 09:14:42 +00:00
|
|
|
|
/>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
</div>
|
2026-05-05 07:23:02 +00:00
|
|
|
|
|
2026-05-25 09:14:42 +00:00
|
|
|
|
<div>
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
label={translate('::Abp.Identity.User.UserInformation.SerialNo')}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
name="serialNo"
|
|
|
|
|
|
placeholder={translate(
|
|
|
|
|
|
'::Abp.Identity.User.UserInformation.SerialNo',
|
|
|
|
|
|
)}
|
|
|
|
|
|
component={Input}
|
2026-05-27 22:30:13 +00:00
|
|
|
|
prefix={<FaHashtag className="text-xl" />}
|
2026-05-25 09:14:42 +00:00
|
|
|
|
/>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
</div>
|
2026-05-05 07:23:02 +00:00
|
|
|
|
|
2026-05-25 09:14:42 +00:00
|
|
|
|
<div>
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
label={translate('::Abp.Identity.User.UserInformation.Province')}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
name="province"
|
|
|
|
|
|
placeholder={translate(
|
|
|
|
|
|
'::Abp.Identity.User.UserInformation.Province',
|
|
|
|
|
|
)}
|
|
|
|
|
|
component={Input}
|
2026-05-27 22:30:13 +00:00
|
|
|
|
prefix={<FaMapMarkerAlt className="text-xl" />}
|
2026-05-25 09:14:42 +00:00
|
|
|
|
/>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
</div>
|
2026-05-05 07:23:02 +00:00
|
|
|
|
|
2026-05-25 09:14:42 +00:00
|
|
|
|
<div>
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
label={translate('::Abp.Identity.User.UserInformation.District')}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
name="district"
|
|
|
|
|
|
placeholder={translate(
|
|
|
|
|
|
'::Abp.Identity.User.UserInformation.District',
|
|
|
|
|
|
)}
|
|
|
|
|
|
component={Input}
|
2026-05-27 22:30:13 +00:00
|
|
|
|
prefix={<FaCity className="text-xl" />}
|
2026-05-25 09:14:42 +00:00
|
|
|
|
/>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
</div>
|
2026-05-05 07:23:02 +00:00
|
|
|
|
|
2026-05-25 09:14:42 +00:00
|
|
|
|
<div>
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
label={translate('::Abp.Identity.User.UserInformation.Village')}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
name="village"
|
|
|
|
|
|
placeholder={translate(
|
|
|
|
|
|
'::Abp.Identity.User.UserInformation.Village',
|
|
|
|
|
|
)}
|
|
|
|
|
|
component={Input}
|
2026-05-27 22:30:13 +00:00
|
|
|
|
prefix={<FaHome className="text-xl" />}
|
2026-05-25 09:14:42 +00:00
|
|
|
|
/>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
</div>
|
2026-05-05 07:23:02 +00:00
|
|
|
|
|
2026-05-25 09:14:42 +00:00
|
|
|
|
<div>
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
label={translate('::Abp.Identity.User.UserInformation.VolumeNo')}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
name="volumeNo"
|
|
|
|
|
|
placeholder={translate(
|
|
|
|
|
|
'::Abp.Identity.User.UserInformation.VolumeNo',
|
|
|
|
|
|
)}
|
|
|
|
|
|
component={Input}
|
2026-05-27 22:30:13 +00:00
|
|
|
|
prefix={<FaBook className="text-xl" />}
|
2026-05-25 09:14:42 +00:00
|
|
|
|
/>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
</div>
|
2026-05-05 07:23:02 +00:00
|
|
|
|
|
2026-05-25 09:14:42 +00:00
|
|
|
|
<div>
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
label={translate(
|
|
|
|
|
|
'::Abp.Identity.User.UserInformation.FamilySequenceNo',
|
|
|
|
|
|
)}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
name="familySequenceNo"
|
|
|
|
|
|
placeholder={translate(
|
|
|
|
|
|
'::Abp.Identity.User.UserInformation.FamilySequenceNo',
|
|
|
|
|
|
)}
|
|
|
|
|
|
component={Input}
|
2026-05-27 22:30:13 +00:00
|
|
|
|
prefix={<FaUsers className="text-xl" />}
|
2026-05-25 09:14:42 +00:00
|
|
|
|
/>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
</div>
|
2026-05-05 07:23:02 +00:00
|
|
|
|
|
2026-05-25 09:14:42 +00:00
|
|
|
|
<div>
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
label={translate('::Abp.Identity.User.UserInformation.SequenceNo')}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
name="sequenceNo"
|
|
|
|
|
|
placeholder={translate(
|
|
|
|
|
|
'::Abp.Identity.User.UserInformation.SequenceNo',
|
|
|
|
|
|
)}
|
|
|
|
|
|
component={Input}
|
2026-05-27 22:30:13 +00:00
|
|
|
|
prefix={<FaHashtag className="text-xl" />}
|
2026-05-25 09:14:42 +00:00
|
|
|
|
/>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
</div>
|
2026-05-05 07:23:02 +00:00
|
|
|
|
|
2026-05-25 09:14:42 +00:00
|
|
|
|
<div>
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
label={translate('::Abp.Identity.User.UserInformation.IssuedPlace')}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
name="issuedPlace"
|
|
|
|
|
|
placeholder={translate(
|
|
|
|
|
|
'::Abp.Identity.User.UserInformation.IssuedPlace',
|
|
|
|
|
|
)}
|
|
|
|
|
|
component={Input}
|
2026-05-27 22:30:13 +00:00
|
|
|
|
prefix={<FaMapPin className="text-xl" />}
|
2026-05-25 09:14:42 +00:00
|
|
|
|
/>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
</div>
|
2026-05-05 07:23:02 +00:00
|
|
|
|
|
2026-05-25 09:14:42 +00:00
|
|
|
|
<div>
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
label={translate('::Abp.Identity.User.UserInformation.IssuedDate')}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field name="issuedDate">
|
|
|
|
|
|
{({ field, form }: FieldProps) => (
|
|
|
|
|
|
<DatePicker
|
|
|
|
|
|
field={field}
|
|
|
|
|
|
form={form}
|
|
|
|
|
|
value={field.value ? dayjs(field.value).toDate() : null}
|
|
|
|
|
|
placeholder={translate(
|
|
|
|
|
|
'::Abp.Identity.User.UserInformation.IssuedDate',
|
|
|
|
|
|
)}
|
2026-05-27 22:30:13 +00:00
|
|
|
|
inputPrefix={<FaCalendarAlt className="text-xl" />}
|
2026-05-25 09:14:42 +00:00
|
|
|
|
onChange={(date) => {
|
|
|
|
|
|
form.setFieldValue(
|
|
|
|
|
|
field.name,
|
|
|
|
|
|
date ? dayjs(date).format('YYYY-MM-DDTHH:mm:ss') : null,
|
|
|
|
|
|
)
|
|
|
|
|
|
}}
|
|
|
|
|
|
/>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</Field>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
</div>
|
2026-05-05 07:23:02 +00:00
|
|
|
|
|
2026-05-25 09:14:42 +00:00
|
|
|
|
<div>
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
label={translate('::Abp.Identity.User.UserInformation.BirthPlace')}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
name="birthPlace"
|
|
|
|
|
|
placeholder={translate(
|
|
|
|
|
|
'::Abp.Identity.User.UserInformation.BirthPlace',
|
|
|
|
|
|
)}
|
|
|
|
|
|
component={Input}
|
2026-05-27 22:30:13 +00:00
|
|
|
|
prefix={<FaMapMarkerAlt className="text-xl" />}
|
2026-05-25 09:14:42 +00:00
|
|
|
|
/>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
</div>
|
2026-05-05 07:23:02 +00:00
|
|
|
|
|
2026-05-25 09:14:42 +00:00
|
|
|
|
<div>
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
label={translate('::Abp.Identity.User.UserInformation.BirthDate')}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field name="birthDate">
|
|
|
|
|
|
{({ field, form }: FieldProps) => (
|
|
|
|
|
|
<DatePicker
|
|
|
|
|
|
field={field}
|
|
|
|
|
|
form={form}
|
|
|
|
|
|
value={field.value ? dayjs(field.value).toDate() : null}
|
|
|
|
|
|
placeholder={translate(
|
|
|
|
|
|
'::Abp.Identity.User.UserInformation.BirthDate',
|
|
|
|
|
|
)}
|
2026-05-27 22:30:13 +00:00
|
|
|
|
inputPrefix={<FaCalendarAlt className="text-xl" />}
|
2026-05-25 09:14:42 +00:00
|
|
|
|
onChange={(date) => {
|
|
|
|
|
|
form.setFieldValue(
|
|
|
|
|
|
field.name,
|
|
|
|
|
|
date ? dayjs(date).format('YYYY-MM-DDTHH:mm:ss') : null,
|
|
|
|
|
|
)
|
|
|
|
|
|
}}
|
|
|
|
|
|
/>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</Field>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
</div>
|
2026-05-05 07:23:02 +00:00
|
|
|
|
|
2026-05-25 09:14:42 +00:00
|
|
|
|
<div>
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
label={translate('::Abp.Identity.User.UserInformation.FatherName')}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
name="fatherName"
|
|
|
|
|
|
placeholder={translate(
|
|
|
|
|
|
'::Abp.Identity.User.UserInformation.FatherName',
|
|
|
|
|
|
)}
|
|
|
|
|
|
component={Input}
|
2026-05-27 22:30:13 +00:00
|
|
|
|
prefix={<FaUserTie className="text-xl" />}
|
2026-05-25 09:14:42 +00:00
|
|
|
|
/>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
</div>
|
2026-05-05 07:23:02 +00:00
|
|
|
|
|
2026-05-25 09:14:42 +00:00
|
|
|
|
<div>
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
label={translate('::Abp.Identity.User.UserInformation.MotherName')}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
name="motherName"
|
|
|
|
|
|
placeholder={translate(
|
|
|
|
|
|
'::Abp.Identity.User.UserInformation.MotherName',
|
|
|
|
|
|
)}
|
|
|
|
|
|
component={Input}
|
2026-05-27 22:30:13 +00:00
|
|
|
|
prefix={<FaFemale className="text-xl" />}
|
2026-05-25 09:14:42 +00:00
|
|
|
|
/>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
</div>
|
2026-05-05 07:23:02 +00:00
|
|
|
|
|
2026-05-25 09:14:42 +00:00
|
|
|
|
<div>
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
label={translate('::Abp.Identity.User.UserInformation.MaritalStatus')}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field type="text" name="maritalStatus">
|
|
|
|
|
|
{({ field, form }: FieldProps<SelectBoxOption>) => (
|
|
|
|
|
|
<Select
|
|
|
|
|
|
field={field}
|
|
|
|
|
|
form={form}
|
|
|
|
|
|
options={maritalStatusOptions}
|
|
|
|
|
|
isClearable={true}
|
|
|
|
|
|
value={maritalStatusOptions.filter(
|
|
|
|
|
|
(o) => o.value === values.maritalStatus,
|
|
|
|
|
|
)}
|
|
|
|
|
|
onChange={(option) =>
|
|
|
|
|
|
form.setFieldValue(field.name, option?.value ?? null)
|
|
|
|
|
|
}
|
|
|
|
|
|
/>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</Field>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
</div>
|
2026-05-05 07:23:02 +00:00
|
|
|
|
|
2026-05-25 09:14:42 +00:00
|
|
|
|
<div>
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
label={translate('::Abp.Identity.User.UserInformation.MarriageDate')}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field name="marriageDate">
|
|
|
|
|
|
{({ field, form }: FieldProps) => (
|
|
|
|
|
|
<DatePicker
|
|
|
|
|
|
field={field}
|
|
|
|
|
|
form={form}
|
|
|
|
|
|
value={field.value ? dayjs(field.value).toDate() : null}
|
|
|
|
|
|
placeholder={translate(
|
|
|
|
|
|
'::Abp.Identity.User.UserInformation.MarriageDate',
|
|
|
|
|
|
)}
|
2026-05-27 22:30:13 +00:00
|
|
|
|
inputPrefix={<FaHeart className="text-xl" />}
|
2026-05-25 09:14:42 +00:00
|
|
|
|
onChange={(date) => {
|
|
|
|
|
|
form.setFieldValue(
|
|
|
|
|
|
field.name,
|
|
|
|
|
|
date ? dayjs(date).format('YYYY-MM-DDTHH:mm:ss') : null,
|
|
|
|
|
|
)
|
|
|
|
|
|
}}
|
|
|
|
|
|
/>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</Field>
|
|
|
|
|
|
</FormItem>
|
2026-05-05 07:23:02 +00:00
|
|
|
|
</div>
|
2026-05-25 09:14:42 +00:00
|
|
|
|
</div>
|
|
|
|
|
|
</FormContainer>
|
2026-05-05 07:23:02 +00:00
|
|
|
|
|
2026-05-27 22:30:13 +00:00
|
|
|
|
<div className="mt-4 ltr:text-right">
|
|
|
|
|
|
<Button variant="solid" loading={isSubmitting} type="submit">
|
|
|
|
|
|
{isSubmitting ? translate('::SavingWithThreeDot') : translate('::Save')}
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</div>
|
2026-05-05 07:23:02 +00:00
|
|
|
|
</Form>
|
|
|
|
|
|
)
|
|
|
|
|
|
}}
|
|
|
|
|
|
</Formik>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</TabContent>
|
|
|
|
|
|
|
2026-02-24 20:44:16 +00:00
|
|
|
|
<TabContent value="lockout">
|
2026-05-27 22:30:13 +00:00
|
|
|
|
<div className="px-4 py-6">
|
2026-02-24 20:44:16 +00:00
|
|
|
|
<Formik
|
|
|
|
|
|
initialValues={userDetails}
|
|
|
|
|
|
onSubmit={async (values, { setSubmitting }) => {
|
|
|
|
|
|
setSubmitting(true)
|
|
|
|
|
|
|
|
|
|
|
|
await putUserLookout({ ...values })
|
|
|
|
|
|
|
|
|
|
|
|
toast.push(
|
|
|
|
|
|
<Notification type="success" duration={2000}>
|
2026-05-04 14:35:18 +00:00
|
|
|
|
{translate('::Abp.Identity.User.SaveLockout')}
|
2026-02-24 20:44:16 +00:00
|
|
|
|
</Notification>,
|
|
|
|
|
|
{
|
|
|
|
|
|
placement: 'top-end',
|
|
|
|
|
|
},
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
getUser()
|
|
|
|
|
|
|
|
|
|
|
|
setSubmitting(false)
|
|
|
|
|
|
}}
|
|
|
|
|
|
>
|
2026-04-26 19:05:19 +00:00
|
|
|
|
{({ isSubmitting, values }) => {
|
|
|
|
|
|
const workHours = values.workHours
|
|
|
|
|
|
|
|
|
|
|
|
const workHourOptions: SelectBoxOption[] = workHours.map((workHour) => ({
|
|
|
|
|
|
value: workHour.name,
|
|
|
|
|
|
label: workHour.name,
|
|
|
|
|
|
}))
|
|
|
|
|
|
|
2026-02-24 20:44:16 +00:00
|
|
|
|
return (
|
|
|
|
|
|
<Form>
|
2026-05-25 09:14:42 +00:00
|
|
|
|
<FormContainer size="md">
|
2026-05-27 22:30:13 +00:00
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5 w-full">
|
2026-05-25 09:14:42 +00:00
|
|
|
|
{/* Account Status */}
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<h6 className="mb-4">
|
|
|
|
|
|
{translate('::Abp.Identity.User.LockoutManagement.AccountStatus')}
|
|
|
|
|
|
</h6>
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
layout="horizontal"
|
|
|
|
|
|
labelClass="!justify-start"
|
|
|
|
|
|
labelWidth="50%"
|
|
|
|
|
|
label={translate('::Abp.Identity.User.LockoutManagement.Status')}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field
|
|
|
|
|
|
name="isActive"
|
|
|
|
|
|
placeholder={translate(
|
|
|
|
|
|
'::Abp.Identity.User.LockoutManagement.Status',
|
|
|
|
|
|
)}
|
|
|
|
|
|
component={Checkbox}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
|
2026-06-03 21:38:21 +00:00
|
|
|
|
{isRequireVerifiedAccount?.toLowerCase() === 'true' && (
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
layout="horizontal"
|
|
|
|
|
|
labelClass="!justify-start"
|
|
|
|
|
|
labelWidth="50%"
|
|
|
|
|
|
label={translate(
|
2026-02-24 20:44:16 +00:00
|
|
|
|
'::Abp.Identity.User.LockoutManagement.AdminVerification',
|
|
|
|
|
|
)}
|
2026-06-03 21:38:21 +00:00
|
|
|
|
>
|
|
|
|
|
|
<Field
|
|
|
|
|
|
name="isVerified"
|
|
|
|
|
|
disabled={isRequireVerifiedAccount?.toLowerCase() !== 'true'}
|
|
|
|
|
|
placeholder={translate(
|
|
|
|
|
|
'::Abp.Identity.User.LockoutManagement.AdminVerification',
|
|
|
|
|
|
)}
|
|
|
|
|
|
component={Checkbox}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
)}
|
2026-05-25 09:14:42 +00:00
|
|
|
|
|
2026-06-03 21:38:21 +00:00
|
|
|
|
{isRequireConfirmedEmail?.toLowerCase() === 'true' && (
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
layout="horizontal"
|
|
|
|
|
|
labelClass="!justify-start"
|
|
|
|
|
|
labelWidth="50%"
|
|
|
|
|
|
label={translate(
|
2026-02-24 20:44:16 +00:00
|
|
|
|
'::Abp.Identity.User.LockoutManagement.EmailConfirmed',
|
|
|
|
|
|
)}
|
2026-06-03 21:38:21 +00:00
|
|
|
|
>
|
|
|
|
|
|
<Field
|
|
|
|
|
|
name="emailConfirmed"
|
|
|
|
|
|
disabled={isRequireConfirmedEmail?.toLowerCase() !== 'true'}
|
|
|
|
|
|
placeholder={translate(
|
|
|
|
|
|
'::Abp.Identity.User.LockoutManagement.EmailConfirmed',
|
|
|
|
|
|
)}
|
|
|
|
|
|
component={Checkbox}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
)}
|
2026-05-25 09:14:42 +00:00
|
|
|
|
|
2026-06-03 21:38:21 +00:00
|
|
|
|
{isRequireConfirmedPhoneNumber?.toLowerCase() === 'true' && (
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
layout="horizontal"
|
|
|
|
|
|
labelClass="!justify-start"
|
|
|
|
|
|
labelWidth="50%"
|
|
|
|
|
|
label={translate(
|
2026-02-24 20:44:16 +00:00
|
|
|
|
'::Abp.Identity.User.LockoutManagement.PhoneNumberConfirmed',
|
|
|
|
|
|
)}
|
2026-06-03 21:38:21 +00:00
|
|
|
|
>
|
|
|
|
|
|
<Field
|
|
|
|
|
|
name="phoneNumberConfirmed"
|
|
|
|
|
|
disabled={isRequireConfirmedPhoneNumber?.toLowerCase() !== 'true'}
|
|
|
|
|
|
placeholder={translate(
|
|
|
|
|
|
'::Abp.Identity.User.LockoutManagement.PhoneNumberConfirmed',
|
|
|
|
|
|
)}
|
|
|
|
|
|
component={Checkbox}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
)}
|
2026-05-25 09:14:42 +00:00
|
|
|
|
|
2026-06-03 21:38:21 +00:00
|
|
|
|
{isTwoFactorEnabled?.toLowerCase() === 'true' && (
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
layout="horizontal"
|
|
|
|
|
|
labelClass="!justify-start"
|
|
|
|
|
|
labelWidth="50%"
|
|
|
|
|
|
label={translate(
|
2026-02-24 20:44:16 +00:00
|
|
|
|
'::Abp.Identity.User.LockoutManagement.TwoFactorEnabled',
|
|
|
|
|
|
)}
|
2026-06-03 21:38:21 +00:00
|
|
|
|
>
|
|
|
|
|
|
<Field
|
|
|
|
|
|
name="twoFactorEnabled"
|
|
|
|
|
|
disabled={isTwoFactorEnabled?.toLowerCase() !== 'true'}
|
|
|
|
|
|
placeholder={translate(
|
|
|
|
|
|
'::Abp.Identity.User.LockoutManagement.TwoFactorEnabled',
|
|
|
|
|
|
)}
|
|
|
|
|
|
component={Checkbox}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
)}
|
2026-05-25 09:14:42 +00:00
|
|
|
|
</div>
|
2026-02-24 20:44:16 +00:00
|
|
|
|
|
2026-05-25 09:14:42 +00:00
|
|
|
|
{/* Login & Lockout Settings */}
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<h6 className="mb-4">
|
|
|
|
|
|
{translate(
|
|
|
|
|
|
'::Abp.Identity.User.LockoutManagement.LoginAndLockoutSettings',
|
|
|
|
|
|
)}
|
|
|
|
|
|
</h6>
|
|
|
|
|
|
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
layout="horizontal"
|
|
|
|
|
|
labelClass="!justify-start"
|
|
|
|
|
|
labelWidth="50%"
|
|
|
|
|
|
label={translate(
|
|
|
|
|
|
'::Abp.Identity.User.LockoutManagement.AccountLockoutEnabled',
|
|
|
|
|
|
)}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field
|
|
|
|
|
|
name="lockoutEnabled"
|
|
|
|
|
|
placeholder={translate(
|
2026-02-24 20:44:16 +00:00
|
|
|
|
'::Abp.Identity.User.LockoutManagement.AccountLockoutEnabled',
|
|
|
|
|
|
)}
|
2026-05-25 09:14:42 +00:00
|
|
|
|
component={Checkbox}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
layout="horizontal"
|
|
|
|
|
|
labelClass="!justify-start"
|
|
|
|
|
|
labelWidth="50%"
|
|
|
|
|
|
label={translate(
|
|
|
|
|
|
'::Abp.Identity.User.LockoutManagement.AccountLocked',
|
|
|
|
|
|
)}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field
|
|
|
|
|
|
name="lockUser"
|
|
|
|
|
|
placeholder={translate(
|
2026-02-24 20:44:16 +00:00
|
|
|
|
'::Abp.Identity.User.LockoutManagement.AccountLocked',
|
|
|
|
|
|
)}
|
2026-05-25 09:14:42 +00:00
|
|
|
|
component={Checkbox}
|
|
|
|
|
|
disabled={values.lockoutEnabled === false}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
layout="horizontal"
|
|
|
|
|
|
labelClass="!justify-start"
|
|
|
|
|
|
labelWidth="50%"
|
|
|
|
|
|
label={translate(
|
|
|
|
|
|
'::Abp.Identity.User.LockoutManagement.AccountEndDate',
|
|
|
|
|
|
)}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field name="lockoutEnd">
|
|
|
|
|
|
{({ field, form }: FieldProps) => (
|
|
|
|
|
|
<DatePicker
|
|
|
|
|
|
field={field}
|
|
|
|
|
|
form={form}
|
|
|
|
|
|
value={field.value ? dayjs(field.value).toDate() : null}
|
|
|
|
|
|
placeholder={translate(
|
|
|
|
|
|
'::Abp.Identity.User.LockoutManagement.AccountEndDate',
|
|
|
|
|
|
)}
|
2026-05-27 22:30:13 +00:00
|
|
|
|
inputPrefix={<FaCalendarAlt className="text-xl" />}
|
2026-05-25 09:14:42 +00:00
|
|
|
|
onChange={(date) => {
|
|
|
|
|
|
form.setFieldValue(
|
|
|
|
|
|
field.name,
|
|
|
|
|
|
date ? dayjs(date).format('YYYY-MM-DDTHH:mm:ss') : null,
|
|
|
|
|
|
)
|
|
|
|
|
|
}}
|
|
|
|
|
|
disabled={values.lockoutEnabled === false}
|
|
|
|
|
|
/>
|
2026-02-24 20:44:16 +00:00
|
|
|
|
)}
|
2026-05-25 09:14:42 +00:00
|
|
|
|
</Field>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
layout="horizontal"
|
|
|
|
|
|
labelClass="!justify-start"
|
|
|
|
|
|
labelWidth="50%"
|
|
|
|
|
|
label={translate(
|
|
|
|
|
|
'::Abp.Identity.User.LockoutManagement.ShouldChangePwOnNextLogin',
|
|
|
|
|
|
)}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field
|
|
|
|
|
|
name="shouldChangePasswordOnNextLogin"
|
|
|
|
|
|
placeholder={translate(
|
2026-02-24 20:44:16 +00:00
|
|
|
|
'::Abp.Identity.User.LockoutManagement.ShouldChangePwOnNextLogin',
|
|
|
|
|
|
)}
|
2026-05-25 09:14:42 +00:00
|
|
|
|
component={Checkbox}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
layout="horizontal"
|
|
|
|
|
|
labelClass="!justify-start"
|
|
|
|
|
|
labelWidth="50%"
|
|
|
|
|
|
label={translate(
|
|
|
|
|
|
'::Abp.Identity.User.LockoutManagement.AccessFailedCount',
|
|
|
|
|
|
)}
|
|
|
|
|
|
>
|
2026-05-27 22:30:13 +00:00
|
|
|
|
<Field
|
|
|
|
|
|
type="number"
|
|
|
|
|
|
name="accessFailedCount"
|
|
|
|
|
|
component={Input}
|
|
|
|
|
|
prefix={<FaExclamationTriangle className="text-xl" />}
|
|
|
|
|
|
/>
|
2026-05-25 09:14:42 +00:00
|
|
|
|
</FormItem>
|
|
|
|
|
|
</div>
|
2026-02-24 20:44:16 +00:00
|
|
|
|
|
2026-05-25 09:14:42 +00:00
|
|
|
|
{/* Login & Lockout Settings */}
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<h6 className="mb-4">
|
|
|
|
|
|
{translate('::Abp.Identity.User.LockoutManagement.ConnectionsTimes')}
|
|
|
|
|
|
</h6>
|
|
|
|
|
|
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
layout="horizontal"
|
|
|
|
|
|
labelClass="!justify-start"
|
|
|
|
|
|
labelWidth="50%"
|
|
|
|
|
|
label={translate('::Abp.Identity.User.LockoutManagement.WorkHour')}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field type="text" name="workHour">
|
|
|
|
|
|
{({ field, form }: FieldProps<SelectBoxOption>) => (
|
|
|
|
|
|
<Select
|
|
|
|
|
|
field={field}
|
|
|
|
|
|
form={form}
|
|
|
|
|
|
options={workHourOptions}
|
|
|
|
|
|
isClearable={true}
|
|
|
|
|
|
value={workHourOptions.filter(
|
|
|
|
|
|
(option) => option.value === values.workHour,
|
|
|
|
|
|
)}
|
|
|
|
|
|
onChange={(option) =>
|
|
|
|
|
|
form.setFieldValue(field.name, option?.value)
|
|
|
|
|
|
}
|
|
|
|
|
|
/>
|
2026-02-24 20:44:16 +00:00
|
|
|
|
)}
|
2026-05-25 09:14:42 +00:00
|
|
|
|
</Field>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
layout="horizontal"
|
|
|
|
|
|
labelClass="!justify-start"
|
|
|
|
|
|
labelWidth="50%"
|
|
|
|
|
|
label={translate(
|
|
|
|
|
|
'::Abp.Identity.User.LockoutManagement.LoginEndDate',
|
|
|
|
|
|
)}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field name="loginEndDate">
|
|
|
|
|
|
{({ field, form }: FieldProps) => (
|
|
|
|
|
|
<DatePicker
|
|
|
|
|
|
field={field}
|
|
|
|
|
|
form={form}
|
|
|
|
|
|
value={field.value ? dayjs(field.value).toDate() : null}
|
|
|
|
|
|
placeholder={translate(
|
|
|
|
|
|
'::Abp.Identity.User.LockoutManagement.LoginEndDate',
|
|
|
|
|
|
)}
|
2026-05-27 22:30:13 +00:00
|
|
|
|
inputPrefix={<FaCalendarAlt className="text-xl" />}
|
2026-05-25 09:14:42 +00:00
|
|
|
|
onChange={(date) => {
|
|
|
|
|
|
form.setFieldValue(
|
|
|
|
|
|
field.name,
|
|
|
|
|
|
date ? dayjs(date).format('YYYY-MM-DDTHH:mm:ss') : null,
|
|
|
|
|
|
)
|
|
|
|
|
|
}}
|
|
|
|
|
|
/>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</Field>
|
|
|
|
|
|
</FormItem>
|
2026-05-27 22:30:13 +00:00
|
|
|
|
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
layout="horizontal"
|
|
|
|
|
|
labelClass="!justify-start"
|
|
|
|
|
|
labelWidth="50%"
|
|
|
|
|
|
label={translate(
|
|
|
|
|
|
'::Abp.Identity.User.UserInformation.PasswordChangeTime',
|
|
|
|
|
|
)}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field name="lastPasswordChangeTime">
|
|
|
|
|
|
{({ field, form }: FieldProps) => (
|
|
|
|
|
|
<DateTimepicker
|
|
|
|
|
|
inputFormat="DD/MM/YYYY HH:mm"
|
|
|
|
|
|
field={field}
|
|
|
|
|
|
form={form}
|
|
|
|
|
|
value={field.value ? dayjs(field.value).toDate() : null}
|
|
|
|
|
|
placeholder="Select Date"
|
|
|
|
|
|
inputPrefix={<FaCalendarAlt className="text-xl" />}
|
|
|
|
|
|
onChange={(date: any) => {
|
|
|
|
|
|
form.setFieldValue(
|
|
|
|
|
|
field.name,
|
|
|
|
|
|
date ? dayjs(date).format('YYYY-MM-DDTHH:mm:ss') : null,
|
|
|
|
|
|
)
|
|
|
|
|
|
}}
|
|
|
|
|
|
/>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</Field>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
layout="horizontal"
|
|
|
|
|
|
labelClass="!justify-start"
|
|
|
|
|
|
labelWidth="50%"
|
|
|
|
|
|
label={translate('::Abp.Identity.User.UserInformation.CreateTime')}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field name="creationTime">
|
|
|
|
|
|
{({ field, form }: FieldProps) => (
|
|
|
|
|
|
<Input
|
|
|
|
|
|
field={field}
|
|
|
|
|
|
form={form}
|
|
|
|
|
|
value={
|
|
|
|
|
|
field.value
|
|
|
|
|
|
? dayjs(field.value).format('DD/MM/YYYY HH:mm')
|
|
|
|
|
|
: undefined
|
|
|
|
|
|
}
|
|
|
|
|
|
disabled
|
|
|
|
|
|
prefix={<FaCalendarAlt className="text-xl" />}
|
|
|
|
|
|
/>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</Field>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
layout="horizontal"
|
|
|
|
|
|
labelClass="!justify-start"
|
|
|
|
|
|
labelWidth="50%"
|
|
|
|
|
|
label={translate('::Abp.Identity.User.UserInformation.UpdateTime')}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field name="lastModificationTime">
|
|
|
|
|
|
{({ field, form }: FieldProps) => (
|
|
|
|
|
|
<Input
|
|
|
|
|
|
field={field}
|
|
|
|
|
|
form={form}
|
|
|
|
|
|
value={
|
|
|
|
|
|
field.value
|
|
|
|
|
|
? dayjs(field.value).format('DD/MM/YYYY HH:mm')
|
|
|
|
|
|
: undefined
|
|
|
|
|
|
}
|
|
|
|
|
|
disabled
|
|
|
|
|
|
prefix={<FaCalendarAlt className="text-xl" />}
|
|
|
|
|
|
/>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</Field>
|
|
|
|
|
|
</FormItem>
|
2026-02-24 20:44:16 +00:00
|
|
|
|
</div>
|
2026-05-25 09:14:42 +00:00
|
|
|
|
</div>
|
|
|
|
|
|
</FormContainer>
|
2026-02-24 20:44:16 +00:00
|
|
|
|
|
2026-05-27 22:30:13 +00:00
|
|
|
|
<div className="mt-4 ltr:text-right">
|
|
|
|
|
|
<Button variant="solid" loading={isSubmitting} type="submit">
|
|
|
|
|
|
{isSubmitting ? translate('::SavingWithThreeDot') : translate('::Save')}
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</div>
|
2026-02-24 20:44:16 +00:00
|
|
|
|
</Form>
|
|
|
|
|
|
)
|
|
|
|
|
|
}}
|
|
|
|
|
|
</Formik>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</TabContent>
|
2026-05-05 07:23:02 +00:00
|
|
|
|
|
2026-02-24 20:44:16 +00:00
|
|
|
|
<TabContent value="claimTypes">
|
2026-05-27 22:30:13 +00:00
|
|
|
|
<div className="px-4 py-6">
|
2026-02-24 20:44:16 +00:00
|
|
|
|
<Table compact>
|
|
|
|
|
|
<THead>
|
|
|
|
|
|
<Tr>
|
|
|
|
|
|
<Th className="text-center">
|
|
|
|
|
|
<Button
|
|
|
|
|
|
shape="circle"
|
|
|
|
|
|
variant="plain"
|
|
|
|
|
|
type="button"
|
2026-05-05 17:59:30 +00:00
|
|
|
|
size="sm"
|
2026-02-24 20:44:16 +00:00
|
|
|
|
title="Add"
|
|
|
|
|
|
icon={<FaFileAlt />}
|
|
|
|
|
|
onClick={async (e) => {
|
|
|
|
|
|
setOpen(true)
|
|
|
|
|
|
}}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</Th>
|
|
|
|
|
|
<Th>{translate('::Abp.Identity.User.ClaimType')}</Th>
|
|
|
|
|
|
<Th>{translate('::Abp.Identity.User.ClaimValue')}</Th>
|
|
|
|
|
|
</Tr>
|
|
|
|
|
|
</THead>
|
|
|
|
|
|
<TBody>
|
|
|
|
|
|
{userDetails.claims.filter((a) => a.isAssigned === true) &&
|
|
|
|
|
|
userDetails.claims.filter((a) => a.isAssigned === true).length > 0 ? (
|
|
|
|
|
|
userDetails.claims.map((claim) => (
|
|
|
|
|
|
<Tr key={claim.id}>
|
|
|
|
|
|
<Td>
|
|
|
|
|
|
<Button
|
|
|
|
|
|
shape="circle"
|
|
|
|
|
|
variant="plain"
|
|
|
|
|
|
type="button"
|
2026-05-05 17:59:30 +00:00
|
|
|
|
size="sm"
|
2026-02-24 20:44:16 +00:00
|
|
|
|
title="Delete"
|
|
|
|
|
|
icon={<FaTrashAlt />}
|
|
|
|
|
|
onClick={() => setConfirmDeleteClaim(claim)}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</Td>
|
|
|
|
|
|
<Td>{claim.claimType}</Td>
|
|
|
|
|
|
<Td>{claim.claimValue}</Td>
|
|
|
|
|
|
</Tr>
|
|
|
|
|
|
))
|
|
|
|
|
|
) : (
|
|
|
|
|
|
<Tr>
|
|
|
|
|
|
<Td colSpan={3} className="text-center">
|
|
|
|
|
|
{translate('::Abp.Identity.User.NoClaimsFound')}
|
|
|
|
|
|
</Td>
|
|
|
|
|
|
</Tr>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</TBody>
|
|
|
|
|
|
</Table>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</TabContent>
|
|
|
|
|
|
</Tabs>
|
2026-05-27 22:30:13 +00:00
|
|
|
|
</AdaptableCard>
|
2026-02-24 20:44:16 +00:00
|
|
|
|
|
|
|
|
|
|
<Dialog isOpen={open} onClose={() => setOpen(false)} onRequestClose={() => setOpen(false)}>
|
|
|
|
|
|
<Formik
|
|
|
|
|
|
initialValues={{ claimType: '', claimValue: '' }}
|
|
|
|
|
|
validationSchema={scheme}
|
|
|
|
|
|
onSubmit={handleSubmit}
|
|
|
|
|
|
>
|
|
|
|
|
|
{({ touched, errors, values, isSubmitting }) => {
|
|
|
|
|
|
const claimOptions: SelectBoxOption[] = userDetails?.claims.map((claim) => ({
|
|
|
|
|
|
value: claim.claimType,
|
|
|
|
|
|
label: claim.claimType,
|
|
|
|
|
|
}))
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<Form>
|
|
|
|
|
|
<FormContainer size="sm">
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
label={translate('::Abp.Identity.User.ClaimType')}
|
|
|
|
|
|
invalid={errors.claimType && touched.claimType}
|
|
|
|
|
|
errorMessage={errors.claimType}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Field type="text" name="claimType">
|
|
|
|
|
|
{({ field, form }: FieldProps<SelectBoxOption>) => (
|
|
|
|
|
|
<Select
|
|
|
|
|
|
field={field}
|
|
|
|
|
|
form={form}
|
|
|
|
|
|
options={claimOptions}
|
|
|
|
|
|
isClearable={true}
|
|
|
|
|
|
value={claimOptions.filter((option) => option.value === values.claimType)}
|
|
|
|
|
|
onChange={(option) => form.setFieldValue(field.name, option?.value)}
|
|
|
|
|
|
/>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</Field>
|
|
|
|
|
|
</FormItem>
|
|
|
|
|
|
|
|
|
|
|
|
<FormItem
|
|
|
|
|
|
label={translate('::Abp.Identity.User.ClaimValue')}
|
|
|
|
|
|
invalid={errors.claimValue && touched.claimValue}
|
|
|
|
|
|
errorMessage={errors.claimValue}
|
|
|
|
|
|
>
|
2026-05-27 22:30:13 +00:00
|
|
|
|
<Field
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
autoComplete="off"
|
|
|
|
|
|
name="claimValue"
|
|
|
|
|
|
component={Input}
|
|
|
|
|
|
prefix={<FaFileAlt className="text-xl" />}
|
|
|
|
|
|
/>
|
2026-02-24 20:44:16 +00:00
|
|
|
|
</FormItem>
|
|
|
|
|
|
|
|
|
|
|
|
<div className="mt-6 flex flex-row justify-end gap-3">
|
|
|
|
|
|
<Button variant="solid" loading={isSubmitting} type="submit">
|
|
|
|
|
|
{isSubmitting ? translate('::SavingWithThreeDot') : translate('::Save')}
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
<Button type="button" variant="plain" onClick={() => setOpen(false)}>
|
|
|
|
|
|
{translate('::Cancel')}
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</FormContainer>
|
|
|
|
|
|
</Form>
|
|
|
|
|
|
)
|
|
|
|
|
|
}}
|
|
|
|
|
|
</Formik>
|
|
|
|
|
|
</Dialog>
|
|
|
|
|
|
|
|
|
|
|
|
<ConfirmDialog
|
|
|
|
|
|
isOpen={!!confirmDeleteClaim}
|
|
|
|
|
|
type="danger"
|
|
|
|
|
|
title={translate('::DeleteConfirmation')}
|
|
|
|
|
|
confirmText={translate('::Delete')}
|
|
|
|
|
|
cancelText={translate('::Cancel')}
|
|
|
|
|
|
confirmButtonColor="red-600"
|
|
|
|
|
|
onCancel={() => setConfirmDeleteClaim(null)}
|
|
|
|
|
|
onConfirm={async () => {
|
|
|
|
|
|
if (confirmDeleteClaim) {
|
|
|
|
|
|
await deleteClaimUser(confirmDeleteClaim.id, userId)
|
|
|
|
|
|
toast.push(
|
|
|
|
|
|
<Notification type="success" duration={2000}>
|
|
|
|
|
|
{translate('::Abp.Identity.User.ClaimDeleted')}
|
|
|
|
|
|
</Notification>,
|
|
|
|
|
|
{ placement: 'top-end' },
|
|
|
|
|
|
)
|
|
|
|
|
|
setConfirmDeleteClaim(null)
|
|
|
|
|
|
getUser()
|
|
|
|
|
|
}
|
|
|
|
|
|
}}
|
|
|
|
|
|
>
|
|
|
|
|
|
<p>
|
|
|
|
|
|
<span className="font-semibold">{confirmDeleteClaim?.claimType}</span> claim silmek
|
|
|
|
|
|
istediğinize emin misiniz?
|
|
|
|
|
|
</p>
|
|
|
|
|
|
</ConfirmDialog>
|
|
|
|
|
|
</>
|
|
|
|
|
|
) : (
|
|
|
|
|
|
<></>
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export default UserDetails
|