refactor: add Subscribe Plan menu item and implement subscription management pages

This commit is contained in:
fredy.siswanto 2025-03-09 14:40:55 +07:00
parent 550b16cfd3
commit 9dca781d6d
7 changed files with 146 additions and 238 deletions

View File

@ -59,6 +59,11 @@ export const MENU: TMenu[] = [
url: '/lg-admin/tags',
icon: TagIcon,
},
{
title: 'Subscribe Plan',
url: '/lg-admin/subscribe-plan',
icon: TagIcon,
},
],
},
]

View File

@ -0,0 +1,85 @@
import DT from 'datatables.net-dt'
import DataTable from 'datatables.net-react'
import { Link, useRouteLoaderData } from 'react-router'
import { Button } from '~/components/ui/button'
import { UiTable } from '~/components/ui/table'
import { TitleDashboard } from '~/components/ui/title-dashboard'
import type { loader } from '~/routes/_admin.lg-admin._dashboard'
export const SubscribePlanPage = () => {
const loaderData = useRouteLoaderData<typeof loader>(
'routes/_admin.lg-admin._dashboard',
)
DataTable.use(DT)
const dataTable = loaderData?.subscriptionsData
const dataColumns = [
{
title: 'No',
render: (
data: unknown,
type: unknown,
row: unknown,
meta: { row: number },
) => {
return meta.row + 1
},
},
{
title: 'Nama',
data: 'name',
},
{
title: 'Kode',
data: 'code',
},
{
title: 'Action',
data: 'id',
},
]
const dataSlot = {
3: (value: string) => (
<Button
as="a"
href={`/lg-admin/subscribe-plan/update/${value}`}
className="text-md rounded-md"
size="sm"
>
Update Subscribe Plan
</Button>
),
}
return (
<div className="relative">
<TitleDashboard title="Subscribe Plan" />
<div className="mb-8 flex items-end justify-between">
<div className="flex-1">{/* TODO: Filter */}</div>
<Button
as={Link}
to="/lg-admin/subscribe-plan/create"
className="text-md h-[42px] rounded-md"
size="lg"
>
Buat Subscribe Plan
</Button>
</div>
<UiTable
data={dataTable}
columns={dataColumns}
slots={dataSlot}
options={{
paging: true,
searching: true,
ordering: true,
info: true,
}}
title=" Daftar Subscribe Plan"
/>
</div>
)
}

View File

@ -8,15 +8,6 @@ type TSubscriptions = {
status: string
}
type TSubSettings = {
id: number
createdAt: string
subscriber: 'Monthly' | 'Yearly' | 'Weekly' | 'Special'
price: string
length: '30' | '365' | '7' | '1'
status: string
}
export const SUBSCRIPTIONS: TSubscriptions[] = [
{
id: 1,
@ -199,86 +190,3 @@ export const SUBSCRIPTIONS: TSubscriptions[] = [
status: 'Draft',
},
]
export const SUBSETTINGS: TSubSettings[] = [
{
id: 1,
createdAt: '24/10/2024',
subscriber: 'Monthly',
price: '100',
length: '30',
status: 'active',
},
{
id: 2,
createdAt: '25/10/2024',
subscriber: 'Yearly',
price: '1000',
length: '365',
status: 'active',
},
{
id: 3,
createdAt: '26/10/2024',
subscriber: 'Weekly',
price: '25',
length: '7',
status: 'inactive',
},
{
id: 4,
createdAt: '27/10/2024',
subscriber: 'Monthly',
price: '100',
length: '30',
status: 'active',
},
{
id: 5,
createdAt: '28/10/2024',
subscriber: 'Yearly',
price: '1000',
length: '365',
status: 'inactive',
},
{
id: 6,
createdAt: '29/10/2024',
subscriber: 'Weekly',
price: '25',
length: '7',
status: 'active',
},
{
id: 7,
createdAt: '30/10/2024',
subscriber: 'Monthly',
price: '100',
length: '30',
status: 'inactive',
},
{
id: 8,
createdAt: '31/10/2024',
subscriber: 'Yearly',
price: '1000',
length: '365',
status: 'active',
},
{
id: 9,
createdAt: '01/11/2024',
subscriber: 'Weekly',
price: '25',
length: '7',
status: 'inactive',
},
{
id: 10,
createdAt: '02/11/2024',
subscriber: 'Monthly',
price: '100',
length: '30',
status: 'active',
},
]

View File

@ -1,18 +1,15 @@
import { Field, Input, Label, Select } from '@headlessui/react'
import DT from 'datatables.net-dt'
import DataTable from 'datatables.net-react'
import { useState } from 'react'
import { SearchIcon } from '~/components/icons/search'
import { Button } from '~/components/ui/button'
import { UiTable } from '~/components/ui/table'
import { TitleDashboard } from '~/components/ui/title-dashboard'
import { SUBSCRIPTIONS, SUBSETTINGS } from './data'
import { SUBSCRIPTIONS } from './data'
export const SubscriptionsPage = () => {
const [SubscribtionOpen, setSubscribtionOpen] = useState(true)
// const [SubSettingOpen, setSubSettingOpen] = useState(false)
DataTable.use(DT)
const colTableSubscription = [
{ title: 'No', data: 'id' },
@ -28,158 +25,64 @@ export const SubscriptionsPage = () => {
},
},
]
const colTableSubSetting = [
{ title: 'No', data: 'id' },
{ title: 'Tanggal Pembuatan', data: 'createdAt' },
{ title: 'Nama Subscription', data: 'subscriber' },
{ title: 'Price', data: 'price' },
{ title: 'Length', data: 'length' },
{
title: 'Status',
data: 'status',
render: (value: string) => {
return value == 'active'
? `<span class="bg-[#DFE5FF] text-[#4C5CA0] px-2 py-1 rounded-md">${value}</span>`
: `<span class="bg-[#FFD1D1] text-[#FF4E4E] px-2 py-1 rounded-md">${value}</span>`
},
},
]
const switchView = () => {
setSubscribtionOpen(!SubscribtionOpen)
}
return (
<div className="relative">
<TitleDashboard title="Subscription" />
{SubscribtionOpen && (
<>
<div className="mb-8 flex items-end justify-between">
<div className="flex items-center gap-5 rounded-lg bg-gray-50 text-[#363636]">
<div className="w-[400px]">
<Field>
<Label className="mb-2 block text-sm font-medium">
Cari User
</Label>
<div className="relative">
<Input
type="text"
placeholder="Cari Nama"
className="w-full rounded-lg bg-white p-2 pr-10 pl-4 shadow focus:ring-1 focus:ring-[#2E2F7C] focus:outline-none"
/>
<div className="absolute inset-y-0 right-0 flex items-center pr-3">
<SearchIcon className="h-5 w-5" />
</div>
</div>
</Field>
<div className="mb-8 flex items-end justify-between">
<div className="flex items-center gap-5 rounded-lg bg-gray-50 text-[#363636]">
<div className="w-[400px]">
<Field>
<Label className="mb-2 block text-sm font-medium">
Cari User
</Label>
<div className="relative">
<Input
type="text"
placeholder="Cari Nama"
className="w-full rounded-lg bg-white p-2 pr-10 pl-4 shadow focus:ring-1 focus:ring-[#2E2F7C] focus:outline-none"
/>
<div className="absolute inset-y-0 right-0 flex items-center pr-3">
<SearchIcon className="h-5 w-5" />
</div>
</div>
<div className="w-[235px]">
<Field>
<Label className="mb-2 block text-sm font-medium">
Status
</Label>
<Select className="w-full rounded-lg bg-white p-2 shadow focus:ring-1 focus:ring-[#2E2F7C] focus:outline-none">
<option>Pilih Status</option>
<option>Aktif</option>
<option>Nonaktif</option>
</Select>
</Field>
</div>
</div>
<Button
className="rounded-md"
size="lg"
onClick={switchView}
>
Subscription Settings
</Button>
</Field>
</div>
<UiTable
data={SUBSCRIPTIONS}
columns={colTableSubscription}
options={{
paging: true,
searching: true,
ordering: true,
info: true,
}}
title="Daftar Subscription"
/>
</>
)}
{!SubscribtionOpen && (
<>
<div className="mb-8 flex items-end justify-between">
<div className="flex items-end gap-5 rounded-lg bg-gray-50 text-[#363636]">
<div className="w-[300px]">
<Field>
<Label className="mb-2 block text-sm font-medium">
Subscription Name
</Label>
<div className="relative">
<Input
type="text"
placeholder="Subscription Name"
className="w-full rounded-lg bg-white p-2 pr-10 pl-4 shadow focus:ring-1 focus:ring-[#2E2F7C] focus:outline-none"
/>
</div>
</Field>
</div>
<div className="w-[300px]">
<Field>
<Label className="mb-2 block text-sm font-medium">
Subscription Price
</Label>
<div className="relative">
<Input
type="text"
placeholder="Subscription Price"
className="w-full rounded-lg bg-white p-2 pr-10 pl-4 shadow focus:ring-1 focus:ring-[#2E2F7C] focus:outline-none"
/>
</div>
</Field>
</div>
<div className="w-[300px]">
<Field>
<Label className="mb-2 block text-sm font-medium">
Subscription Length (Days)
</Label>
<Input
type="text"
placeholder="Subscription Length (Days)"
className="w-full rounded-lg bg-white p-2 shadow focus:ring-1 focus:ring-[#2E2F7C] focus:outline-none"
></Input>
</Field>
</div>
</div>
<Button
className="rounded-md"
size="lg"
onClick={switchView}
>
Save
</Button>
<div className="w-[235px]">
<Field>
<Label className="mb-2 block text-sm font-medium">Status</Label>
<Select className="w-full rounded-lg bg-white p-2 shadow focus:ring-1 focus:ring-[#2E2F7C] focus:outline-none">
<option>Pilih Status</option>
<option>Aktif</option>
<option>Nonaktif</option>
</Select>
</Field>
</div>
</div>
<UiTable
data={SUBSETTINGS}
columns={colTableSubSetting}
options={{
paging: true,
searching: true,
ordering: true,
info: true,
}}
title=" Daftar Subscription"
/>
</>
)}
<Button
as="a"
className="rounded-md"
size="lg"
href="#"
>
Subscription Settings
</Button>
</div>
<UiTable
data={SUBSCRIPTIONS}
columns={colTableSubscription}
options={{
paging: true,
searching: true,
ordering: true,
info: true,
}}
title="Daftar Subscription"
/>
</div>
)
}

View File

@ -0,0 +1,4 @@
import { SubscribePlanPage } from '~/pages/dashboard-plan-subscribe'
const DashboardSubscriptionsSettingsLayout = () => <SubscribePlanPage />
export default DashboardSubscriptionsSettingsLayout

View File

@ -1,6 +1,7 @@
import { Outlet } from 'react-router'
import { getCategories } from '~/apis/common/get-categories'
import { getSubscriptions } from '~/apis/common/get-subscriptions'
import { getTags } from '~/apis/common/get-tags'
import { AdminDashboardLayout } from '~/layouts/admin/dashboard'
@ -9,10 +10,12 @@ import type { Route } from './+types/_admin.lg-admin._dashboard'
export const loader = async ({}: Route.LoaderArgs) => {
const { data: categoriesData } = await getCategories()
const { data: tagsData } = await getTags()
const { data: subscriptionsData } = await getSubscriptions()
return {
categoriesData,
tagsData,
subscriptionsData,
}
}