Files
hackaton-2025-web-frontend/src/App.js

170 lines
6.9 KiB
JavaScript
Raw Normal View History

2025-04-30 12:46:28 +03:00
import SendIcon from './img/paper-plane.png';
import { useState } from 'react';
import Message from './misc/Message';
2025-04-30 14:27:13 +03:00
import SendForm from './misc/SendForm';
import Spinner from './misc/Spinner';
import WaitResponse from './misc/WaitResponse';
2025-04-30 12:46:28 +03:00
import './App.css';
function App() {
2025-04-30 12:46:28 +03:00
const [Stage, setStage] = useState(0);
const [Loading, setLoading] = useState(false);
2025-04-30 14:27:13 +03:00
const [GenerationProcess, setGenerationProcess] = useState(false);
2025-04-30 12:46:28 +03:00
const [LoadingText, setLoadingText] = useState("");
const [formData, setFormData] = useState({
name: '',
work_place: '',
2025-04-30 14:27:13 +03:00
problem: '',
message: ''
2025-04-30 12:46:28 +03:00
});
const handleChange = (e) => {
const { name, value } = e.target;
setFormData((prev) => ({
...prev,
[name]: value
}));
};
2025-04-30 14:27:13 +03:00
const [messages, setMessages] = useState([]);
2025-04-30 12:46:28 +03:00
2025-04-30 14:27:13 +03:00
const addMessage = (text, self = true) => {
const newMessage = {
id: Date.now(), // уникальный ключ для нового элемента
text: text,
self: self
};
setMessages(prev => [...prev, newMessage]);
};
window.addMessage = addMessage;
2025-04-30 12:46:28 +03:00
const handleSubmit = (e) => {
e.preventDefault(); // Останавливаем стандартную отправку формы
console.log('Отправленные данные:', formData);
setLoading(true);
2025-04-30 14:27:13 +03:00
setTimeout(() => {
2025-04-30 12:46:28 +03:00
setStage(1);
setLoading(false);
2025-04-30 14:27:13 +03:00
addMessage(formData.message);
setTimeout(() => {
addMessage("Ваш вопрос отправлен в службу поддержки. Уже подбираем варианты решения проблемы...", false);
setTimeout(() => {
setGenerationProcess(true);
}, 500);
}, 500);
}, 500)
2025-04-30 12:46:28 +03:00
};
return (
2025-04-30 12:46:28 +03:00
<div className="flex w-full h-full justify-center items-center">
2025-04-30 14:27:13 +03:00
<div className="relative flex md:h-[550px] h-full md:w-[500px] w-full flex-col justify-center md:rounded-xl bg-gray-50 p-5 text-sm/7 text-gray-800 shadow-sm shadow-orange-500/50 dark:bg-gray-900 dark:text-gray-200">
2025-04-30 12:46:28 +03:00
2025-04-30 14:27:13 +03:00
<Spinner show={Loading} />
2025-04-30 12:46:28 +03:00
{Stage == 0 &&
2025-04-30 14:27:13 +03:00
<div className="p-0 md:p-4">
2025-04-30 12:46:28 +03:00
<h1 className="text-2xl font-bold text-gray-900 dark:text-gray-100">
Сообщить о проблеме
</h1>
<div className="space-y-6">
<p className="leading-5">
Чем подробнее вы опишете ситуацию, тем быстрее мы найдём решение
</p>
<form className="space-y-3" onSubmit={handleSubmit}>
<input
type="text"
name="name"
className="block w-full rounded-xl border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:border-orange-500 focus:ring-orange-500 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus:border-orange-500 dark:focus:ring-orange-500"
placeholder="Ваше имя *"
required={true}
value={formData.name}
onChange={handleChange}
/>
<input
type="text"
name="work_place"
className="block w-full rounded-xl border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:border-orange-500 focus:ring-orange-500 disabled:text-gray-500 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus:border-orange-500 dark:focus:ring-orange-500"
defaultValue="Рабочее место 192.168.0.24"
placeholder="Адрес рабочего места *"
required={true}
disabled={false}
value={formData.work_place}
onChange={handleChange}
/>
<select
name="problem"
className="mt-10 block w-full rounded-xl border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:border-orange-500 focus:ring-orange-500 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus:border-orange-500 dark:focus:ring-orange-500"
value={formData.problem}
onChange={handleChange}
2025-04-30 14:27:13 +03:00
>
2025-04-30 12:46:28 +03:00
<option value="0">Выберите тип проблемы *</option>
<option value="1">Ошибка в работе ПО</option>
<option value="2">Проблемы с доступом/паролями</option>
<option value="3">Не работает оборудование</option>
<option value="4">Другое</option>
</select>
<textarea
name="message"
rows={4}
className="block w-full rounded-xl border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:border-orange-500 focus:ring-orange-500 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus:border-orange-500 dark:focus:ring-orange-500"
placeholder="Добавьте описание *"
required={true}
value={formData.message}
onChange={handleChange}
/>
<button
type="submit"
className="text-md dark:bg-orange-600dark:focus:ring-orange-900 mb-2 w-full cursor-pointer rounded-xl bg-orange-500 px-5 py-2.5 font-bold text-white shadow-md duration-300 hover:scale-105 focus:outline-none"
>
Отправить
</button>
</form>
</div>
</div>
}
{Stage == 1 &&
<>
<div className="flex flex-col gap-3 w-full h-full items-start scroll-box">
2025-04-30 14:27:13 +03:00
{messages.map(message => (
<Message key={message.id} self={message.self} text={message.text} />
))}
2025-04-30 12:46:28 +03:00
2025-04-30 14:27:13 +03:00
<WaitResponse show={GenerationProcess} />
2025-04-30 12:46:28 +03:00
</div>
<div className="pt-4">
<form className='flex gap-3'>
<input
type="text"
id="name"
className="block w-full rounded-xl border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:border-orange-500 focus:ring-orange-500 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus:border-orange-500 dark:focus:ring-orange-500"
placeholder="Сообщение"
required=""
/>
<button type='submit' className='transition-transform duration-300 hover:rotate-45'>
2025-04-30 14:27:13 +03:00
<img src={SendIcon} className='h-6 w-6' />
2025-04-30 12:46:28 +03:00
</button>
</form>
</div>
</>
}
</div>
</div >
);
}
export default App;