mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 13:32:00 +00:00
fix(FE): revert require auth component
This commit is contained in:
@@ -1,83 +0,0 @@
|
||||
# Dropdown Component
|
||||
|
||||
Komponen Dropdown reusable berdasarkan DaisyUI yang mengatasi issue children component yang ter-render sebelum dropdown dibuka.
|
||||
|
||||
## Features
|
||||
|
||||
- ✅ **Conditional Rendering**: Children hanya di-render ketika dropdown aktif/terbuka
|
||||
- ✅ **Click Outside to Close**: Otomatis menutup dropdown ketika klik di luar area dropdown
|
||||
- ✅ **Multiple Positions**: Support berbagai posisi (top, bottom, left, right) dengan alignment (start, center, end)
|
||||
- ✅ **Hover Support**: Optional hover mode untuk membuka dropdown
|
||||
- ✅ **Customizable**: Mendukung custom className untuk container dan content
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic Example
|
||||
|
||||
```tsx
|
||||
import Dropdown from '@/components/dropdown/Dropdown';
|
||||
import Menu from '@/components/menu/Menu';
|
||||
import MenuItem from '@/components/menu/MenuItem';
|
||||
|
||||
<Dropdown
|
||||
trigger={
|
||||
<button className="btn">Click Me</button>
|
||||
}
|
||||
>
|
||||
<Menu className="p-2 bg-base-100 shadow rounded-box menu-sm w-52">
|
||||
<MenuItem title="Item 1" onClick={() => console.log('Item 1')} />
|
||||
<MenuItem title="Item 2" onClick={() => console.log('Item 2')} />
|
||||
</Menu>
|
||||
</Dropdown>
|
||||
```
|
||||
|
||||
### With Position
|
||||
|
||||
```tsx
|
||||
<Dropdown
|
||||
position="bottom-end"
|
||||
trigger={<button className="btn">Dropdown</button>}
|
||||
contentClassName="w-52 mt-3"
|
||||
>
|
||||
{/* Your content */}
|
||||
</Dropdown>
|
||||
```
|
||||
|
||||
### Hover Mode
|
||||
|
||||
```tsx
|
||||
<Dropdown
|
||||
hover={true}
|
||||
trigger={<button className="btn">Hover Me</button>}
|
||||
>
|
||||
{/* Your content */}
|
||||
</Dropdown>
|
||||
```
|
||||
|
||||
## Props
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `trigger` | `ReactNode` | - | **Required**. Element yang akan men-trigger dropdown |
|
||||
| `children` | `ReactNode` | - | **Required**. Content dropdown yang akan ditampilkan |
|
||||
| `position` | `'top' \| 'bottom' \| 'left' \| 'right' \| 'top-start' \| 'top-end' \| 'bottom-start' \| 'bottom-end' \| 'left-start' \| 'left-end' \| 'right-start' \| 'right-end'` | `'bottom'` | Posisi dropdown relatif terhadap trigger |
|
||||
| `align` | `'start' \| 'center' \| 'end'` | `'start'` | Alignment dropdown (digunakan jika position tidak mengandung alignment) |
|
||||
| `hover` | `boolean` | `false` | Aktifkan mode hover untuk membuka dropdown |
|
||||
| `className` | `string` | - | Custom className untuk container dropdown |
|
||||
| `contentClassName` | `string` | - | Custom className untuk content dropdown |
|
||||
|
||||
## Position Examples
|
||||
|
||||
- `bottom` - Dropdown muncul di bawah, align ke start
|
||||
- `bottom-end` - Dropdown muncul di bawah, align ke end
|
||||
- `bottom-center` - Dropdown muncul di bawah, align ke center
|
||||
- `top-start` - Dropdown muncul di atas, align ke start
|
||||
- `left-end` - Dropdown muncul di kiri, align ke end
|
||||
- Dan seterusnya...
|
||||
|
||||
## Key Benefits
|
||||
|
||||
1. **Performance**: Children tidak di-render sampai dropdown dibuka, menghemat resources
|
||||
2. **Clean State**: Setiap kali dropdown dibuka, children di-render fresh
|
||||
3. **DaisyUI Compatible**: Menggunakan class DaisyUI yang sudah ada
|
||||
4. **Accessible**: Menggunakan proper ARIA attributes dan keyboard navigation
|
||||
@@ -6,147 +6,9 @@ import useSWRImmutable from 'swr/immutable';
|
||||
|
||||
import { useAuth } from '@/services/hooks/useAuth';
|
||||
import { httpClientFetcher, SWRHttpKey } from '@/services/http/client';
|
||||
import { isResponseSuccess } from '@/lib/api-helper';
|
||||
import { GetMeResponse } from '@/types/api/api-general';
|
||||
|
||||
// TODO: delete this later, DONT HARDCODE USER DATA
|
||||
const DUMMY_USER = {
|
||||
id: 1,
|
||||
email: 'admin@mbugroup.id',
|
||||
npk: '0001',
|
||||
name: 'Super Admin',
|
||||
image: null,
|
||||
created_at: '2025-09-30T03:24:20.899229Z',
|
||||
updated_at: '2025-09-30T03:24:20.899229Z',
|
||||
roles: [
|
||||
{
|
||||
id: 1,
|
||||
key: 'mbu.super_admin',
|
||||
name: 'MBU Administrator',
|
||||
client: {
|
||||
id: 1,
|
||||
name: 'PT Mitra Berlian Unggas',
|
||||
alias: 'MBU',
|
||||
},
|
||||
permissions: [
|
||||
{
|
||||
id: 1,
|
||||
name: 'mbu:purchase:read',
|
||||
action: 'read',
|
||||
client: {
|
||||
id: 1,
|
||||
name: 'PT Mitra Berlian Unggas',
|
||||
alias: 'MBU',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: 'mbu:purchase:create',
|
||||
action: 'create',
|
||||
client: {
|
||||
id: 1,
|
||||
name: 'PT Mitra Berlian Unggas',
|
||||
alias: 'MBU',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: 'mbu:purchase:approve',
|
||||
action: 'approve',
|
||||
client: {
|
||||
id: 1,
|
||||
name: 'PT Mitra Berlian Unggas',
|
||||
alias: 'MBU',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
key: 'lti.super_admin',
|
||||
name: 'LTI Administrator',
|
||||
client: {
|
||||
id: 2,
|
||||
name: 'PT Lumbung Telur Indonesia',
|
||||
alias: 'LTI',
|
||||
},
|
||||
permissions: [
|
||||
{
|
||||
id: 4,
|
||||
name: 'lti:purchase:read',
|
||||
action: 'read',
|
||||
client: {
|
||||
id: 2,
|
||||
name: 'PT Lumbung Telur Indonesia',
|
||||
alias: 'LTI',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: 'lti:purchase:create',
|
||||
action: 'create',
|
||||
client: {
|
||||
id: 2,
|
||||
name: 'PT Lumbung Telur Indonesia',
|
||||
alias: 'LTI',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
name: 'lti:purchase:approve',
|
||||
action: 'approve',
|
||||
client: {
|
||||
id: 2,
|
||||
name: 'PT Lumbung Telur Indonesia',
|
||||
alias: 'LTI',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
key: 'manbu.super_admin',
|
||||
name: 'MANBU Administrator',
|
||||
client: {
|
||||
id: 3,
|
||||
name: 'PT Mandiri Berlian Unggas',
|
||||
alias: 'MANBU',
|
||||
},
|
||||
permissions: [
|
||||
{
|
||||
id: 7,
|
||||
name: 'manbu:purchase:read',
|
||||
action: 'read',
|
||||
client: {
|
||||
id: 3,
|
||||
name: 'PT Mandiri Berlian Unggas',
|
||||
alias: 'MANBU',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
name: 'manbu:purchase:create',
|
||||
action: 'create',
|
||||
client: {
|
||||
id: 3,
|
||||
name: 'PT Mandiri Berlian Unggas',
|
||||
alias: 'MANBU',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
name: 'manbu:purchase:approve',
|
||||
action: 'approve',
|
||||
client: {
|
||||
id: 3,
|
||||
name: 'PT Mandiri Berlian Unggas',
|
||||
alias: 'MANBU',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
|
||||
import { BaseApiResponse, GetMeResponse } from '@/types/api/api-general';
|
||||
import { AxiosError } from 'axios';
|
||||
|
||||
interface RequireAuthProps {
|
||||
children?: ReactNode;
|
||||
@@ -156,17 +18,20 @@ const RequireAuth = ({ children }: RequireAuthProps) => {
|
||||
const router = useRouter();
|
||||
const { setUser, setIsLoadingUser } = useAuth();
|
||||
|
||||
const { data: userResponse, isLoading: isLoadingUserResponse } =
|
||||
useSWRImmutable<GetMeResponse & { ok?: boolean }, unknown, SWRHttpKey>(
|
||||
'/auth/sso/userinfo',
|
||||
httpClientFetcher,
|
||||
{
|
||||
shouldRetryOnError: false,
|
||||
revalidateOnFocus: false,
|
||||
revalidateOnReconnect: false,
|
||||
refreshInterval: 0,
|
||||
}
|
||||
);
|
||||
const {
|
||||
data: userResponse,
|
||||
isLoading: isLoadingUserResponse,
|
||||
error: userErrorResponse,
|
||||
} = useSWRImmutable<
|
||||
GetMeResponse & { ok?: boolean },
|
||||
AxiosError<BaseApiResponse>,
|
||||
SWRHttpKey
|
||||
>('/sso/userinfo', httpClientFetcher, {
|
||||
shouldRetryOnError: false,
|
||||
revalidateOnFocus: false,
|
||||
revalidateOnReconnect: false,
|
||||
refreshInterval: 0,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setIsLoadingUser(isLoadingUserResponse);
|
||||
@@ -175,23 +40,25 @@ const RequireAuth = ({ children }: RequireAuthProps) => {
|
||||
useEffect(() => {
|
||||
if (isResponseSuccess(userResponse)) {
|
||||
setUser(userResponse.data);
|
||||
} else {
|
||||
// router.replace(process.env.NEXT_PUBLIC_SSO_LOGIN_URL as string);
|
||||
// TODO: remove this later, DONT HARDCODE USER DATA
|
||||
setUser(DUMMY_USER);
|
||||
} else if (
|
||||
isResponseError(userErrorResponse?.response?.data) &&
|
||||
typeof window !== 'undefined'
|
||||
) {
|
||||
router.replace(
|
||||
`${process.env.NEXT_PUBLIC_SSO_LOGIN_URL as string}?redirect_url=${window.location.href}`
|
||||
);
|
||||
}
|
||||
}, [userResponse, setIsLoadingUser, setUser]);
|
||||
}, [userResponse, userErrorResponse, setIsLoadingUser, setUser]);
|
||||
|
||||
// TODO: uncomment this later
|
||||
// if (isLoadingUserResponse && !userResponse) {
|
||||
// return (
|
||||
// <div className='w-full flex flex-row justify-center items-center p-4'>
|
||||
// <span className='loading loading-spinner loading-xl' />
|
||||
// </div>
|
||||
// );
|
||||
// }
|
||||
if (isLoadingUserResponse && !userResponse && !userErrorResponse) {
|
||||
return (
|
||||
<div className='w-full flex flex-row justify-center items-center p-4'>
|
||||
<span className='loading loading-spinner loading-xl' />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return <>{children}</>;
|
||||
return <>{isResponseSuccess(userResponse) && children}</>;
|
||||
};
|
||||
|
||||
export default RequireAuth;
|
||||
|
||||
Reference in New Issue
Block a user