chore: update project files

This commit is contained in:
2026-02-13 23:23:36 +08:00
parent 66e438978e
commit 6a2d2c9724
1361 changed files with 4298 additions and 5117 deletions

View File

@@ -0,0 +1,111 @@
<script setup lang="ts">
import { reactive, watch } from 'vue'
import type { Task } from '../types'
import { t } from '../i18n'
const props = defineProps<{
modelValue: boolean
editingTask?: Task | null
}>()
const emit = defineEmits<{
'update:modelValue': [boolean]
submit: [payload: Partial<Task>]
}>()
const form = reactive({
title: '',
description: '',
due_at: '',
priority: 2,
tags: '',
})
watch(
() => props.editingTask,
(task) => {
form.title = task?.title ?? ''
form.description = task?.description ?? ''
form.due_at = toLocal(task?.due_at ?? '')
form.priority = task?.priority ?? 2
form.tags = task?.tags?.join(', ') ?? ''
},
{ immediate: true },
)
watch(
() => props.modelValue,
(open) => {
if (!open && !props.editingTask) {
form.title = ''
form.description = ''
form.due_at = ''
form.priority = 2
form.tags = ''
}
},
)
function close() {
emit('update:modelValue', false)
}
function save() {
emit('submit', {
title: form.title,
description: form.description,
due_at: form.due_at ? new Date(form.due_at).toISOString() : '',
priority: Number(form.priority),
tags: form.tags
.split(',')
.map((v) => v.trim())
.filter(Boolean),
})
}
function toLocal(v: string) {
if (!v) return ''
const d = new Date(v)
if (Number.isNaN(d.getTime())) return ''
const offset = d.getTimezoneOffset() * 60000
return new Date(d.getTime() - offset).toISOString().slice(0, 16)
}
</script>
<template>
<div v-if="modelValue" class="modal-mask" @click.self="close">
<section class="modal">
<header>
<h3>{{ editingTask ? t('edit_todo') : t('create_todo') }}</h3>
</header>
<label>
{{ t('title') }}
<input v-model="form.title" type="text" required />
</label>
<label>
{{ t('due_at') }}
<input v-model="form.due_at" type="datetime-local" />
</label>
<label>
{{ t('priority') }}
<select v-model="form.priority">
<option :value="1">{{ t('high') }}</option>
<option :value="2">{{ t('medium') }}</option>
<option :value="3">{{ t('low') }}</option>
</select>
</label>
<label>
{{ t('tags') }}
<input v-model="form.tags" type="text" :placeholder="t('tags_placeholder')" />
</label>
<label>
{{ t('description') }}
<textarea v-model="form.description" rows="4"></textarea>
</label>
<div class="modal-actions">
<button class="btn" @click="close">{{ t('cancel') }}</button>
<button class="btn primary" @click="save">{{ t('save') }}</button>
</div>
</section>
</div>
</template>