101 lines
3.0 KiB
TypeScript
101 lines
3.0 KiB
TypeScript
import React, { useEffect, useState } from 'react';
|
|
import { api } from '../lib/api';
|
|
import { LeaveDto, LeaveType } from '../types';
|
|
|
|
const TYPES: LeaveType[] = ['ANNUAL', 'SICK', 'PERSONAL', 'MARRIAGE', 'MATERNITY', 'BEREAVEMENT'];
|
|
|
|
export default function Leave() {
|
|
const [list, setList] = useState<LeaveDto[]>([]);
|
|
const [type, setType] = useState<LeaveType>('ANNUAL');
|
|
const [startTime, setStartTime] = useState('');
|
|
const [endTime, setEndTime] = useState('');
|
|
const [reason, setReason] = useState('');
|
|
|
|
const load = () => api.get<LeaveDto[]>('/leave-requests/my').then(setList);
|
|
|
|
useEffect(() => {
|
|
load();
|
|
}, []);
|
|
|
|
const submit = async (e: React.FormEvent) => {
|
|
e.preventDefault();
|
|
await api.post('/leave-requests', {
|
|
type,
|
|
startTime: new Date(startTime).toISOString(),
|
|
endTime: new Date(endTime).toISOString(),
|
|
reason,
|
|
});
|
|
setReason('');
|
|
setStartTime('');
|
|
setEndTime('');
|
|
load();
|
|
};
|
|
|
|
return (
|
|
<div className="page animate-in">
|
|
<div className="page-header">
|
|
<h1>请假</h1>
|
|
<p>提交申请与查看记录</p>
|
|
</div>
|
|
|
|
<div className="grid cols-2">
|
|
<div className="card">
|
|
<div className="card-title">提交请假</div>
|
|
<form className="form" onSubmit={submit}>
|
|
<label>
|
|
类型
|
|
<select value={type} onChange={(e) => setType(e.target.value as LeaveType)}>
|
|
{TYPES.map((t) => (
|
|
<option key={t} value={t}>
|
|
{t}
|
|
</option>
|
|
))}
|
|
</select>
|
|
</label>
|
|
<label>
|
|
开始时间
|
|
<input
|
|
type="datetime-local"
|
|
value={startTime}
|
|
onChange={(e) => setStartTime(e.target.value)}
|
|
required
|
|
/>
|
|
</label>
|
|
<label>
|
|
结束时间
|
|
<input
|
|
type="datetime-local"
|
|
value={endTime}
|
|
onChange={(e) => setEndTime(e.target.value)}
|
|
required
|
|
/>
|
|
</label>
|
|
<label>
|
|
原因
|
|
<textarea value={reason} onChange={(e) => setReason(e.target.value)} required />
|
|
</label>
|
|
<button className="btn btn-primary">提交</button>
|
|
</form>
|
|
</div>
|
|
|
|
<div className="card">
|
|
<div className="card-title">我的请假</div>
|
|
<div className="list-stagger">
|
|
{list.map((l) => (
|
|
<div key={l.id} className="list-item">
|
|
<div className="list-title">
|
|
{l.type} · {l.status}
|
|
</div>
|
|
<div className="list-sub">
|
|
{new Date(l.startTime).toLocaleString()} → {new Date(l.endTime).toLocaleString()}
|
|
</div>
|
|
<div className="list-sub">{l.reason}</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|