Skip to content
Draft
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
38 changes: 38 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Commands

| Command | Action |
| :---------------------- | :----------------------------------------------- |
| `pnpm install` | Installs dependencies |
| `pnpm run dev` | Starts local dev server |
| `pnpm run build` | Build your production site to `./dist/` |
| `pnpm run preview` | Preview your build locally, before deploying |
| `pnpm run lint` | Run ESLint for code linting |
| `pnpm run astro ...` | Run CLI commands like `astro add`, `astro check` |
| `pnpm run astro --help` | Get help using the Astro CLI |

## Code Structure

- **src/components**: Contains reusable UI components (Astro, React, Vue).
- **src/pages**: Contains page-level components and routes.
- **src/layouts**: Contains layout components for different page types.
- **src/utils**: Utility functions and helpers.
- **src/types**: TypeScript type definitions.
- **src/styles**: Global styles and Tailwind configuration.

## Key Technologies

- **Astro**: Static site generator.
- **React/Vue**: UI frameworks used for interactive components.
- **TailwindCSS**: Utility-first CSS framework.
- **ESLint**: JavaScript/TypeScript linting.
- **TypeScript**: Static typing for JavaScript.

## Notes

- The project uses `pnpm` as the package manager.
- Pre-commit hooks (via Husky) run ESLint on staged files.
- OpenAPI types are generated using `openapi-typescript`.
32 changes: 16 additions & 16 deletions src/pages/archive.astro
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,23 @@ tags.forEach((tag) => {
<section class="archive">
<div class="section-content section-tag">
{
tags.map((tag, index) => {
return (
<div class="archive-tag">
<h2 class="tag-header">{tag}</h2>
<div class="tag-post-list">
{posts[index].length !== 0
? (
<ArchivePostList posts={posts[index]} />
)
: (
<div class="no-posts">暂无文章</div>
)}
tags.map((tag, index) => {
return (
<div class="archive-tag">
<h2 class="tag-header">{tag}</h2>
<div class="tag-post-list">
{posts[index].length !== 0
? (
<ArchivePostList posts={posts[index]} />
)
: (
<div class="no-posts">暂无文章</div>
)}
</div>
</div>
</div>
)
})
}
)
})
}
</div>
</section>
</BaseLayout>
70 changes: 27 additions & 43 deletions src/pages/repair/EventAction.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { UserInfoResponse } from "@logto/browser"
import type { PublicMember } from "../../store/member"
import { EventStatus, type PublicEvent } from "../../types/event"
import { saturdayApiBaseUrl } from "../../utils/client"
import { saturdayClient } from "../../utils/client"
import { Button, Form, Select, SelectItem, Textarea } from "@heroui/react"
import { useEffect, useState } from "react"

Expand Down Expand Up @@ -104,17 +104,17 @@ export const EventActionCommit = (props: EventActionProps) => {

const onSubmit = async () => {
props.onLoading("commit")
const res = await fetch(`${saturdayApiBaseUrl}/member/events/${props.event.eventId}/commit`, {
method: "POST",
headers: {
Authorization: `Bearer ${props.identityContext.token}`,
ContentType: "application/json",
},
body: JSON.stringify({
const { data: res } = await saturdayClient.POST("/member/events/{EventId}/commit", {
body: {
size: formData.size,
content: formData.description,
}),
}).then(res => res.json())
},
params: {
path: {
EventId: props.event.eventId,
},
},
})
props.onLoading()
return props.onUpdated(res)
}
Expand Down Expand Up @@ -151,17 +151,13 @@ export const EventActionAlterCommit = (props: EventActionProps) => {

const onSubmit = async () => {
props.onLoading("alterCommit")
const res = await fetch(`${saturdayApiBaseUrl}/member/events/${props.event.eventId}/commit`, {
method: "PATCH",
headers: {
Authorization: `Bearer ${props.identityContext.token}`,
ContentType: "application/json",
},
body: JSON.stringify({
const { data: res } = await saturdayClient.POST("/member/events/{EventId}/commit", {
params: { path: { EventId: props.event.eventId } },
body: {
size: formData.size,
content: formData.description,
}),
}).then(res => res.json())
},
})
props.onLoading()
return props.onUpdated(res)
}
Expand Down Expand Up @@ -235,12 +231,9 @@ export const getAvailableEventActions = (event: PublicEvent, identityContext: Id
variant: "solid",
color: "primary",
handler: async () => {
return await fetch(`${saturdayApiBaseUrl}/member/events/${event.eventId}/accept`, {
method: "POST",
headers: {
Authorization: `Bearer ${identityContext.token}`,
},
}).then(res => res.json())
return await saturdayClient.POST("/member/events/{EventId}/accept", {
params: { path: { EventId: event.eventId } },
})
},
}),
})
Expand All @@ -256,12 +249,9 @@ export const getAvailableEventActions = (event: PublicEvent, identityContext: Id
action: "drop",
label: "放弃",
handler: async () => {
return await fetch(`${saturdayApiBaseUrl}/member/events/${event.eventId}/accept`, {
method: "DELETE",
headers: {
Authorization: `Bearer ${identityContext.token}`,
},
}).then(res => res.json())
return saturdayClient.DELETE("/member/events/{EventId}/accept", {
params: { path: { EventId: event.eventId } },
})
},
}),
})
Expand All @@ -281,12 +271,9 @@ export const getAvailableEventActions = (event: PublicEvent, identityContext: Id
color: "success",
label: "完成",
handler: async () => {
return await fetch(`${saturdayApiBaseUrl}/events/${event.eventId}/close`, {
method: "POST",
headers: {
Authorization: `Bearer ${identityContext.token}`,
},
}).then(res => res.json())
return await saturdayClient.POST("/events/{EventId}/close", {
params: { path: { EventId: event.eventId } },
})
},
}),
})
Expand All @@ -297,12 +284,9 @@ export const getAvailableEventActions = (event: PublicEvent, identityContext: Id
color: "danger",
label: "退回",
handler: async () => {
return await fetch(`${saturdayApiBaseUrl}/events/${event.eventId}/commit`, {
method: "DELETE",
headers: {
Authorization: `Bearer ${identityContext.token}`,
},
}).then(res => res.json())
return await saturdayClient.DELETE("/events/{EventId}/commit", {
params: { path: { EventId: event.eventId } },
})
},
}),
})
Expand Down
16 changes: 8 additions & 8 deletions src/pages/repair/ExportEventDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import {
DateRangePicker,
} from "@heroui/react"
import { parseDate } from "@internationalized/date"
import { saturdayApiBaseUrl } from "../../utils/client"
import { makeLogtoClient } from "../../utils/auth"
import { saturdayClient } from "../../utils/client"
import dayjs from "dayjs"

export function ExportExcelModal() {
Expand All @@ -31,16 +30,17 @@ export function ExportExcelModal() {
try {
const start = dateRange.start.toString() // Format: 'YYYY-MM-DD'
const end = dateRange.end.toString()
const url = `${saturdayApiBaseUrl}/events/xlsx?start_time=${start}&end_time=${end}`
// const url = `${saturdayApiBaseUrl}/events/xlsx?start_time=${start}&end_time=${end}`

const token = await makeLogtoClient().getAccessToken()
const response = await fetch(url, {
headers: {
Authorization: `Bearer ${token}`,
const { response } = await saturdayClient.GET("/events/xlsx", {
params: {
query: {
start_time: start,
end_time: end,
},
},
})
if (!response.ok) throw new Error("Download failed")

// Extract filename from Content-Disposition header
const disposition = response.headers.get("Content-Disposition")
let filename = "export.xlsx" // Default filename
Expand Down
10 changes: 2 additions & 8 deletions src/pages/repair/RepairAdmin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
import { useCallback, useEffect, useMemo, useRef, useState } from "react"
import { useAsyncList } from "@react-stately/data"
import type { components } from "../../types/saturday"
import { saturdayApiBaseUrl, saturdayClient } from "../../utils/client"
import { saturdayClient } from "../../utils/client"
import EventDetail, { EventStatusChip, type EventDetailRef } from "./EventDetail"
import dayjs from "dayjs"
import { EventStatus, UserEventStatus } from "../../types/event"
Expand Down Expand Up @@ -215,13 +215,7 @@ export default function App() {
return
}
setUserInfo(res)

const currentMember = await fetch(`${saturdayApiBaseUrl}/member`, {
method: "GET",
headers: {
Authorization: `Bearer ${token}`,
},
}).then(res => res.json())
const { data: currentMember } = await saturdayClient.GET("/member")
setCurrentMember(currentMember)
}
check()
Expand Down
Loading