Added User List table
This commit is contained in:
@@ -1,9 +1,7 @@
|
||||
import { createFileRoute } from '@tanstack/react-router';
|
||||
import { createFileRoute, redirect } from '@tanstack/react-router';
|
||||
|
||||
export const Route = createFileRoute('/(app)/(auth)/account/')({
|
||||
component: RouteComponent,
|
||||
beforeLoad: () => {
|
||||
throw redirect({ to: '/' });
|
||||
},
|
||||
});
|
||||
|
||||
function RouteComponent() {
|
||||
return <div>Hello "/(app)/(auth)/account/"!</div>;
|
||||
}
|
||||
|
||||
15
src/routes/(app)/(auth)/kanri/index.tsx
Normal file
15
src/routes/(app)/(auth)/kanri/index.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import { createFileRoute } from '@tanstack/react-router';
|
||||
|
||||
export const Route = createFileRoute('/(app)/(auth)/kanri/')({
|
||||
component: RouteComponent,
|
||||
});
|
||||
|
||||
function RouteComponent() {
|
||||
return (
|
||||
<div className="@container/main flex flex-1 flex-col gap-2 p-4">
|
||||
<div className="*:data-[slot=card]:from-primary/5 *:data-[slot=card]:to-card dark:*:data-[slot=card]:bg-card *:data-[slot=card]:bg-linear-to-br *:data-[slot=card]:shadow-xs grid grid-cols-1 @xl/main:grid-cols-2 @5xl/main:grid-cols-3 gap-4">
|
||||
Hello Admin!
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,28 +1,19 @@
|
||||
import { logColumns } from '@/components/audit/audit-columns';
|
||||
import DataTable from '@/components/DataTable';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Card, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import {
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupInput,
|
||||
} from '@/components/ui/input-group';
|
||||
import SearchInput from '@/components/ui/search-input';
|
||||
import { Skeleton } from '@/components/ui/skeleton';
|
||||
import useDebounced from '@/hooks/use-debounced';
|
||||
import { m } from '@/paraglide/messages';
|
||||
import { auditQueries } from '@/service/queries';
|
||||
import {
|
||||
CircuitryIcon,
|
||||
MagnifyingGlassIcon,
|
||||
XIcon,
|
||||
} from '@phosphor-icons/react';
|
||||
import { CircuitryIcon } from '@phosphor-icons/react';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { createFileRoute } from '@tanstack/react-router';
|
||||
import { useState } from 'react';
|
||||
|
||||
export const Route = createFileRoute('/(app)/(auth)/logs')({
|
||||
export const Route = createFileRoute('/(app)/(auth)/kanri/logs')({
|
||||
component: RouteComponent,
|
||||
staticData: { breadcrumb: () => m.nav_log() },
|
||||
staticData: { breadcrumb: () => m.nav_logs() },
|
||||
});
|
||||
|
||||
function RouteComponent() {
|
||||
@@ -42,9 +33,6 @@ function RouteComponent() {
|
||||
setSearchKeyword(e.target.value);
|
||||
setPage(1);
|
||||
};
|
||||
const onClearSearch = () => {
|
||||
setSearchKeyword('');
|
||||
};
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
@@ -68,32 +56,14 @@ function RouteComponent() {
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
</Card>
|
||||
<div className="flex">
|
||||
<InputGroup className="w-70">
|
||||
<InputGroupInput
|
||||
id="keywords"
|
||||
placeholder="Search...."
|
||||
value={searchKeyword}
|
||||
onChange={onSearchChange}
|
||||
/>
|
||||
<InputGroupAddon>
|
||||
<MagnifyingGlassIcon />
|
||||
</InputGroupAddon>
|
||||
<InputGroupAddon align="inline-end">
|
||||
{searchKeyword !== '' && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon-sm"
|
||||
className="rounded-full"
|
||||
onClick={onClearSearch}
|
||||
>
|
||||
<XIcon />
|
||||
</Button>
|
||||
)}
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
<div className="flex items-center">
|
||||
<SearchInput
|
||||
keywords={searchKeyword}
|
||||
setKeyword={setSearchKeyword}
|
||||
onChange={onSearchChange}
|
||||
/>
|
||||
</div>
|
||||
{data && (
|
||||
{data?.result && (
|
||||
<DataTable
|
||||
data={data.result || []}
|
||||
columns={logColumns}
|
||||
10
src/routes/(app)/(auth)/kanri/route.tsx
Normal file
10
src/routes/(app)/(auth)/kanri/route.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import { createFileRoute, redirect } from '@tanstack/react-router';
|
||||
|
||||
export const Route = createFileRoute('/(app)/(auth)/kanri')({
|
||||
beforeLoad: ({ context }) => {
|
||||
if (!context.session?.user.role && context.session?.user.role !== 'admin') {
|
||||
throw redirect({ to: '/' });
|
||||
}
|
||||
},
|
||||
staticData: { breadcrumb: 'Kanri' },
|
||||
});
|
||||
@@ -2,7 +2,7 @@ import SettingsForm from '@/components/form/settings-form';
|
||||
import { m } from '@/paraglide/messages';
|
||||
import { createFileRoute } from '@tanstack/react-router';
|
||||
|
||||
export const Route = createFileRoute('/(app)/(auth)/settings')({
|
||||
export const Route = createFileRoute('/(app)/(auth)/kanri/settings')({
|
||||
component: RouteComponent,
|
||||
staticData: { breadcrumb: () => m.nav_settings() },
|
||||
});
|
||||
81
src/routes/(app)/(auth)/kanri/users.tsx
Normal file
81
src/routes/(app)/(auth)/kanri/users.tsx
Normal file
@@ -0,0 +1,81 @@
|
||||
import DataTable from '@/components/DataTable';
|
||||
import { Card, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import SearchInput from '@/components/ui/search-input';
|
||||
import { Skeleton } from '@/components/ui/skeleton';
|
||||
import { userColumns } from '@/components/user/user-column';
|
||||
import useDebounced from '@/hooks/use-debounced';
|
||||
import { m } from '@/paraglide/messages';
|
||||
import { usersQueries } from '@/service/queries';
|
||||
import { UsersIcon } from '@phosphor-icons/react';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { createFileRoute } from '@tanstack/react-router';
|
||||
import { useState } from 'react';
|
||||
|
||||
export const Route = createFileRoute('/(app)/(auth)/kanri/users')({
|
||||
component: RouteComponent,
|
||||
staticData: { breadcrumb: () => m.nav_users() },
|
||||
});
|
||||
|
||||
function RouteComponent() {
|
||||
const [page, setPage] = useState(1);
|
||||
const [pageLimit, setPageLimit] = useState(10);
|
||||
const [searchKeyword, setSearchKeyword] = useState('');
|
||||
const debouncedSearch = useDebounced(searchKeyword, 500);
|
||||
|
||||
const { data, isLoading } = useQuery(
|
||||
usersQueries.list({
|
||||
page,
|
||||
limit: pageLimit,
|
||||
keyword: debouncedSearch,
|
||||
}),
|
||||
);
|
||||
|
||||
const onSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setSearchKeyword(e.target.value);
|
||||
setPage(1);
|
||||
};
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="@container/main flex flex-1 flex-col gap-2 p-4">
|
||||
<div className="flex flex-col gap-4">
|
||||
<Skeleton className="h-20 w-full" />
|
||||
<Skeleton className="h-130 w-full" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="@container/main flex flex-1 flex-col gap-2 p-4">
|
||||
<div className="*:data-[slot=card]:from-primary/5 *:data-[slot=card]:to-card dark:*:data-[slot=card]:bg-card *:data-[slot=card]:bg-linear-to-br *:data-[slot=card]:shadow-xs flex flex-col gap-4">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="text-xl flex items-center gap-2">
|
||||
<UsersIcon size={24} />
|
||||
{m.users_page_ui_title()}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
</Card>
|
||||
<div className="flex items-center">
|
||||
<SearchInput
|
||||
keywords={searchKeyword}
|
||||
setKeyword={setSearchKeyword}
|
||||
onChange={onSearchChange}
|
||||
/>
|
||||
</div>
|
||||
{data && (
|
||||
<DataTable
|
||||
data={data.result || []}
|
||||
columns={userColumns}
|
||||
page={page}
|
||||
setPage={setPage}
|
||||
limit={pageLimit}
|
||||
setLimit={setPageLimit}
|
||||
pagination={data.pagination}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user