비밀번호 변경
This commit is contained in:
@@ -32,6 +32,7 @@ const AppContent = ({ options, showLogin, setShowLogin }) => {
|
||||
showTCPServerEdit: false,
|
||||
showQueueEdit: false,
|
||||
showUserEdit: false,
|
||||
showPasswordChange: false,
|
||||
selectedItem: null,
|
||||
});
|
||||
|
||||
@@ -77,6 +78,9 @@ const AppContent = ({ options, showLogin, setShowLogin }) => {
|
||||
case 'variables-show':
|
||||
setDialogState(prev => ({ ...prev, showVariableModal: true }));
|
||||
break;
|
||||
case 'change-password':
|
||||
setDialogState(prev => ({ ...prev, showPasswordChange: true }));
|
||||
break;
|
||||
case 'logout':
|
||||
const success = await handleLogout();
|
||||
if (success) {
|
||||
@@ -139,6 +143,7 @@ const AppContent = ({ options, showLogin, setShowLogin }) => {
|
||||
showQueueEdit={dialogState.showQueueEdit}
|
||||
showUserEdit={dialogState.showUserEdit}
|
||||
selectedItem={dialogState.selectedItem}
|
||||
showPasswordChange={dialogState.showPasswordChange}
|
||||
onDialogChange={handleDialogChange}
|
||||
/>
|
||||
<div className="flex-1 mt-14">
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogFooter,
|
||||
} from '@/components/ui/dialog';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Alert, AlertDescription } from '@/components/ui/alert';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { getCSRFToken } from '@/services/token.js';
|
||||
|
||||
const PasswordChangeDialog = ({ open, onOpenChange }) => {
|
||||
const [formData, setFormData] = useState({
|
||||
oldPassword: '',
|
||||
newPassword: '',
|
||||
newPassword2: ''
|
||||
});
|
||||
const [message, setMessage] = useState({ type: '', content: '' });
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const resetForm = () => {
|
||||
setFormData({
|
||||
oldPassword: '',
|
||||
newPassword: '',
|
||||
newPassword2: ''
|
||||
});
|
||||
setMessage({ type: '', content: '' });
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
resetForm();
|
||||
onOpenChange(false);
|
||||
};
|
||||
|
||||
const validateForm = () => {
|
||||
if (!formData.oldPassword) {
|
||||
setMessage({ type: 'error', content: '현재 비밀번호를 입력해주세요.' });
|
||||
return false;
|
||||
}
|
||||
if (!formData.newPassword) {
|
||||
setMessage({ type: 'error', content: '새 비밀번호를 입력해주세요.' });
|
||||
return false;
|
||||
}
|
||||
if (formData.newPassword !== formData.newPassword2) {
|
||||
setMessage({ type: 'error', content: '새 비밀번호가 일치하지 않습니다.' });
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
const handleSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
if (!validateForm()) return;
|
||||
|
||||
setIsLoading(true);
|
||||
setMessage({ type: '', content: '' });
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/account/password', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-XSRF-TOKEN': getCSRFToken()
|
||||
},
|
||||
body: JSON.stringify(formData)
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || '비밀번호 변경에 실패했습니다.');
|
||||
}
|
||||
|
||||
setMessage({ type: 'success', content: '비밀번호가 성공적으로 변경되었습니다.' });
|
||||
setTimeout(() => {
|
||||
handleClose();
|
||||
}, 2000);
|
||||
} catch (error) {
|
||||
setMessage({ type: 'error', content: error.message });
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={handleClose}>
|
||||
<DialogContent className="sm:max-w-[425px]">
|
||||
<DialogHeader>
|
||||
<DialogTitle>비밀번호 변경</DialogTitle>
|
||||
</DialogHeader>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<div className="grid gap-4 py-4">
|
||||
{message.content && (
|
||||
<Alert variant={message.type === 'error' ? 'destructive' : 'default'}>
|
||||
<AlertDescription>{message.content}</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
<div className="grid grid-cols-4 items-center gap-4">
|
||||
<Label htmlFor="oldPassword" className="text-right">
|
||||
현재 비밀번호
|
||||
</Label>
|
||||
<Input
|
||||
id="oldPassword"
|
||||
type="password"
|
||||
value={formData.oldPassword}
|
||||
onChange={(e) => setFormData(prev => ({ ...prev, oldPassword: e.target.value }))}
|
||||
className="col-span-3"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div className="grid grid-cols-4 items-center gap-4">
|
||||
<Label htmlFor="newPassword" className="text-right">
|
||||
새 비밀번호
|
||||
</Label>
|
||||
<Input
|
||||
id="newPassword"
|
||||
type="password"
|
||||
value={formData.newPassword}
|
||||
onChange={(e) => setFormData(prev => ({ ...prev, newPassword: e.target.value }))}
|
||||
className="col-span-3"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div className="grid grid-cols-4 items-center gap-4">
|
||||
<Label htmlFor="newPassword2" className="text-right">
|
||||
새 비밀번호 확인
|
||||
</Label>
|
||||
<Input
|
||||
id="newPassword2"
|
||||
type="password"
|
||||
value={formData.newPassword2}
|
||||
onChange={(e) => setFormData(prev => ({ ...prev, newPassword2: e.target.value }))}
|
||||
className="col-span-3"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<Button type="button" variant="secondary" onClick={handleClose}>
|
||||
취소
|
||||
</Button>
|
||||
<Button type="submit" disabled={isLoading}>
|
||||
{isLoading ? '변경 중...' : '변경'}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</form>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
export default PasswordChangeDialog;
|
||||
@@ -7,6 +7,7 @@ import MockRouteEditDialog from '@/components/mock-route/MockRouteEditDialog.jsx
|
||||
import TCPServerEditDialog from '@/components/tcp-servers/TCPServerEditDialog.jsx';
|
||||
import QueueEditDialog from '@/components/queues/QueueEditDialog.jsx';
|
||||
import UserEditDialog from '@/components/users/UserEditDialog.jsx';
|
||||
import PasswordChangeDialog from '@/components/account/PasswordChangeDialog.jsx';
|
||||
|
||||
const DialogManager = ({
|
||||
showAddApi,
|
||||
@@ -18,6 +19,7 @@ const DialogManager = ({
|
||||
showQueueEdit,
|
||||
showUserEdit,
|
||||
selectedItem,
|
||||
showPasswordChange,
|
||||
onDialogChange
|
||||
}) => {
|
||||
|
||||
@@ -58,6 +60,10 @@ const DialogManager = ({
|
||||
onOpenChange={(isOpen) => onDialogChange('showUserEdit', isOpen)}
|
||||
item={selectedItem}
|
||||
/>
|
||||
<PasswordChangeDialog
|
||||
open={showPasswordChange}
|
||||
onOpenChange={(isOpen) => onDialogChange('showPasswordChange', isOpen)}
|
||||
/>
|
||||
</>;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user