2024-06-22 18:34:39 +08:00
|
|
|
import { TitleIconBg } from "@/components/bs-comp/cardComponent";
|
2024-06-13 15:11:41 +08:00
|
|
|
import { Button } from "@/components/bs-ui/button";
|
|
|
|
|
import { DialogClose, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/bs-ui/dialog";
|
|
|
|
|
import { Input, Textarea } from "@/components/bs-ui/input";
|
|
|
|
|
import { useToast } from "@/components/bs-ui/toast/use-toast";
|
|
|
|
|
import { useEffect, useState } from "react";
|
|
|
|
|
import { useTranslation } from "react-i18next";
|
2024-06-22 18:34:39 +08:00
|
|
|
import npcIcon from "../../../../assets/npc/npcIcon.png";
|
|
|
|
|
import huifumoren from "../../../../assets/npc/huifumoren.png";
|
|
|
|
|
import { uploadNpcHeaderLibFileWithProgress } from "@/modals/UploadModal/upload";
|
2024-06-13 15:11:41 +08:00
|
|
|
|
2024-06-22 18:34:39 +08:00
|
|
|
export default function EditAssistantDialog({ name, desc, avatar_img, avatar_color, onSave }) {
|
2024-06-13 15:11:41 +08:00
|
|
|
|
|
|
|
|
const { t } = useTranslation()
|
|
|
|
|
// State for form fields
|
2024-06-22 18:34:39 +08:00
|
|
|
const [formData, setFormData] = useState({ name: '', desc: '', avatar_img: '', avatar_color: '' });
|
2024-06-13 15:11:41 +08:00
|
|
|
useEffect(() => {
|
2024-06-22 18:34:39 +08:00
|
|
|
setFormData({ name, desc, avatar_img, avatar_color })
|
|
|
|
|
}, [name, desc, avatar_img, avatar_color])
|
|
|
|
|
console.log(formData, name, desc, avatar_img, avatar_color);
|
2024-06-13 15:11:41 +08:00
|
|
|
|
|
|
|
|
// State for errors
|
|
|
|
|
const [errors, setErrors] = useState<any>({});
|
|
|
|
|
|
|
|
|
|
// Validate form fields
|
|
|
|
|
const validateField = (name, value) => {
|
|
|
|
|
switch (name) {
|
|
|
|
|
case 'name':
|
|
|
|
|
if (!value) return t('build.nameRequired');
|
|
|
|
|
if (value.length > 50) return t('build.nameMaxLength');
|
|
|
|
|
return '';
|
|
|
|
|
case 'desc':
|
|
|
|
|
if (value.length > 1000) return t('build.descMaxLength');
|
|
|
|
|
return '';
|
|
|
|
|
default:
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Handle field change
|
|
|
|
|
const handleChange = (e) => {
|
|
|
|
|
const { name, value } = e.target;
|
|
|
|
|
const error = validateField(name, value);
|
|
|
|
|
|
|
|
|
|
setFormData(prev => ({ ...prev, [name]: value }));
|
|
|
|
|
setErrors(prev => ({ ...prev, [name]: error }));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Validate entire form
|
|
|
|
|
const validateForm = () => {
|
|
|
|
|
const formErrors = {};
|
|
|
|
|
let isValid = true;
|
|
|
|
|
|
|
|
|
|
Object.keys(formData).forEach(key => {
|
|
|
|
|
const error = validateField(key, formData[key]);
|
|
|
|
|
if (error) {
|
|
|
|
|
formErrors[key] = error;
|
|
|
|
|
isValid = false;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
setErrors(formErrors);
|
|
|
|
|
return isValid;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const { message, toast } = useToast()
|
|
|
|
|
// Handle form submission
|
|
|
|
|
const handleSubmit = (e) => {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
const isValid = validateForm();
|
|
|
|
|
// console.log('Form data:', errors);
|
|
|
|
|
if (!isValid) return toast({
|
|
|
|
|
title: t('prompt'),
|
|
|
|
|
variant: 'error',
|
|
|
|
|
description: Object.keys(errors).map(key => errors[key]),
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
onSave(formData)
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
2024-06-22 18:34:39 +08:00
|
|
|
const handleButtonClick = () => {
|
|
|
|
|
// Create a file input element
|
|
|
|
|
const input = document.createElement("input");
|
|
|
|
|
input.type = "file";
|
|
|
|
|
input.accept = "image/*";
|
|
|
|
|
input.style.display = "none"; // Hidden from view
|
|
|
|
|
input.multiple = false; // Allow only one file selection
|
|
|
|
|
|
|
|
|
|
input.onchange = (e: Event) => {
|
|
|
|
|
// setLoading(true);
|
|
|
|
|
// Get the selected file
|
|
|
|
|
const file = (e.target as HTMLInputElement).files?.[0];
|
|
|
|
|
// Check if the file type is correct
|
|
|
|
|
// Upload the file
|
|
|
|
|
uploadNpcHeaderLibFileWithProgress(file, (progress) => { }).then(res => {
|
|
|
|
|
// setLoading(false);
|
|
|
|
|
setFormData({ name, desc, avatar_img: res, avatar_color })
|
|
|
|
|
})
|
|
|
|
|
};
|
|
|
|
|
// Trigger the file selection dialog
|
|
|
|
|
input.click();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return <DialogContent className="sm:max-w-[625px] bg-[#262626]">
|
2024-06-13 15:11:41 +08:00
|
|
|
<DialogHeader>
|
2024-06-22 18:34:39 +08:00
|
|
|
<DialogTitle className="text-[#fff]">{t('build.editAssistant')}</DialogTitle>
|
2024-06-13 15:11:41 +08:00
|
|
|
</DialogHeader>
|
|
|
|
|
<div className="flex flex-col gap-8 py-6">
|
2024-06-22 18:34:39 +08:00
|
|
|
<div>
|
|
|
|
|
<label htmlFor="name" className="bisheng-label text-[#999999]"><span className="bisheng-tip text-[#FF6060]">* </span>NPC头像</label>
|
|
|
|
|
{/* <TitleIconBg className="w-[40px] h-[40px] min-w-[40px]" img={item.avatar_img} id={item.avatar_color ? item.avatar_color : item.id} ><img src={item.avatar_img ? item.avatar_img : npcIcon} alt="" /></TitleIconBg> */}
|
|
|
|
|
|
|
|
|
|
<div className="flex items-center ml-[7px] mt-[6px]">
|
|
|
|
|
<TitleIconBg className="w-[41px] h-[41px] min-w-[41px]" img={formData.avatar_img} id={formData.avatar_color} ><img onClick={handleButtonClick} src={formData.avatar_img ? formData.avatar_img : npcIcon} alt="" /></TitleIconBg>
|
|
|
|
|
<div className="flex items-center justify-center ml-[20px] w-[95px] h-[27px] bg-[#333333] cursor-pointer" style={{borderRadius:"14px"}} onClick={() => setFormData({ name, desc, avatar_img: '', avatar_color })}>
|
|
|
|
|
<img src={huifumoren} className="w-[12px] h-[11px]" alt="" />
|
|
|
|
|
<span className="ml-[5px] text-[#999999] text-[12px] mt-[1px]">恢复默认</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2024-06-13 15:11:41 +08:00
|
|
|
<div className="">
|
2024-06-22 18:34:39 +08:00
|
|
|
<label htmlFor="name" className="bisheng-label text-[#999999]">{t('build.assistantName')}<span className="bisheng-tip text-[#FF6060]">*</span></label>
|
|
|
|
|
<Input id="name" name="name" placeholder={t('build.enterName')} className="mt-2 npcInput" value={formData.name} onChange={handleChange} />
|
|
|
|
|
{errors.name && <p className="bisheng-tip mt-1 text-[#999999]">{errors.name}</p>}
|
2024-06-13 15:11:41 +08:00
|
|
|
</div>
|
|
|
|
|
<div className="">
|
2024-06-22 18:34:39 +08:00
|
|
|
<label htmlFor="desc" className="bisheng-label text-[#999999]">{t('build.assistantDesc')}</label>
|
|
|
|
|
<Textarea id="desc" name="desc" placeholder={t('build.enterDesc')} maxLength={1200} className="mt-2 npcInput no-scrollbar" value={formData.desc} onChange={handleChange} />
|
2024-06-13 15:11:41 +08:00
|
|
|
{errors.desc && <p className="bisheng-tip mt-1">{errors.desc}</p>}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<DialogFooter>
|
|
|
|
|
<DialogClose>
|
2024-06-22 18:34:39 +08:00
|
|
|
<Button variant="outline" className="px-11 baogao-btn baogao-btn2" type="button">{t('build.cancel')}</Button>
|
2024-06-13 15:11:41 +08:00
|
|
|
</DialogClose>
|
2024-06-22 18:34:39 +08:00
|
|
|
<Button type="submit" className="px-11 baogao-btn baogao-btn2" onClick={handleSubmit}>{t('build.confirm')}</Button>
|
2024-06-13 15:11:41 +08:00
|
|
|
</DialogFooter>
|
|
|
|
|
</DialogContent>
|
|
|
|
|
};
|
|
|
|
|
|