Initial commit

This commit is contained in:
2026-01-14 20:23:10 +06:00
commit 954dd473d1
57 changed files with 8854 additions and 0 deletions

View File

@@ -0,0 +1,108 @@
import { useState } from 'react';
import { X } from 'lucide-react';
import axios from 'axios';
import { API_URL } from '../config';
export default function CreateServerModal({ token, theme, onClose, onCreated }) {
const [formData, setFormData] = useState({
name: '',
displayName: '',
startCommand: 'java -Xmx2G -Xms1G -jar server.jar nogui'
});
const [loading, setLoading] = useState(false);
const handleSubmit = async (e) => {
e.preventDefault();
setLoading(true);
try {
await axios.post(
`${API_URL}/api/servers/create`,
formData,
{ headers: { Authorization: `Bearer ${token}` } }
);
onCreated();
onClose();
} catch (error) {
alert(error.response?.data?.detail || 'Ошибка создания сервера');
} finally {
setLoading(false);
}
};
return (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4">
<div className={`${theme.secondary} rounded-2xl p-6 w-full max-w-md shadow-2xl ${theme.border} border`}>
<div className="flex items-center justify-between mb-6">
<h2 className={`text-xl font-bold ${theme.text}`}>Создать сервер</h2>
<button
onClick={onClose}
className={`${theme.textSecondary} hover:${theme.text} transition`}
>
<X className="w-6 h-6" />
</button>
</div>
<form onSubmit={handleSubmit} className="space-y-4">
<div>
<label className={`block text-sm font-medium mb-2 ${theme.text}`}>
Имя папки (только латиница, цифры, _ и -)
</label>
<input
type="text"
required
value={formData.name}
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
className={`w-full ${theme.input} ${theme.border} border rounded-xl px-4 py-2 ${theme.text} focus:outline-none focus:ring-2 focus:ring-blue-500 transition`}
placeholder="my_server"
/>
</div>
<div>
<label className={`block text-sm font-medium mb-2 ${theme.text}`}>
Отображаемое имя
</label>
<input
type="text"
required
value={formData.displayName}
onChange={(e) => setFormData({ ...formData, displayName: e.target.value })}
className={`w-full ${theme.input} ${theme.border} border rounded-xl px-4 py-2 ${theme.text} focus:outline-none focus:ring-2 focus:ring-blue-500 transition`}
placeholder="Мой сервер"
/>
</div>
<div>
<label className={`block text-sm font-medium mb-2 ${theme.text}`}>
Команда запуска
</label>
<input
type="text"
required
value={formData.startCommand}
onChange={(e) => setFormData({ ...formData, startCommand: e.target.value })}
className={`w-full ${theme.input} ${theme.border} border rounded-xl px-4 py-2 ${theme.text} focus:outline-none focus:ring-2 focus:ring-blue-500 transition`}
/>
</div>
<div className="flex gap-2 pt-4">
<button
type="button"
onClick={onClose}
className={`flex-1 ${theme.card} ${theme.hover} px-4 py-2 rounded-xl transition`}
>
Отмена
</button>
<button
type="submit"
disabled={loading}
className={`flex-1 ${theme.accent} ${theme.accentHover} px-4 py-2 rounded-xl disabled:opacity-50 transition text-white`}
>
{loading ? 'Создание...' : 'Создать'}
</button>
</div>
</form>
</div>
</div>
);
}