120 lines
4.1 KiB
TypeScript
120 lines
4.1 KiB
TypeScript
import {
|
|
Box,
|
|
Button,
|
|
Container,
|
|
TextField,
|
|
Typography,
|
|
Paper,
|
|
Dialog,
|
|
DialogActions,
|
|
DialogContent,
|
|
DialogContentText,
|
|
DialogTitle,
|
|
FormControlLabel,
|
|
Checkbox
|
|
} from '@mui/material'
|
|
import { useEffect, useState } from 'react'
|
|
import { useNavigate, useParams } from 'react-router-dom'
|
|
import api from '../lib/api'
|
|
|
|
export default function CharacterEditPage() {
|
|
const { id } = useParams()
|
|
const navigate = useNavigate()
|
|
|
|
const [name, setName] = useState('')
|
|
const [server, setServer] = useState('')
|
|
const [combatPower, setCombatPower] = useState('')
|
|
const [isPublic, setIsPublic] = useState(false)
|
|
const [error, setError] = useState('')
|
|
const [openConfirm, setOpenConfirm] = useState(false)
|
|
|
|
useEffect(() => {
|
|
api.get(`/characters/${id}`)
|
|
.then(res => {
|
|
setName(res.data.name)
|
|
setServer(res.data.server || '')
|
|
setCombatPower(String(res.data.combat_power || ''))
|
|
setIsPublic(Boolean(res.data.is_public))
|
|
})
|
|
.catch(() => setError('캐릭터 정보를 불러오는 데 실패했습니다.'))
|
|
}, [id])
|
|
|
|
const handleUpdate = async () => {
|
|
try {
|
|
await api.put(`/characters/${id}`, {
|
|
name,
|
|
server,
|
|
power: Number(combatPower),
|
|
is_public: isPublic,
|
|
})
|
|
navigate('/characters')
|
|
} catch {
|
|
setError('캐릭터 수정에 실패했습니다.')
|
|
}
|
|
}
|
|
|
|
const handleDelete = async () => {
|
|
try {
|
|
await api.delete(`/characters/${id}`)
|
|
navigate('/characters')
|
|
} catch {
|
|
setError('캐릭터 삭제에 실패했습니다.')
|
|
}
|
|
}
|
|
|
|
return (
|
|
<Container maxWidth="sm" sx={{ mt: 4 }}>
|
|
<Typography variant="h5" gutterBottom>캐릭터 수정</Typography>
|
|
|
|
<Paper sx={{ p: 3 }}>
|
|
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
|
<TextField
|
|
label="캐릭터 이름"
|
|
value={name}
|
|
onChange={(e) => setName(e.target.value)}
|
|
fullWidth
|
|
/>
|
|
<TextField
|
|
label="서버"
|
|
value={server}
|
|
onChange={(e) => setServer(e.target.value)}
|
|
fullWidth
|
|
/>
|
|
<TextField
|
|
label="전투력"
|
|
value={combatPower}
|
|
onChange={(e) => setCombatPower(e.target.value)}
|
|
fullWidth
|
|
type="number"
|
|
/>
|
|
<FormControlLabel
|
|
control={<Checkbox checked={isPublic} onChange={e => setIsPublic(e.target.checked)} />}
|
|
label="친구에게 노출"
|
|
/>
|
|
|
|
{error && <Typography color="error">{error}</Typography>}
|
|
|
|
<Box display="flex" justifyContent="space-between" gap={2}>
|
|
<Button variant="contained" onClick={handleUpdate}>수정</Button>
|
|
<Button variant="outlined" color="error" onClick={() => setOpenConfirm(true)}>삭제</Button>
|
|
</Box>
|
|
</Box>
|
|
</Paper>
|
|
|
|
<Dialog
|
|
open={openConfirm}
|
|
onClose={() => setOpenConfirm(false)}
|
|
>
|
|
<DialogTitle>삭제 확인</DialogTitle>
|
|
<DialogContent>
|
|
<DialogContentText>정말 이 캐릭터를 삭제하시겠습니까?</DialogContentText>
|
|
</DialogContent>
|
|
<DialogActions>
|
|
<Button onClick={() => setOpenConfirm(false)}>취소</Button>
|
|
<Button onClick={handleDelete} color="error">삭제</Button>
|
|
</DialogActions>
|
|
</Dialog>
|
|
</Container>
|
|
)
|
|
}
|