Client Portal - Employee Data

This commit is contained in:
Muhammad Fajar
2024-01-06 11:40:40 +07:00
parent 37b8229fc2
commit 23081382ce
8 changed files with 577 additions and 58 deletions

View File

@@ -0,0 +1,46 @@
<?php
namespace Modules\Client\Transformers\EmployeeData\UserProfile;
use Illuminate\Http\Resources\Json\JsonResource;
class DataMemberResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request
* @return array
*/
public function toArray($request)
{
return [
'person' => [
'name' => $this->full_name ?? null,
'weight' => $this->person->last_weight_kg ?? null,
'height' => $this->person->last_height_kg ?? null,
'placeOfBirth' => ucwords($this->person->birth_place) ?? null,
'dateOfBirth' => $this->birth_date ?? $this->person->birth_date,
'gender' => ucwords(strtolower($this->gender ?? $this->person->gender)),
'phoneNumber' => $this->person->phone ?? null,
'email' => $this->email ?? ($this->person->email ?? null),
'address' => $this->person->last_height_kg ?? null,
'idNumber' => $this->person->nik ?? null,
'religion' => ucwords(strtolower($this->person->religion)) ?? null,
'maritalStatus' => $this->marital_status,
'education' => ucwords(strtolower($this->person->last_education)) ?? null,
'occupation' => null,
],
'families' => collect($this->families)->map(function ($family) {
return [
'name' => $family->full_name ?? null,
'relationship' => $family->relationship ?? null,
'dateOfBirth' => $family->birth_date ?? $family->person->birth_date,
'email' => $this->email ?? ($this->person->email ?? null),
'phoneNumber' => $this->person->phone ?? null,
'status' => $this->status ?? null
];
})->all()
];
}
}

View File

@@ -40,7 +40,7 @@ class Person extends Model
'updated_by',
'deleted_by'
];
protected $hidden = [
'created_at',
'updated_at',
@@ -126,6 +126,11 @@ class Person extends Model
return $this->morphMany(AppointmentParticipant::class, 'participantable');
}
public function member()
{
return $this->hasOne(Member::class);
}
public function setGenderAttribute($value)
{
if ($value == "M" || $value == "L") {
@@ -139,7 +144,6 @@ class Person extends Model
public function getGenderAttribute()
{
if ($this->attributes['gender'] == "male" || $this->attributes['gender'] == "L") {
return "male";
} else if ($this->attributes['gender'] == "female" || $this->attributes['gender'] == "P") {
@@ -148,9 +152,4 @@ class Person extends Model
return "other";
}
}
public function updatePerson()
{
$this-> update ( $data );
}
}

View File

@@ -1,21 +1,45 @@
// ----------------------------------------------------------------------
export type Member = {
id: string,
member_id: string,
record_type: string,
payor_id: string,
user_id: string,
name_prefix: string,
name: string,
name_suffix: string,
birth_date: string,
gender: string,
language: string,
race: string,
marital_status: string,
principal_id: string,
relation_with_principal: string,
bpjs_class: string,
active: string,
id: string;
member_id: string;
record_type: string;
payor_id: string;
user_id: string;
name_prefix: string;
name: string;
name_suffix: string;
birth_date: string;
gender: string;
language: string;
race: string;
marital_status: string;
principal_id: string;
relation_with_principal: string;
bpjs_class: string;
active: string;
};
export type PersonalInformationType = {
name: string;
weight: number;
height: number;
placeOfBirth: string;
dateOfBirth: string;
gender: string;
phoneNumber: string;
email: string;
address: string;
idNumber: string;
religion: string;
maritalStatus: string;
education: string;
occupation: string;
};
export type FamilyInformationtype = {
name: string;
relationship: string;
dateOfBirth: string;
email: string;
phoneNumber: string;
status: string;
};

View File

@@ -33,8 +33,6 @@ export default function AccountPopover() {
const navigate = useNavigate();
const { logout, user } = useAuth();
console.log(user);
const handleOpen = (event: React.MouseEvent<HTMLElement>) => {
setOpen(event.currentTarget);
};

View File

@@ -1,68 +1,72 @@
// mui
import { IconButton, Container, Grid, Stack, Typography } from '@mui/material';
import { Container, Grid, Stack, Typography } from '@mui/material';
// components
import Page from '../../components/Page';
import Iconify from '../../components/Iconify';
// utils
import useSettings from '../../hooks/useSettings';
// section
import CardPersonalInformation from '../../sections/alarm-center/user-profile/CardPersonalInformation';
import CardFamilyInformation from '../../sections/alarm-center/user-profile/CardFamilyInformation';
import CardPolicyNumber from '../../sections/alarm-center/user-profile/CardPolicyNumber';
import CardBenefitSummary from '../../sections/alarm-center/user-profile/CardBenefitSummary';
import CardClaimHistory from '../../sections/alarm-center/user-profile/CardClaimHistory';
// react
import { useNavigate, useParams } from 'react-router-dom';
import ButtonBack from '../../components/ButtonBack';
import { useEffect, useState, useContext } from 'react';
import axios from '../../utils/axios';
import { UserCurrentCorporateContext } from '../../contexts/UserCurrentCorporate';
import ArrowBackIosIcon from '@mui/icons-material/ArrowBackIos';
import CardPersonalInformation from '../../sections/employee-data/user-profile/CardPersonalInformation';
import CardFamilyInformation from '../../sections/employee-data/user-profile/CardFamilyInformation';
import { FamilyInformationtype, PersonalInformationType } from '../../@types/member';
// ----------------------------------------------------------------------
type UserProfileDataType = {
person: PersonalInformationType;
families: FamilyInformationtype[];
};
export default function UserProfile() {
const { themeStretch } = useSettings();
const navigate = useNavigate();
const [data, setData] = useState();
const [data, setData] = useState<UserProfileDataType>();
const { corporateValue } = useContext(UserCurrentCorporateContext);
const { id } = useParams();
useEffect(() => {
axios
.get(corporateValue + '/members/' + id)
.then((response) => {
setData(response.data);
})
.catch((error) => {
console.error(error);
});
(async () => {
await axios
.get(corporateValue + '/members/' + id)
.then((response) => {
setTimeout(() => {
console.log(response.data);
setData(response.data);
}, 1000);
})
.catch((error) => {
if (error.response.data.statusCode === 404) {
navigate(-1);
} else {
console.error(error);
}
});
})();
}, []);
// console.log('data', data);
return (
<Page title="Profile">
<Container maxWidth={themeStretch ? false : 'xl'}>
<Stack direction="row" alignItems="center" sx={{ marginBottom: 3 }}>
{/* <IconButton sx={{ marginRight: '10px', color: '#424242' }} onClick={() => navigate()}>
<Iconify icon="heroicons-outline:arrow-narrow-left" />
</IconButton> */}
<ArrowBackIosIcon sx={{cursor:'pointer'}} onClick={() => navigate(-1)}/>
<Typography variant="h5" sx={{marginLeft:2}}>Profile</Typography>
<ArrowBackIosIcon sx={{ cursor: 'pointer' }} onClick={() => navigate(-1)} />
<Typography variant="h5" sx={{ marginLeft: 2 }}>
Profile
</Typography>
</Stack>
{data ? (
<Grid container spacing={2}>
{/* Row 1 */}
<Grid item xs={12} md={12}>
<CardPersonalInformation data={data} />
<CardPersonalInformation data={data?.person} />
</Grid>
<Grid item xs={12} md={12}>
<CardFamilyInformation data={data} />
<CardFamilyInformation data={data?.families} />
</Grid>
</Grid>
) : ''}
</Container>
</Page>
);

View File

@@ -0,0 +1,165 @@
/* ------------------------------- material ui ------------------------------ */
import { Card, Typography, Grid, Skeleton, Stack } from '@mui/material';
import { fDateBirth } from '../../../utils/formatTime';
type CardFamilyInformationProps = {
data?: {
name: string;
relationship: string;
dateOfBirth: string;
email: string;
phoneNumber: string;
status: string;
}[];
};
export default function CardFamilyInformation({ data }: CardFamilyInformationProps) {
console.log(data);
return (
<Card sx={{ borderRadius: 2, padding: 3 }}>
<Grid container gap={5}>
<Grid item xs={12}>
<Typography component={'h6'} fontWeight={700}>
{data ? 'Beneficiary / Family' : <Skeleton animation={'wave'} width={200} />}
</Typography>
</Grid>
<Grid item container xs={12} spacing={3}>
{data && data.length > 0 ? (
data.map((familyMember, index) => (
<Grid item xs={12} md={6} key={index}>
<Card sx={{ borderRadius: 1.5, paddingX: 3, paddingY: 3.5 }}>
<Grid container>
<Grid item xs={12}>
<Stack gap={0.5}>
<Typography variant="subtitle1" color={'grey.800'}>
{familyMember.name ? familyMember.name : '-'}
</Typography>
<Typography variant="subtitle2" color={'grey.600'}>
{familyMember.relationship ? familyMember.relationship : '-'}
</Typography>
</Stack>
</Grid>
<Grid container xs={12} marginTop={3}>
<Grid item xs={12} md={4}>
<Typography variant="body2" color={'grey.600'}>
Date Of Birth
</Typography>
</Grid>
<Grid item xs={12} md={8}>
<Typography variant="body2" color={'grey.800'}>
{familyMember.dateOfBirth ? fDateBirth(familyMember.dateOfBirth) : '-'}
</Typography>
</Grid>
</Grid>
<Grid container xs={12}>
<Grid item xs={12} md={4}>
<Typography variant="body2" color={'grey.600'}>
Email
</Typography>
</Grid>
<Grid item xs={12} md={8}>
<Typography variant="body2" color={'grey.800'}>
{familyMember.email ? familyMember.email : '-'}
</Typography>
</Grid>
</Grid>
<Grid container xs={12}>
<Grid item xs={12} md={4}>
<Typography variant="body2" color={'grey.600'}>
Phone Number
</Typography>
</Grid>
<Grid item xs={12} md={8}>
<Typography variant="body2" color={'grey.800'}>
{familyMember.phoneNumber ? familyMember.phoneNumber : '-'}
</Typography>
</Grid>
</Grid>
<Grid container xs={12}>
<Grid item xs={12} md={4}>
<Typography variant="body2" color={'grey.600'}>
Status
</Typography>
</Grid>
<Grid item xs={12} md={8}>
<Typography variant="body2" color={'grey.800'}>
{familyMember.status ? familyMember.status : '-'}
</Typography>
</Grid>
</Grid>
</Grid>
</Card>
</Grid>
))
) : (
<Grid item xs={12} md={6}>
<Card sx={{ borderRadius: 1.5, paddingX: 3, paddingY: 3.5 }}>
<Grid container>
<Grid item xs={12}>
<Stack gap={0.5}>
<Typography variant="subtitle1" color={'grey.800'}>
<Skeleton animation={'wave'} width={250} />
</Typography>
<Typography variant="subtitle2" color={'grey.600'}>
<Skeleton animation={'wave'} width={150} />
</Typography>
</Stack>
</Grid>
<Grid container xs={12} spacing={1} marginTop={3}>
<Grid item xs={12} md={4}>
<Typography variant="body2" color={'grey.600'}>
<Skeleton animation={'wave'} />
</Typography>
</Grid>
<Grid item xs={12} md={8}>
<Typography variant="body2" color={'grey.800'}>
<Skeleton animation={'wave'} />
</Typography>
</Grid>
</Grid>
<Grid container xs={12} spacing={1}>
<Grid item xs={12} md={4}>
<Typography variant="body2" color={'grey.600'}>
<Skeleton animation={'wave'} />
</Typography>
</Grid>
<Grid item xs={12} md={8}>
<Typography variant="body2" color={'grey.800'}>
<Skeleton animation={'wave'} />
</Typography>
</Grid>
</Grid>
<Grid container xs={12} spacing={1}>
<Grid item xs={12} md={4}>
<Typography variant="body2" color={'grey.600'}>
<Skeleton animation={'wave'} />
</Typography>
</Grid>
<Grid item xs={12} md={8}>
<Typography variant="body2" color={'grey.800'}>
<Skeleton animation={'wave'} />
</Typography>
</Grid>
</Grid>
<Grid container xs={12} spacing={1}>
<Grid item xs={12} md={4}>
<Typography variant="body2" color={'grey.600'}>
<Skeleton animation={'wave'} />
</Typography>
</Grid>
<Grid item xs={12} md={8}>
<Typography variant="body2" color={'grey.800'}>
<Skeleton animation={'wave'} />
</Typography>
</Grid>
</Grid>
</Grid>
</Card>
</Grid>
)}
</Grid>
</Grid>
</Card>
);
}

View File

@@ -0,0 +1,280 @@
/* ------------------------------- Material UI ------------------------------ */
import { Card, Stack, Typography, Grid, Skeleton } from '@mui/material';
import { fDateBirth } from '../../../utils/formatTime';
type CardPersonalInformationProps = {
data?: {
name: string;
weight: number;
height: number;
placeOfBirth: string;
dateOfBirth: string;
gender: string;
phoneNumber: string;
email: string;
address: string;
idNumber: string;
religion: string;
maritalStatus: string;
education: string;
occupation: string;
};
};
export default function CardPersonalInformation({ data }: CardPersonalInformationProps) {
return (
<Card sx={{ borderRadius: 2, padding: 3 }}>
<Grid container gap={5}>
<Grid item xs={12}>
<Typography component={'h6'} fontWeight={700}>
{data ? 'Personal Information' : <Skeleton animation={'wave'} width={200} />}
</Typography>
</Grid>
<Grid item container xs={12} spacing={3}>
{/* First */}
<Grid item xs={12} md={4}>
<Stack gap={1.5}>
<Typography variant="subtitle2" color={'grey.600'}>
{data ? 'Full Name' : <Skeleton animation={'wave'} width={200} />}
</Typography>
<Typography variant="subtitle1" color={'grey.800'}>
{data ? data.name ? data.name : '-' : <Skeleton animation={'wave'} width={125} />}
</Typography>
</Stack>
</Grid>
<Grid item xs={12} md={4}>
<Stack gap={1.5}>
<Typography variant="subtitle2" color={'grey.600'}>
{data ? 'Weight' : <Skeleton animation={'wave'} width={200} />}
</Typography>
<Typography variant="subtitle1" color={'grey.800'}>
{data ? (
data.weight ? (
`${data.weight} kg`
) : (
'-'
)
) : (
<Skeleton animation={'wave'} width={125} />
)}
</Typography>
</Stack>
</Grid>
<Grid item xs={12} md={4}>
<Stack gap={1.5}>
<Typography variant="subtitle2" color={'grey.600'}>
{data ? 'Height' : <Skeleton animation={'wave'} width={200} />}
</Typography>
<Typography variant="subtitle1" color={'grey.800'}>
{data ? (
data.height ? (
`${data.height} cm`
) : (
'-'
)
) : (
<Skeleton animation={'wave'} width={125} />
)}
</Typography>
</Stack>
</Grid>
{/* Second */}
<Grid item xs={12} md={4}>
<Stack gap={1.5}>
<Typography variant="subtitle2" color={'grey.600'}>
{data ? 'Place of Birth' : <Skeleton animation={'wave'} width={200} />}
</Typography>
<Typography variant="subtitle1" color={'grey.800'}>
{data ? (
data.placeOfBirth ? (
data.placeOfBirth
) : (
'-'
)
) : (
<Skeleton animation={'wave'} width={125} />
)}
</Typography>
</Stack>
</Grid>
<Grid item xs={12} md={4}>
<Stack gap={1.5}>
<Typography variant="subtitle2" color={'grey.600'}>
{data ? 'Date of Birth' : <Skeleton animation={'wave'} width={200} />}
</Typography>
<Typography variant="subtitle1" color={'grey.800'}>
{data ? (
data.dateOfBirth ? (
fDateBirth(data.dateOfBirth)
) : (
'-'
)
) : (
<Skeleton animation={'wave'} width={125} />
)}
</Typography>
</Stack>
</Grid>
<Grid item xs={12} md={4}>
<Stack gap={1.5}>
<Typography variant="subtitle2" color={'grey.600'}>
{data ? 'Gender' : <Skeleton animation={'wave'} width={200} />}
</Typography>
<Typography variant="subtitle1" color={'grey.800'}>
{data ? (
data.gender ? (
data.gender
) : (
'-'
)
) : (
<Skeleton animation={'wave'} width={125} />
)}
</Typography>
</Stack>
</Grid>
{/* Third */}
<Grid item xs={12} md={4}>
<Stack gap={1.5}>
<Typography variant="subtitle2" color={'grey.600'}>
{data ? 'Phone Number' : <Skeleton animation={'wave'} width={200} />}
</Typography>
<Typography variant="subtitle1" color={'grey.800'}>
{data ? (
data.phoneNumber ? (
data.phoneNumber
) : (
'-'
)
) : (
<Skeleton animation={'wave'} width={125} />
)}
</Typography>
</Stack>
</Grid>
<Grid item xs={8}>
<Stack gap={1.5}>
<Typography variant="subtitle2" color={'grey.600'}>
{data ? 'Email' : <Skeleton animation={'wave'} width={200} />}
</Typography>
<Typography variant="subtitle1" color={'grey.800'}>
{data ? data.email ? data.email : '-' : <Skeleton animation={'wave'} width={125} />}
</Typography>
</Stack>
</Grid>
{/* Four */}
<Grid item xs={12}>
<Stack gap={1.5}>
<Typography variant="subtitle2" color={'grey.600'}>
{data ? 'Address' : <Skeleton animation={'wave'} width={200} />}
</Typography>
<Typography variant="subtitle1" color={'grey.800'}>
{data ? (
data.address ? (
data.address
) : (
'-'
)
) : (
<Skeleton animation={'wave'} width={125} />
)}
</Typography>
</Stack>
</Grid>
{/* Five */}
<Grid item xs={12} md={4}>
<Stack gap={1.5}>
<Typography variant="subtitle2" color={'grey.600'}>
{data ? 'ID Number' : <Skeleton animation={'wave'} width={200} />}
</Typography>
<Typography variant="subtitle1" color={'grey.800'}>
{data ? (
data.idNumber ? (
data.idNumber
) : (
'-'
)
) : (
<Skeleton animation={'wave'} width={125} />
)}
</Typography>
</Stack>
</Grid>
<Grid item xs={8}>
<Stack gap={1.5}>
<Typography variant="subtitle2" color={'grey.600'}>
{data ? 'Religion' : <Skeleton animation={'wave'} width={200} />}
</Typography>
<Typography variant="subtitle1" color={'grey.800'}>
{data ? (
data.religion ? (
data.religion
) : (
'-'
)
) : (
<Skeleton animation={'wave'} width={125} />
)}
</Typography>
</Stack>
</Grid>
{/* Six */}
<Grid item xs={12} md={4}>
<Stack gap={1.5}>
<Typography variant="subtitle2" color={'grey.600'}>
{data ? 'Marital Status' : <Skeleton animation={'wave'} width={200} />}
</Typography>
<Typography variant="subtitle1" color={'grey.800'}>
{data ? (
data.maritalStatus ? (
data.maritalStatus
) : (
'-'
)
) : (
<Skeleton animation={'wave'} width={125} />
)}
</Typography>
</Stack>
</Grid>
<Grid item xs={12} md={4}>
<Stack gap={1.5}>
<Typography variant="subtitle2" color={'grey.600'}>
{data ? 'Education' : <Skeleton animation={'wave'} width={200} />}
</Typography>
<Typography variant="subtitle1" color={'grey.800'}>
{data ? (
data.education ? (
data.education
) : (
'-'
)
) : (
<Skeleton animation={'wave'} width={125} />
)}
</Typography>
</Stack>
</Grid>
<Grid item xs={12} md={4}>
<Stack gap={1.5}>
<Typography variant="subtitle2" color={'grey.600'}>
{data ? 'Occupation' : <Skeleton animation={'wave'} width={200} />}
</Typography>
<Typography variant="subtitle1" color={'grey.800'}>
{data ? (
data.occupation ? (
data.occupation
) : (
'-'
)
) : (
<Skeleton animation={'wave'} width={125} />
)}
</Typography>
</Stack>
</Grid>
</Grid>
</Grid>
</Card>
);
}

View File

@@ -7,6 +7,10 @@ export function fDate(date: Date | string | number) {
return format(new Date(date), 'dd MMMM yyyy');
}
export function fDateBirth(date: Date | string | number) {
return format(new Date(date), 'dd MMM yyyy');
}
export function fDateTime(date: Date | string | number) {
return format(new Date(date), 'dd MMM yyyy hh:mm');
}
@@ -19,7 +23,6 @@ export function fDateTimeSuffix(date: Date | string | number) {
return format(new Date(date), 'dd/MM/yyyy hh:mm p');
}
export function fDateSuffix(date: Date | string | number) {
return format(new Date(date), 'dd MMM yyyy');
}