Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"@radix-ui/react-separator": "^1.1.8",
"@radix-ui/react-slot": "^1.2.4",
"@radix-ui/react-tabs": "^1.1.13",
"@tanstack/react-table": "^8.21.3",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"lucide-react": "^0.575.0",
Expand Down
34 changes: 28 additions & 6 deletions src/api/activity/get-activities.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,30 @@
import { requestApi } from './request';
import type { Activity, ApiResult } from './types';
import { requestApi } from "./request"
import type { AdminActivityPageResponse, ApiResult } from "./types"

export async function GetActivities(): Promise<ApiResult<Activity[]>> {
return requestApi<Activity[]>('/admin/activities', {
method: 'GET',
});
export interface ActivityPageQuery {
page?: number
size?: number
sort?: string
keyword?: string
}

export async function GetActivities(
query: ActivityPageQuery,
): Promise<ApiResult<AdminActivityPageResponse>> {
const params = new URLSearchParams()

params.set("page", String(query.page ?? 0))
params.set("size", String(query.size ?? 50))

if (query.sort) {
params.set("sort", query.sort)
}

if (query.keyword && query.keyword.trim().length > 0) {
params.set("keyword", query.keyword.trim())
}

return requestApi<AdminActivityPageResponse>(`/admin/activities?${params.toString()}`, {
method: "GET",
})
}
23 changes: 16 additions & 7 deletions src/api/activity/types.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
export interface Activity {
activityId: number;
name: string;
pointAmount: number;
activityId: number
name: string
pointAmount: number
}

export interface MemberInfo {
memberId: number;
name: string;
studentId: string;
memberId: number
name: string
studentId: string
}

export type { ApiResult } from '@/lib/http/types';
export interface AdminActivityPageResponse {
content: Activity[]
page: number
size: number
totalElements: number
totalPages: number
hasNext: boolean
}

export type { ApiResult } from "@/lib/http/types"
30 changes: 26 additions & 4 deletions src/api/coupon/get-coupon-codes.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,28 @@
import { requestApi } from './request';
import type { AdminCouponCode, ApiResult } from './types';
import { requestApi } from "./request"
import type { AdminCouponCodePageResponse, ApiResult } from "./types"

export async function getCouponCodes(): Promise<ApiResult<AdminCouponCode[]>> {
return requestApi<AdminCouponCode[]>('/admin/coupons/code', { method: 'GET' });
export interface CouponCodePageQuery {
page?: number
size?: number
sort?: string
keyword?: string
}

export async function getCouponCodes(
query: CouponCodePageQuery,
): Promise<ApiResult<AdminCouponCodePageResponse>> {
const params = new URLSearchParams()

params.set("page", String(query.page ?? 0))
params.set("size", String(query.size ?? 50))

if (query.sort) {
params.set("sort", query.sort)
}

if (query.keyword && query.keyword.trim().length > 0) {
params.set("keyword", query.keyword.trim())
}

return requestApi<AdminCouponCodePageResponse>(`/admin/coupons/code?${params.toString()}`, { method: "GET" })
}
28 changes: 24 additions & 4 deletions src/api/coupon/get-coupons.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,26 @@
import { requestApi } from './request';
import type { AdminCoupon, ApiResult } from './types';
import { requestApi } from "./request"
import type { AdminCouponPageResponse, ApiResult } from "./types"

export async function getCoupons(): Promise<ApiResult<AdminCoupon[]>> {
return requestApi<AdminCoupon[]>('/admin/coupons', { method: 'GET' });
export interface CouponPageQuery {
page?: number
size?: number
sort?: string
keyword?: string
}

export async function getCoupons(query: CouponPageQuery): Promise<ApiResult<AdminCouponPageResponse>> {
const params = new URLSearchParams()

params.set("page", String(query.page ?? 0))
params.set("size", String(query.size ?? 50))

if (query.sort) {
params.set("sort", query.sort)
}

if (query.keyword && query.keyword.trim().length > 0) {
params.set("keyword", query.keyword.trim())
}

return requestApi<AdminCouponPageResponse>(`/admin/coupons?${params.toString()}`, { method: "GET" })
}
47 changes: 43 additions & 4 deletions src/api/coupon/get-issued-coupons.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,45 @@
import { requestApi } from './request';
import type { AdminIssuedCoupon, ApiResult } from './types';
import { requestApi } from "./request"
import type { AdminIssuedCouponPageResponse, ApiResult } from "./types"

export async function getIssuedCoupons(): Promise<ApiResult<AdminIssuedCoupon[]>> {
return requestApi<AdminIssuedCoupon[]>('/admin/coupons/issued', { method: 'GET' });
export interface IssuedCouponPageQuery {
page?: number
size?: number
sort?: string
keyword?: string
couponId?: number
memberId?: number
isValid?: boolean
}

export async function getIssuedCoupons(
query: IssuedCouponPageQuery,
): Promise<ApiResult<AdminIssuedCouponPageResponse>> {
const params = new URLSearchParams()

params.set("page", String(query.page ?? 0))
params.set("size", String(query.size ?? 50))

if (query.sort) {
params.set("sort", query.sort)
}

if (query.keyword && query.keyword.trim().length > 0) {
params.set("keyword", query.keyword.trim())
}

if (query.couponId !== undefined) {
params.set("couponId", String(query.couponId))
}

if (query.memberId !== undefined) {
params.set("memberId", String(query.memberId))
}

if (query.isValid !== undefined) {
params.set("isValid", String(query.isValid))
}

return requestApi<AdminIssuedCouponPageResponse>(`/admin/coupons/issued?${params.toString()}`, {
method: "GET",
})
}
89 changes: 58 additions & 31 deletions src/api/coupon/types.ts
Original file line number Diff line number Diff line change
@@ -1,43 +1,70 @@
export interface AdminCoupon {
couponId: number;
couponName: string;
discountAmount: number;
createdAt: string;
updatedAt: string;
couponId: number
couponName: string
discountAmount: number
createdAt: string
updatedAt: string
}

export interface AdminCouponCode {
codeCouponId: number;
couponId: number;
couponName: string;
code: string;
description: string | null;
isValid: boolean;
issuedCouponId: number | null;
usedAt: string | null;
createdAt: string;
codeCouponId: number
couponId: number
couponName: string
code: string
description: string | null
isValid: boolean
issuedCouponId: number | null
usedAt: string | null
createdAt: string
}

export interface AdminIssuedCoupon {
issuedCouponId: number;
couponId: number;
couponName: string;
discountAmount: number;
memberId: number;
memberName: string;
memberEmail: string;
isValid: boolean;
paymentId: number | null;
usedAt: string | null;
createdAt: string;
issuedCouponId: number
couponId: number
couponName: string
discountAmount: number
memberId: number
memberName: string
memberEmail: string
isValid: boolean
paymentId: number | null
usedAt: string | null
createdAt: string
}

export interface AdminMemberSummary {
memberId: number;
studentId: string | null;
name: string;
email: string;
role: string;
memberId: number
studentId: string | null
name: string
email: string
role: string
}

export type { ApiResult } from "@/lib/http/types";
export interface AdminCouponPageResponse {
content: AdminCoupon[]
page: number
size: number
totalElements: number
totalPages: number
hasNext: boolean
}

export interface AdminCouponCodePageResponse {
content: AdminCouponCode[]
page: number
size: number
totalElements: number
totalPages: number
hasNext: boolean
}

export interface AdminIssuedCouponPageResponse {
content: AdminIssuedCoupon[]
page: number
size: number
totalElements: number
totalPages: number
hasNext: boolean
}

export type { ApiResult } from "@/lib/http/types"
3 changes: 3 additions & 0 deletions src/components/admin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@ export { AdminPageHeader } from "@/components/admin/AdminPageHeader"
export { AdminSectionCard } from "@/components/admin/AdminSectionCard"
export { AdminTableEmptyRow } from "@/components/admin/AdminTableEmptyRow"
export { AdminSortableTableHead } from "@/components/admin/AdminSortableTableHead"
export { AdminDataTable } from "@/components/admin/table/AdminDataTable"
export { createSortingState, normalizeSingleSorting, serializeSortingState } from "@/components/admin/table/sorting"
export type { AdminColumnMeta, AdminDataTableProps, ColumnSortMap } from "@/components/admin/table/types"
Loading