89 lines
3.0 KiB
TypeScript
89 lines
3.0 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
import { Link, useNavigate } from "react-router-dom";
|
|
import { api, type StyleItem } from "../../api";
|
|
import { Button, Flash, PageHeader, Section } from "../../components/ui";
|
|
import { AppSelect, AppTextField } from "../../ui";
|
|
|
|
export function StylesPage() {
|
|
const navigate = useNavigate();
|
|
const [items, setItems] = useState<StyleItem[]>([]);
|
|
const [name, setName] = useState("");
|
|
const [from, setFrom] = useState("osm-bright");
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
const reload = () =>
|
|
api
|
|
.styles()
|
|
.then(setItems)
|
|
.catch((err: unknown) => setError(err instanceof Error ? err.message : "Не удалось загрузить стили"));
|
|
|
|
useEffect(() => {
|
|
void reload();
|
|
}, []);
|
|
|
|
const presets = items.filter((item) => item.isPreset);
|
|
const cloneFrom = presets.length > 0 ? from : "osm-bright";
|
|
|
|
return (
|
|
<>
|
|
<PageHeader
|
|
eyebrow="Стили"
|
|
title="Карта"
|
|
description="Клонируйте пресет и откройте визуальный редактор: слои, карта и свойства."
|
|
/>
|
|
<Section title="Клонировать пресет">
|
|
<div className="form-row">
|
|
<AppTextField id="style-name" label="Имя копии" value={name} onChange={(e) => setName(e.target.value)} placeholder="my-bright" />
|
|
<AppSelect
|
|
id="style-from"
|
|
label="Пресет"
|
|
value={cloneFrom}
|
|
onChange={(e) => setFrom(e.target.value)}
|
|
>
|
|
{(presets.length > 0 ? presets : [{ name: "osm-bright" }]).map((item) => (
|
|
<option key={item.name} value={item.name}>
|
|
{item.name}
|
|
</option>
|
|
))}
|
|
</AppSelect>
|
|
<Button
|
|
variant="primary"
|
|
onClick={() => {
|
|
setError(null);
|
|
void api
|
|
.cloneStyle(name, cloneFrom)
|
|
.then((created) => navigate(`/styles/${created.name}`))
|
|
.catch((err: unknown) => setError(err instanceof Error ? err.message : "Не удалось клонировать"));
|
|
}}
|
|
>
|
|
Клонировать
|
|
</Button>
|
|
</div>
|
|
<Flash error={error} />
|
|
</Section>
|
|
<Section title="Список">
|
|
<table className="data-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Имя</th>
|
|
<th>Источник</th>
|
|
<th>Тип</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{items.map((item) => (
|
|
<tr key={item.name}>
|
|
<td>
|
|
<Link to={`/styles/${item.name}`}>{item.name}</Link>
|
|
</td>
|
|
<td>{item.createdFrom ?? "—"}</td>
|
|
<td>{item.isPreset ? "пресет" : "мой"}</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</Section>
|
|
</>
|
|
);
|
|
}
|