generated from template/vite-react-template
add temp ticket
This commit is contained in:
parent
7fb0666612
commit
e56eaab69a
@ -42,6 +42,7 @@
|
||||
"@types/react-dom": "^19.1.1",
|
||||
"@vitejs/plugin-basic-ssl": "^2.0.0",
|
||||
"@vitejs/plugin-react": "^4.3.4",
|
||||
"commander": "^13.1.0",
|
||||
"tailwindcss": "^4.1.1",
|
||||
"typescript": "^5.8.2",
|
||||
"vite": "^6.2.4"
|
||||
|
@ -1,3 +0,0 @@
|
||||
packages:
|
||||
- 'submodules/*'
|
||||
- 'packages/*'
|
@ -1,5 +1,6 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { program } from 'commander';
|
||||
|
||||
export const root = process.cwd();
|
||||
|
||||
@ -9,3 +10,11 @@ export const clearWorkspace = () => {
|
||||
fs.rmSync(path.join(root, file), { recursive: true, force: true });
|
||||
}
|
||||
};
|
||||
|
||||
// clearWorkspace();
|
||||
program.option('-c, --clear', 'clear workspace').action((opts) => {
|
||||
if (opts.clear) {
|
||||
clearWorkspace();
|
||||
}
|
||||
});
|
||||
program.parse(process.argv);
|
||||
|
@ -1,5 +1,87 @@
|
||||
import { basename } from '../modules/basename';
|
||||
console.log('basename', basename);
|
||||
import { useState } from 'react';
|
||||
import { Box, Button, Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, IconButton } from '@mui/material';
|
||||
import { Edit, Delete } from 'lucide-react';
|
||||
import { ModalForm } from './ModalForm';
|
||||
|
||||
// 定义工单类型
|
||||
interface Ticket {
|
||||
id: number;
|
||||
title: string;
|
||||
status: string;
|
||||
priority: string;
|
||||
createTime: string;
|
||||
}
|
||||
|
||||
export const App = () => {
|
||||
return <div className='bg-slate-200 w-full h-full border'>123</div>;
|
||||
const [tickets, setTickets] = useState<Ticket[]>([]);
|
||||
const [open, setOpen] = useState(false);
|
||||
const [selectedTicket, setSelectedTicket] = useState<Ticket | null>(null);
|
||||
|
||||
const handleCreate = () => {
|
||||
setSelectedTicket(null);
|
||||
setOpen(true);
|
||||
};
|
||||
|
||||
const handleEdit = (ticket: Ticket) => {
|
||||
setSelectedTicket(ticket);
|
||||
setOpen(true);
|
||||
};
|
||||
|
||||
const handleDelete = (id: number) => {
|
||||
setTickets(tickets.filter((ticket) => ticket.id !== id));
|
||||
};
|
||||
|
||||
const handleSave = (data: Ticket) => {
|
||||
if (selectedTicket) {
|
||||
setTickets(tickets.map((t) => (t.id === selectedTicket.id ? data : t)));
|
||||
} else {
|
||||
setTickets([...tickets, { ...data, id: Date.now() }]);
|
||||
}
|
||||
setOpen(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<Box className='p-4'>
|
||||
<Box className='mb-4 flex justify-between'>
|
||||
<h1 className='text-2xl font-bold'>工单管理</h1>
|
||||
<Button variant='contained' onClick={handleCreate}>
|
||||
创建工单
|
||||
</Button>
|
||||
</Box>
|
||||
|
||||
<TableContainer component={Paper}>
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>标题</TableCell>
|
||||
<TableCell>状态</TableCell>
|
||||
<TableCell>优先级</TableCell>
|
||||
<TableCell>创建时间</TableCell>
|
||||
<TableCell>操作</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{tickets.map((ticket) => (
|
||||
<TableRow key={ticket.id}>
|
||||
<TableCell>{ticket.title}</TableCell>
|
||||
<TableCell>{ticket.status}</TableCell>
|
||||
<TableCell>{ticket.priority}</TableCell>
|
||||
<TableCell>{ticket.createTime}</TableCell>
|
||||
<TableCell>
|
||||
<IconButton onClick={() => handleEdit(ticket)}>
|
||||
<Edit className='w-4 h-4' />
|
||||
</IconButton>
|
||||
<IconButton onClick={() => handleDelete(ticket.id)}>
|
||||
<Delete className='w-4 h-4' />
|
||||
</IconButton>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
|
||||
<ModalForm open={open} onClose={() => setOpen(false)} onSave={handleSave} ticket={selectedTicket} />
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
121
src/pages/ModalForm.tsx
Normal file
121
src/pages/ModalForm.tsx
Normal file
@ -0,0 +1,121 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useForm, Controller } from 'react-hook-form';
|
||||
import {
|
||||
Dialog,
|
||||
DialogTitle,
|
||||
DialogContent,
|
||||
DialogActions,
|
||||
Button,
|
||||
TextField,
|
||||
MenuItem,
|
||||
Box
|
||||
} from '@mui/material';
|
||||
|
||||
interface Ticket {
|
||||
id: number;
|
||||
title: string;
|
||||
status: string;
|
||||
priority: string;
|
||||
createTime: string;
|
||||
}
|
||||
|
||||
interface ModalFormProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
onSave: (data: Ticket) => void;
|
||||
ticket: Ticket | null;
|
||||
}
|
||||
|
||||
export const ModalForm = ({ open, onClose, onSave, ticket }: ModalFormProps) => {
|
||||
const { control, handleSubmit, reset } = useForm<Ticket>({
|
||||
defaultValues: {
|
||||
title: '',
|
||||
status: '待处理',
|
||||
priority: '中',
|
||||
createTime: new Date().toLocaleString()
|
||||
}
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (ticket) {
|
||||
reset(ticket);
|
||||
} else {
|
||||
reset({
|
||||
title: '',
|
||||
status: '待处理',
|
||||
priority: '中',
|
||||
createTime: new Date().toLocaleString()
|
||||
});
|
||||
}
|
||||
}, [ticket, reset]);
|
||||
|
||||
const onSubmit = (data: Ticket) => {
|
||||
onSave(data);
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog open={open} onClose={onClose} maxWidth="sm" fullWidth>
|
||||
<DialogTitle>{ticket ? '编辑工单' : '创建工单'}</DialogTitle>
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<DialogContent>
|
||||
<Box className="space-y-4">
|
||||
<Controller
|
||||
name="title"
|
||||
control={control}
|
||||
rules={{ required: '请输入标题' }}
|
||||
render={({ field, fieldState }) => (
|
||||
<TextField
|
||||
{...field}
|
||||
label="标题"
|
||||
fullWidth
|
||||
error={!!fieldState.error}
|
||||
helperText={fieldState.error?.message}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
<Controller
|
||||
name="status"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<TextField
|
||||
{...field}
|
||||
select
|
||||
label="状态"
|
||||
fullWidth
|
||||
>
|
||||
<MenuItem value="待处理">待处理</MenuItem>
|
||||
<MenuItem value="处理中">处理中</MenuItem>
|
||||
<MenuItem value="已完成">已完成</MenuItem>
|
||||
</TextField>
|
||||
)}
|
||||
/>
|
||||
|
||||
<Controller
|
||||
name="priority"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<TextField
|
||||
{...field}
|
||||
select
|
||||
label="优先级"
|
||||
fullWidth
|
||||
>
|
||||
<MenuItem value="高">高</MenuItem>
|
||||
<MenuItem value="中">中</MenuItem>
|
||||
<MenuItem value="低">低</MenuItem>
|
||||
</TextField>
|
||||
)}
|
||||
/>
|
||||
</Box>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={onClose}>取消</Button>
|
||||
<Button type="submit" variant="contained">
|
||||
保存
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</form>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
22
turbo.json
22
turbo.json
@ -1,22 +0,0 @@
|
||||
{
|
||||
"$schema": "https://turbo.build/schema.json",
|
||||
"tasks": {
|
||||
"build": {
|
||||
"dependsOn": [
|
||||
"^build"
|
||||
],
|
||||
"outputs": [
|
||||
"dist/**"
|
||||
]
|
||||
},
|
||||
"dev:lib": {
|
||||
"persistent": true,
|
||||
"cache": true
|
||||
},
|
||||
"build:lib": {
|
||||
"dependsOn": [
|
||||
"^build:lib"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user