From 1f7c6338c15232e3b2b55bd1a8974c16ce760538 Mon Sep 17 00:00:00 2001 From: roziqinkhoeru Date: Wed, 21 Feb 2024 11:38:11 +0700 Subject: [PATCH 01/26] `update` note --- note.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/note.txt b/note.txt index 2270013..fd20cd1 100644 --- a/note.txt +++ b/note.txt @@ -1,2 +1,3 @@ 💡!!BACKLOG!! -- import type \ No newline at end of file +- management alert +- alert error \ No newline at end of file From 6443265b4d616fe61866c919930e8071a4117af5 Mon Sep 17 00:00:00 2001 From: roziqinkhoeru Date: Wed, 21 Feb 2024 11:38:45 +0700 Subject: [PATCH 02/26] `feat(profile)` update profile page --- src/pages/Profile/ChangePassword.tsx | 5 +- .../Profile/components/HeaderProfile.tsx | 33 +++-- .../Profile/components/LoadingProfileUser.tsx | 9 ++ src/pages/Profile/components/ProfileUser.tsx | 113 +++++++++--------- src/pages/Profile/index.tsx | 35 +----- 5 files changed, 97 insertions(+), 98 deletions(-) create mode 100644 src/pages/Profile/components/LoadingProfileUser.tsx diff --git a/src/pages/Profile/ChangePassword.tsx b/src/pages/Profile/ChangePassword.tsx index b903c9b..99afda3 100644 --- a/src/pages/Profile/ChangePassword.tsx +++ b/src/pages/Profile/ChangePassword.tsx @@ -8,6 +8,7 @@ import HeaderProfile from './components/HeaderProfile'; import { EyeIcon, EyeOffIcon } from 'lucide-react'; import type { ChangePasswordRequest } from '../../types'; +import { useNavigate } from 'react-router-dom'; const schema = yup.object().shape({ oldPassword: yup.string().required('Password lama harus diisi.'), @@ -25,6 +26,7 @@ interface ShowPasswordState { } function ChangePassword() { + const navigate = useNavigate(); const [showPassword, setShowPassword] = useState({ oldPassword: false, newPassword: false, @@ -58,6 +60,7 @@ function ChangePassword() { await changePassword(data).unwrap(); showSuccessToast('Password berhasil diubah.'); reset(); + navigate('/profile'); // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (error: any) { if (error.data) { @@ -189,7 +192,7 @@ function ChangePassword() {
-

{currentUser?.name}

-

+

+ {currentUser?.name} +

+

{currentUser?.role}

-
+
{isProfilePage ? ( - Change Password + className="leading-normal ml-4 inline-flex justify-center rounded-md border border-neutral-200 bg-white px-3 py-1.5 text-sm font-medium text-gray-800 hover:bg-neutral-100 hover:border-neutral-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-violet-500 focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed disabled:bg-violet-500 disabled:focus-visible:ring-2 disabled:focus-visible:ring-violet-500 disabled:focus-visible:ring-offset-2 transition-all dark:bg-gray-800 dark:text-gray-200 dark:border-gray-600 dark:hover:bg-gray-700 dark:hover:border-gray-700 h-[35px] xl:h-auto items-center"> + Ubah Password + + + ) : ( - Profile + className="leading-normal ml-4 inline-flex justify-center rounded-md border border-neutral-200 bg-white px-3 py-1.5 text-sm font-medium text-gray-800 hover:bg-neutral-100 hover:border-neutral-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-violet-500 focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed disabled:bg-violet-500 disabled:focus-visible:ring-2 disabled:focus-visible:ring-violet-500 disabled:focus-visible:ring-offset-2 transition-all dark:bg-gray-800 dark:text-gray-200 dark:border-gray-600 dark:hover:bg-gray-700 dark:hover:border-gray-700 h-[35px] xl:h-auto items-center"> + Profil + + + )} - - Activity + className="leading-normal ml-4 inline-flex justify-center rounded-md border border-transparent bg-indigo-600 px-3 py-1.5 text-sm font-medium text-gray-100 hover:bg-indigo-500 focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed disabled:bg-indigo-500 disabled:focus-visible:ring-2 disabled:focus-visible:ring-indigo-500 disabled:focus-visible:ring-offset-2 transition-all dark:bg-indigo-700 dark:hover:bg-indigo-600 h-[35px] xl:h-auto items-center"> + Aktivitas + + +
diff --git a/src/pages/Profile/components/LoadingProfileUser.tsx b/src/pages/Profile/components/LoadingProfileUser.tsx new file mode 100644 index 0000000..345f5ab --- /dev/null +++ b/src/pages/Profile/components/LoadingProfileUser.tsx @@ -0,0 +1,9 @@ +function LoadingProfileUser() { + return ( +
+
Loading...
+
+ ); +} + +export default LoadingProfileUser; diff --git a/src/pages/Profile/components/ProfileUser.tsx b/src/pages/Profile/components/ProfileUser.tsx index 22a2cb5..4eec08c 100644 --- a/src/pages/Profile/components/ProfileUser.tsx +++ b/src/pages/Profile/components/ProfileUser.tsx @@ -3,68 +3,71 @@ import type { ProfileUserProps } from '../../../types'; function ProfileUser({ user }: ProfileUserProps) { return ( <> - {/* name */} -
-
-
- +
+
+ Informasi Personal +
+
+
+

+ Nama Depan +

+

{user?.name}

-
- +
+

+ Nama Belakang +

+

{user?.name}

-
-
- {/* email */} -
-
-
- +
+

+ Alamat Email +

+

{user?.email}

-
- +
+

+ Nomor Telepon +

+

+ {user?.phoneNumber} +

+
+
+

Alamat

+

+ Semarang, Indonesia +

-
-
-
- +
+
+ Informasi Sekolah +
+
+
+

+ Nama Sekolah +

+

+ {user?.school?.name} +

+
+
+

+ Jumlah Siswa +

+

+ {user?.school?.studentsCount} +

-
- +
+

Alamat

+

+ {user?.school?.address} +

diff --git a/src/pages/Profile/index.tsx b/src/pages/Profile/index.tsx index a7aa5ce..b93ac7a 100644 --- a/src/pages/Profile/index.tsx +++ b/src/pages/Profile/index.tsx @@ -1,38 +1,10 @@ import ProfileUser from './components/ProfileUser'; import { useGetProfileQuery } from '../../services/profileApi'; import HeaderProfile from './components/HeaderProfile'; +import LoadingProfileUser from './components/LoadingProfileUser'; function Profile() { - const { data: user, isLoading, isSuccess, isError } = useGetProfileQuery(); - let content; - - if (isLoading) { - content = ( -
- - - - -
- ); - } else if (isSuccess) { - content = ; - } else if (isError) { - content =
error
; - } + const { data: user, isLoading, isSuccess } = useGetProfileQuery(); return (
@@ -43,7 +15,8 @@ function Profile() {

Kelola informasi profil Anda

- {content} + {isLoading && } + {isSuccess && }
From 77ba6fda9fa7c339cd17ac2c00b7bad2211bfc57 Mon Sep 17 00:00:00 2001 From: roziqinkhoeru Date: Wed, 21 Feb 2024 11:39:06 +0700 Subject: [PATCH 03/26] `chore` adjustment profile --- src/common/Navbar.tsx | 9 ++++--- src/common/Sidebar.tsx | 57 +++++++++++++++++++++++------------------- src/types/authType.ts | 2 +- 3 files changed, 38 insertions(+), 30 deletions(-) diff --git a/src/common/Navbar.tsx b/src/common/Navbar.tsx index f2c2482..f804cbb 100644 --- a/src/common/Navbar.tsx +++ b/src/common/Navbar.tsx @@ -82,9 +82,12 @@ function Navbar() { to="/profile" title="Profile"> {`${user?.name} diff --git a/src/common/Sidebar.tsx b/src/common/Sidebar.tsx index d860eb4..c25b63f 100644 --- a/src/common/Sidebar.tsx +++ b/src/common/Sidebar.tsx @@ -86,10 +86,10 @@ export default function Sidebar({ children, currentPath }: SidebarProps) {
logo admin panel @@ -119,16 +119,16 @@ export default function Sidebar({ children, currentPath }: SidebarProps) { }`} onClick={() => setProfileToggle((curr) => !curr)}> {`${user?.name}
{`${user?.name} -
+

{user?.name} @@ -208,19 +211,21 @@ export default function Sidebar({ children, currentPath }: SidebarProps) { )} Dark Mode

-
- -
+ {profileToggle && ( +
+ +
+ )}

diff --git a/src/types/authType.ts b/src/types/authType.ts index a7357fa..a2fd192 100644 --- a/src/types/authType.ts +++ b/src/types/authType.ts @@ -6,7 +6,7 @@ interface UserAuth { role: string; email: string; phoneNumber: string; - images: Image | null; + image: Image | null; school: string; } interface Token { From e7f7d00e208b891f16858bd6b458b27d4bc408b9 Mon Sep 17 00:00:00 2001 From: roziqinkhoeru Date: Wed, 21 Feb 2024 20:16:08 +0700 Subject: [PATCH 04/26] `chore` update commons component --- src/App.tsx | 2 +- src/common/Navbar.tsx | 2 +- src/common/Sidebar.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index ce4e6e0..6c53f2b 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -117,7 +117,7 @@ function App() { element={} /> } /> setProfileToggle(false)} title="Account Settings"> From d7f28c7083e75e026fe859c191c4e35dd3c9e03b Mon Sep 17 00:00:00 2001 From: roziqinkhoeru Date: Wed, 21 Feb 2024 20:16:29 +0700 Subject: [PATCH 05/26] `feat(profile)` update profile page --- src/pages/Profile/ChangePassword.tsx | 14 +++---- .../Profile/components/HeaderProfile.tsx | 2 +- .../Profile/components/LoadingProfileUser.tsx | 39 +++++++++++++++++-- src/pages/Profile/components/ProfileUser.tsx | 11 ++++-- src/pages/Profile/index.tsx | 1 + 5 files changed, 52 insertions(+), 15 deletions(-) diff --git a/src/pages/Profile/ChangePassword.tsx b/src/pages/Profile/ChangePassword.tsx index 99afda3..70bee67 100644 --- a/src/pages/Profile/ChangePassword.tsx +++ b/src/pages/Profile/ChangePassword.tsx @@ -60,7 +60,7 @@ function ChangePassword() { await changePassword(data).unwrap(); showSuccessToast('Password berhasil diubah.'); reset(); - navigate('/profile'); + navigate('/profile/account'); // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (error: any) { if (error.data) { @@ -81,12 +81,12 @@ function ChangePassword() { Ubah password akun Anda

-
+
@@ -130,12 +130,12 @@ function ChangePassword() {
-
+
@@ -179,12 +179,12 @@ function ChangePassword() {
-
+
diff --git a/src/pages/Profile/components/HeaderProfile.tsx b/src/pages/Profile/components/HeaderProfile.tsx index 63bac02..2987ffc 100644 --- a/src/pages/Profile/components/HeaderProfile.tsx +++ b/src/pages/Profile/components/HeaderProfile.tsx @@ -50,7 +50,7 @@ function HeaderProfile({ isProfilePage }: HeaderProfileProps) { ) : ( Profil diff --git a/src/pages/Profile/components/LoadingProfileUser.tsx b/src/pages/Profile/components/LoadingProfileUser.tsx index 345f5ab..90a8a10 100644 --- a/src/pages/Profile/components/LoadingProfileUser.tsx +++ b/src/pages/Profile/components/LoadingProfileUser.tsx @@ -1,8 +1,41 @@ function LoadingProfileUser() { return ( -
-
Loading...
-
+ <> +
+
+
+ {[...Array(5)].map((_, index) => ( +
+
+
+
+ ))} +
+
+
+
+
+
+
+
+
+ {[...Array(2)].map((_, index) => ( +
+
+
+
+ ))} +
+
+
+
+
+
+ ); } diff --git a/src/pages/Profile/components/ProfileUser.tsx b/src/pages/Profile/components/ProfileUser.tsx index 4eec08c..695ebfb 100644 --- a/src/pages/Profile/components/ProfileUser.tsx +++ b/src/pages/Profile/components/ProfileUser.tsx @@ -1,10 +1,13 @@ import type { ProfileUserProps } from '../../../types'; +import { extractNameParts } from '../../../utilities/stringUtils'; function ProfileUser({ user }: ProfileUserProps) { + const { firstName, lastName } = extractNameParts(user?.name); + return ( <>
-
+
Informasi Personal
@@ -12,13 +15,13 @@ function ProfileUser({ user }: ProfileUserProps) {

Nama Depan

-

{user?.name}

+

{firstName}

Nama Belakang

-

{user?.name}

+

{lastName}

@@ -43,7 +46,7 @@ function ProfileUser({ user }: ProfileUserProps) {

-
+
Informasi Sekolah
diff --git a/src/pages/Profile/index.tsx b/src/pages/Profile/index.tsx index b93ac7a..bd2ab22 100644 --- a/src/pages/Profile/index.tsx +++ b/src/pages/Profile/index.tsx @@ -15,6 +15,7 @@ function Profile() {

Kelola informasi profil Anda

+ {/* */} {isLoading && } {isSuccess && }
From 25350d6cdf79c42beb4f448282c53c3a99cdf4a4 Mon Sep 17 00:00:00 2001 From: roziqinkhoeru Date: Wed, 21 Feb 2024 20:16:46 +0700 Subject: [PATCH 06/26] `style` update tailwind styles --- src/index.css | 24 ++++++++++++++---------- tailwind.config.js | 2 ++ 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/index.css b/src/index.css index 073a515..d9fd651 100644 --- a/src/index.css +++ b/src/index.css @@ -41,43 +41,47 @@ button { .Toastify__toast-container { @apply w-full xsm:w-auto; } - .toastify-containers { @apply relative flex min-h-0 overflow-hidden cursor-pointer pl-2 pr-4 py-2 rounded-lg items-center mb-4 mx-2 sm:mx-0 mt-2 sm:mt-0; } - .Toastify__toast-body { @apply mr-5; } - .Toastify__toast-body > div:last-child { @apply text-sm font-medium leading-tight whitespace-nowrap; } - .Toastify__close-button { @apply py-0.75 pl-0.75 pr-0.5 bg-transparent rounded self-center; } - .Toastify__close-button:hover { @apply bg-gray-900/10; } - .Toastify__toast-icon { @apply w-auto mr-3; } - .Toastify__toast--success { @apply bg-emerald-500; } - .Toastify__toast--error { @apply bg-red-500; } - .Toastify__toast--warning { @apply bg-amber-500; } - .Toastify__toast--info { @apply bg-violet-500; } + +/* skeleton */ +.skeleton-loader { + @apply bg-gray-200 dark:bg-gray-700 rounded-full; +} +.skeleton-xs { + @apply h-3; +} +.skeleton-sm { + @apply h-4; +} +.skeleton-base { + @apply h-5; +} diff --git a/tailwind.config.js b/tailwind.config.js index 1cd31de..8d75eee 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -7,6 +7,7 @@ export default { animation: { 'spin-slow': 'spin 1.5s linear infinite', 'spin-fast': 'spin 0.75s linear infinite', + 'pulse-fast': 'pulse 1s linear infinite', }, blur: { 2: '0.5rem', @@ -57,6 +58,7 @@ export default { 1.6375: '0.409375rem', 4.5: '1.125rem', 6.5: '1.625rem', + 30: '7.5rem', 31: '7.75rem', 10.8: '2.7rem', 106: '26.5rem', From 3a6571dd30653ae65230c8640d9282b5933a0ff6 Mon Sep 17 00:00:00 2001 From: roziqinkhoeru Date: Wed, 21 Feb 2024 20:17:03 +0700 Subject: [PATCH 07/26] `chore` update text utils --- src/utilities/stringUtils.ts | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/utilities/stringUtils.ts b/src/utilities/stringUtils.ts index 2a90963..9b51cbb 100644 --- a/src/utilities/stringUtils.ts +++ b/src/utilities/stringUtils.ts @@ -4,3 +4,32 @@ export const transformStringPlus = (input: string | undefined): string => { } return input.replace(/\s+/g, '+'); }; + +export const extractNameParts = (fullName: string | undefined) => { + if (fullName === undefined) { + return { + firstName: '', + lastName: '', + }; + } + + const nameParts = fullName.split(' '); + if (nameParts.length === 2) { + return { + firstName: nameParts[0], + lastName: nameParts[1], + }; + } else if (nameParts.length > 2) { + const firstName = nameParts.slice(0, -1).join(' '); + const lastName = nameParts[nameParts.length - 1]; + return { + firstName: firstName, + lastName: lastName, + }; + } else { + return { + firstName: fullName, + lastName: '', + }; + } +}; From 73cb97a580cc80f582f0597c49fc5f642aca1894 Mon Sep 17 00:00:00 2001 From: roziqinkhoeru Date: Wed, 21 Feb 2024 20:23:23 +0700 Subject: [PATCH 08/26] `chore` update common components --- src/common/Layout.tsx | 8 ++++---- src/common/Sidebar.tsx | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/common/Layout.tsx b/src/common/Layout.tsx index 9847ae6..9ec8933 100644 --- a/src/common/Layout.tsx +++ b/src/common/Layout.tsx @@ -37,21 +37,21 @@ function Layout() { /> } - text="Students" + text="Siswa" path="/student" alert={true} active={isCurrentLocation('student')} /> } - text="Score" + text="Skor" path="/score" alert={true} active={isCurrentLocation('score')} /> } - text="Analysis" + text="Analisis" path="/analysis" alert={false} active={isCurrentLocation('analysis')} @@ -70,7 +70,7 @@ function Layout() { /> } - text="School" + text="Sekolah" path="/school" alert={false} active={isCurrentLocation('school')} diff --git a/src/common/Sidebar.tsx b/src/common/Sidebar.tsx index 75e9ea9..a1dc0c8 100644 --- a/src/common/Sidebar.tsx +++ b/src/common/Sidebar.tsx @@ -239,7 +239,7 @@ export default function Sidebar({ children, currentPath }: SidebarProps) { onClick={() => setProfileToggle(false)} title="Account Settings"> - Account Settings + Pengaturan Akun setProfileToggle(false)} title="Activity"> - Activity + Aktivitas

From 8e80a75a28e1304e81fbe96b137ca0a1deb0dad5 Mon Sep 17 00:00:00 2001 From: roziqinkhoeru Date: Wed, 21 Feb 2024 21:53:24 +0700 Subject: [PATCH 09/26] `feat(score)` update score table view --- src/index.css | 2 +- src/pages/Profile/components/ProfileUser.tsx | 56 ++++++++++---------- src/pages/Score/components/ScoreTable.tsx | 53 +++++++++++------- src/pages/Score/index.tsx | 2 +- 4 files changed, 65 insertions(+), 48 deletions(-) diff --git a/src/index.css b/src/index.css index d9fd651..110622d 100644 --- a/src/index.css +++ b/src/index.css @@ -29,7 +29,7 @@ button { /* form */ .forms-checkbox { - @apply form-checkbox h-4 w-4 border-2 border-gray-400 rounded bg-gray-50 focus:outline focus:outline-2 focus:outline-offset-0 focus:outline-indigo-600/20 focus:border-indigo-500/50 focus:ring-offset-0 focus:ring-0 block checked:bg-indigo-500; + @apply form-checkbox h-4 w-4 border-2 border-gray-400 rounded bg-gray-50 focus:outline focus:outline-2 focus:outline-offset-0 focus:outline-indigo-600/20 focus:border-indigo-500/50 focus:ring-offset-0 focus:ring-0 block checked:bg-indigo-500 dark:border-gray-600 dark:bg-gray-600 dark:checked:bg-indigo-600 dark:checked:border-indigo-600; } /* utilities */ diff --git a/src/pages/Profile/components/ProfileUser.tsx b/src/pages/Profile/components/ProfileUser.tsx index 695ebfb..5f30227 100644 --- a/src/pages/Profile/components/ProfileUser.tsx +++ b/src/pages/Profile/components/ProfileUser.tsx @@ -45,35 +45,37 @@ function ProfileUser({ user }: ProfileUserProps) {
-
-
- Informasi Sekolah -
-
-
-

- Nama Sekolah -

-

- {user?.school?.name} -

-
-
-

- Jumlah Siswa -

-

- {user?.school?.studentsCount} -

-
-
-

Alamat

-

- {user?.school?.address} -

+ {user?.role !== 'Super Admin' && ( +
+
+ Informasi Sekolah +
+
+
+

+ Nama Sekolah +

+

+ {user?.school?.name} +

+
+
+

+ Jumlah Siswa +

+

+ {user?.school?.studentsCount} +

+
+
+

Alamat

+

+ {user?.school?.address} +

+
-
+ )} ); } diff --git a/src/pages/Score/components/ScoreTable.tsx b/src/pages/Score/components/ScoreTable.tsx index 42cb01d..1c1f742 100644 --- a/src/pages/Score/components/ScoreTable.tsx +++ b/src/pages/Score/components/ScoreTable.tsx @@ -23,9 +23,13 @@ import { ScoreProps } from '../../../types'; import scoreData from '../../../data/SCORE_DATA.json'; function IndeterminateCheckbox({ + isHeader, indeterminate, ...rest -}: { indeterminate?: boolean } & HTMLProps) { +}: { + indeterminate?: boolean; + isHeader?: boolean; +} & HTMLProps) { const ref = useRef(null!); useEffect(() => { @@ -38,7 +42,12 @@ function IndeterminateCheckbox({ ); @@ -66,6 +75,7 @@ function ScoreTable() { id: 'checkboxs', header: ({ table }) => ( (
-
+
setFilter(String(e.target.value))} + autoComplete="off" />
-

+

{table.getState().pagination.pageIndex + 1}/{table.getPageCount()}

@@ -162,13 +175,13 @@ function ScoreTable() { {table.getHeaderGroups().map((headerGroup) => ( + className="border-y border-gray-200 bg-indigo-50/50 dark:border-gray-600 dark:bg-gray-600"> {headerGroup.headers.map((header) => ( + } dark:text-gray-300`}> {header.isPlaceholder ? null : (
( + className="border-b border-gray-200 hover:bg-gray-100 dark:border-gray-600 dark:hover:bg-gray-600/40"> {row.getVisibleCells().map((cell) => ( {flexRender( @@ -228,12 +241,12 @@ function ScoreTable() {
-

Menampilkan

+

Menampilkan

); } function AdminTable() { - const [filter, setFilter] = useState(''); + const [search, setSearch] = useState(''); + const [limitPage, setLimitPage] = useState(10); + const [querySearch] = useDebounce(search, 500); + const [rowSelection, setRowSelection] = useState({}); const [sorting, setSorting] = useState([]); - const [isOpenDeleteDialog, setIsOpenDeleteDialog] = useState(false); - const [deleteId, setDeleteId] = useState(''); - const [isLoadingDelete, setIsLoadingDelete] = useState(false); + const [isLargeView, setIsLargeView] = useState( window.innerWidth > 1024 ); - const data = useMemo(() => adminData, []); + + const dispatch = useAppDispatch(); + const [getAdmin, { isLoading, isSuccess, isError }] = useGetAdminMutation(); + const [deleteAdmin, { isLoading: isLoadingDelete }] = + useDeleteAdminMutation(); + const admins = useAppSelector(selectAdmin); + const adminStatus = useAppSelector(selectAdminStatus); + const adminPages = useAppSelector(selectAdminPage); + const admin = useMemo(() => admins ?? [], [admins]); + const [isOpenDeleteDialog, setIsOpenDeleteDialog] = useState(false); + const [deleteId, setDeleteId] = useState(''); const headerClass: Record = { checkboxs: 'w-14 text-center', row_number: 'w-12', }; - const columnHelper = createColumnHelper(); + const fetchAdmin = async (credentials: DataTableGetRequest) => { + try { + const result = await getAdmin(credentials).unwrap(); + dispatch(setAdmin(result)); + } catch (error) { + showErrorToast('Gagal mengambil data admin'); + } + }; + + const openDeleteDialog = (id: string) => { + setIsOpenDeleteDialog(true); + setDeleteId(id); + }; + const closeDeleteDialog = () => { + setIsOpenDeleteDialog(false); + }; + + const handleDelete = async () => { + try { + const responseDelete = await deleteAdmin({ id: deleteId }).unwrap(); + if (responseDelete.success) { + showSuccessToast('Berhasil menghapus data sekolah'); + } + } catch (error) { + showErrorToast('Gagal menghapus data sekolah'); + } + setIsOpenDeleteDialog(false); + }; + + const columnHelper = createColumnHelper(); const defaultColumns = useMemo( () => [ columnHelper.display({ id: 'checkboxs', header: ({ table }) => ( info.row.index + 1, + cell: (info) => info?.row?.index + 1, }), columnHelper.accessor('name', { header: 'Nama Lengkap', cell: (info) => (
{`${info.getValue()} -

{info.getValue()}

+

{info?.getValue()}

), }), @@ -116,8 +182,9 @@ function AdminTable() { cell: (info) => info.getValue(), }), columnHelper.accessor('school.name', { + id: 'school', header: 'Sekolah', - cell: (info) => info.getValue(), + cell: (info) => info.getValue() ?? '-', }), // action edit and delete columnHelper.display({ @@ -127,15 +194,16 @@ function AdminTable() {
+ to={`/admin/edit/${info?.row?.original?._id}`}>
-
+
-
+
-

Informasi Siswa

+

Informasi Admin

- Informasi siswa yang akan ditambahkan ke dalam sistem. + Informasi admin yang akan ditambahkan ke dalam sistem.

- +
{/* name */}
+ {errors.name && ( +

+ {errors.name.message} +

+ )}
{/* email */}
+ {errors.email && ( +

+ {errors.email.message} +

+ )}
{/* phone number */}
+ {errors.phoneNumber && ( +

+ {errors.phoneNumber.message} +

+ )}
{/* school::select */}
+ {errors.school && ( +

+ {errors.school.message} +

+ )}
- +
-
+

Foto Profil

- Foto profil siswa yang akan ditambahkan ke dalam sistem. + Foto profil admin yang akan ditambahkan ke dalam sistem.

{`${admin?.name} 0 + ? URL.createObjectURL(watchMedia[0]) + : 'https://ui-avatars.com/api/?name=Gameon' + } + alt="Profile Placeholder" className="w-full h-full object-cover object-center" />
- Ubah Foto Profil + Tambah Foto Profil
-

+

Hapus

-

- Update +

+ Terapkan

-
- -
-
+
+
+ +
-

- {' '} - or drag and drop +

+ + Pilih file + {' '} + atau drag and drop file di sini

-

- SVG, PNG, or JPG (max. 3.00 MB) +

+ SVG, PNG, atau JPG (maks. 3MB)

- +
+ {watchMedia?.length > 0 && errors.media && ( +

+ {errors.media.message?.toString()} +

+ )}
-
+
); } diff --git a/src/pages/Admin/components/AdminTable.tsx b/src/pages/Admin/components/AdminTable.tsx index 66d5163..ea2a9cf 100644 --- a/src/pages/Admin/components/AdminTable.tsx +++ b/src/pages/Admin/components/AdminTable.tsx @@ -9,13 +9,6 @@ import { getSortedRowModel, useReactTable, } from '@tanstack/react-table'; -import { useAppDispatch, useAppSelector } from '../../../app/hooks'; -import { - selectAdmin, - selectAdminPage, - selectAdminStatus, - setAdmin, -} from '../../../features/adminSlice'; import { useDeleteAdminMutation, useGetAdminMutation, @@ -79,14 +72,12 @@ function AdminTable() { window.innerWidth > 1024 ); - const dispatch = useAppDispatch(); - const [getAdmin, { isLoading, isSuccess, isError }] = useGetAdminMutation(); + const [getAdmin, { isLoading, isError, data: admins }] = + useGetAdminMutation(); const [deleteAdmin, { isLoading: isLoadingDelete }] = useDeleteAdminMutation(); - const admins = useAppSelector(selectAdmin); - const adminStatus = useAppSelector(selectAdminStatus); - const adminPages = useAppSelector(selectAdminPage); - const admin = useMemo(() => admins ?? [], [admins]); + const admin = useMemo(() => admins?.data ?? [], [admins]); + const adminPages = admins?.page; const [isOpenDeleteDialog, setIsOpenDeleteDialog] = useState(false); const [deleteId, setDeleteId] = useState(''); const headerClass: Record = { @@ -96,8 +87,7 @@ function AdminTable() { const fetchAdmin = async (credentials: DataTableGetRequest) => { try { - const result = await getAdmin(credentials).unwrap(); - dispatch(setAdmin(result)); + await getAdmin(credentials).unwrap(); } catch (error) { showErrorToast('Gagal mengambil data admin'); } @@ -116,6 +106,7 @@ function AdminTable() { const responseDelete = await deleteAdmin({ id: deleteId }).unwrap(); if (responseDelete.success) { showSuccessToast('Berhasil menghapus data sekolah'); + fetchAdmin({ search: querySearch, limit: limitPage }); } } catch (error) { showErrorToast('Gagal menghapus data sekolah'); @@ -159,16 +150,20 @@ function AdminTable() { header: 'Nama Lengkap', cell: (info) => (
- {`${info?.getValue()} +
+
+ {`${info?.getValue()} +
+

{info?.getValue()}

), @@ -181,10 +176,10 @@ function AdminTable() { header: 'Telepon', cell: (info) => info.getValue(), }), - columnHelper.accessor('school.name', { + columnHelper.accessor((data) => data?.school?.name || '', { id: 'school', header: 'Sekolah', - cell: (info) => info.getValue() ?? '-', + cell: (info) => info?.row?.original?.school?.name ?? '-', }), // action edit and delete columnHelper.display({ @@ -240,9 +235,7 @@ function AdminTable() { }, []); useEffect(() => { - if (adminStatus === 'idle' || isSuccess) { - fetchAdmin({ search: querySearch, limit: limitPage }); - } + fetchAdmin({ search: querySearch, limit: limitPage }); }, [querySearch, limitPage]); return ( @@ -328,25 +321,25 @@ function AdminTable() { - +
- +
- +
- +
- +
- +
- +