Compare commits

2 Commits

Author SHA1 Message Date
f6fd1cc0fb fix: rename agenda form field name→title to prevent 1Password person-name autofill
All checks were successful
Client Check Build (NixCN CMS) TeamCity build finished
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 22:06:26 +08:00
2482b392b5 fix: remove resolve() wrapping of page.url.pathname in attendance pagination
All checks were successful
Client Check Build (NixCN CMS) TeamCity build finished
resolve() prepends the /app base path, but page.url.pathname already
includes it — causing double /app/ in pagination hrefs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 21:45:18 +08:00
6 changed files with 21 additions and 22 deletions

View File

@@ -39,7 +39,7 @@
$effect(() => {
if (open && mode === 'edit' && item) {
$form.name = item.name ?? '';
$form.title = item.name ?? '';
$form.description = item.description ?? '';
} else if (!open) {
reset();
@@ -75,18 +75,18 @@
<div class="flex flex-col gap-1">
<label for="agenda-name" class="text-sm font-medium">名称</label>
<label class="input w-full {$errors.name ? 'input-error' : ''}">
<label class="input w-full {$errors.title ? 'input-error' : ''}">
<input
id="agenda-name"
name="name"
name="title"
type="text"
placeholder="议程标题"
maxlength="255"
bind:value={$form.name}
bind:value={$form.title}
/>
</label>
{#if $errors.name}
<p class="text-xs text-error">{$errors.name}</p>
{#if $errors.title}
<p class="text-xs text-error">{$errors.title}</p>
{/if}
</div>

View File

@@ -7,28 +7,28 @@ import {
} from './agenda';
describe('agendaItemSchema', () => {
it('accepts name and description', () => {
expect(agendaItemSchema.safeParse({ name: '开幕式', description: '活动开场' }).success).toBe(
it('accepts title and description', () => {
expect(agendaItemSchema.safeParse({ title: '开幕式', description: '活动开场' }).success).toBe(
true
);
});
it('rejects empty name', () => {
expect(agendaItemSchema.safeParse({ name: '', description: '描述' }).success).toBe(false);
it('rejects empty title', () => {
expect(agendaItemSchema.safeParse({ title: '', description: '描述' }).success).toBe(false);
});
it('rejects name over 255 chars', () => {
expect(agendaItemSchema.safeParse({ name: 'a'.repeat(256), description: '描述' }).success).toBe(
it('rejects title over 255 chars', () => {
expect(agendaItemSchema.safeParse({ title: 'a'.repeat(256), description: '描述' }).success).toBe(
false
);
});
it('rejects missing description', () => {
expect(agendaItemSchema.safeParse({ name: '开幕式' }).success).toBe(false);
expect(agendaItemSchema.safeParse({ title: '开幕式' }).success).toBe(false);
});
it('rejects empty description', () => {
expect(agendaItemSchema.safeParse({ name: '开幕式', description: '' }).success).toBe(false);
expect(agendaItemSchema.safeParse({ title: '开幕式', description: '' }).success).toBe(false);
});
});

View File

@@ -1,10 +1,10 @@
import { z } from 'zod';
// Submit/Update form: name + description
// Submit/Update form: title + description
// description is required — backend stores it as base64 markdown for both
// postAgendaSubmit and patchAgendaUpdate.
export const agendaItemSchema = z.object({
name: z.string().min(1, '请填写名称').max(255, '名称最多 255 字'),
title: z.string().min(1, '请填写名称').max(255, '名称最多 255 字'),
description: z.string().min(1, '请填写描述')
});

View File

@@ -61,7 +61,7 @@ export const actions: Actions = {
client: api,
body: {
agenda_id,
name: fd.name,
name: fd.title,
// Backend stores description as base64; encode before sending.
description: fd.description ? Buffer.from(fd.description).toString('base64') : undefined
}

View File

@@ -1,5 +1,4 @@
<script lang="ts">
import { resolve } from '$app/paths';
import { page } from '$app/state';
import dayjs from '$lib/dayjs';
import type { PageData } from './$types';
@@ -97,14 +96,14 @@
<div class="join">
{#if data.page > 1}
<a
href={resolve(`${page.url.pathname}?page=${data.page - 1}` as '/')}
href={`${page.url.pathname}?page=${data.page - 1}`}
class="btn join-item btn-sm"
aria-label="上一页">«</a
>
{/if}
{#if hasNextPage}
<a
href={resolve(`${page.url.pathname}?page=${data.page + 1}` as '/')}
href={`${page.url.pathname}?page=${data.page + 1}`}
class="btn join-item btn-sm"
aria-label="下一页">»</a
>

View File

@@ -184,7 +184,7 @@ export const actions: Actions = {
client: api,
body: {
event_id: eventId,
name: fd.name,
name: fd.title,
description: Buffer.from(fullDescription).toString('base64')
}
})
@@ -209,7 +209,7 @@ export const actions: Actions = {
client: api,
body: {
agenda_id,
name: fd.name,
name: fd.title,
description: Buffer.from(fd.description).toString('base64')
}
})