Фреймворк Fresh построен вокруг идеи минималистичных, высокопроизводительных веб-приложений на основе Deno. Dashboard в Fresh представляет собой набор страниц и компонентов, которые отображают данные в реальном времени или предоставляют пользователю визуальные отчёты и интерфейсы управления.
В основе архитектуры лежат следующие ключевые элементы:
routes/. Каждая страница Dashboard соответствует отдельному
файлу или папке с файлом index.tsx.components/, позволяют повторно использовать визуальные
элементы, такие как таблицы, графики, карточки статистики..ts или
.tsx файлы) могут напрямую взаимодействовать с базой данных
или внешними API, возвращая данные на клиент без необходимости
полноценного бэкенда.Стандартная структура Dashboard в Fresh выглядит следующим образом:
/dashboard
/routes
index.tsx
/analytics
index.tsx
_chart.tsx
/users
index.tsx
_userCard.tsx
/components
NavBar.tsx
Sidebar.tsx
StatsCard.tsx
/islands
LiveChart.tsx
Notifications.tsx
routes отвечает за страницы. Подпапки отражают
вложенные маршруты (/analytics, /users).components содержат статические элементы
интерфейса.islands используют концепцию islands
architecture: интерактивные компоненты, которые гидратируются
на клиенте, оставаясь статически отрендеренными на сервере.Fresh применяет серверный рендеринг (SSR) по умолчанию. Страницы
Dashboard обычно получают данные через функции handler:
import { Handlers } from "$fresh/server.ts";
export const handler: Handlers = {
async GET(_req, ctx) {
const users = await fetch("https://api.example.com/users").then(r => r.json());
return ctx.render({ users });
}
};
В этом примере данные загружаются на сервере, а затем передаются в
компонент страницы через ctx.render.
Компоненты в Fresh создаются с использованием JSX/TSX и могут быть как статическими, так и интерактивными. Пример карточки статистики:
interface StatsCardProps {
title: string;
value: number;
}
export default function StatsCard({ title, value }: StatsCardProps) {
return (
<div class="p-4 bg-white rounded shadow">
<h3 class="text-gray-500">{title}</h3>
<p class="text-2xl font-bold">{value}</p>
</div>
);
}
Для интерактивных элементов применяется island:
import { useState } from "preact/hooks";
export default function LiveChart({ initialData }: { initialData: number[] }) {
const [data, setData] = useState(initialData);
const updateData = () => {
const newValue = Math.floor(Math.random() * 100);
setData([...data.slice(1), newValue]);
};
return (
<div>
<canvas id="chart"></canvas>
<button onCl ick={updateData}>Обновить</button>
</div>
);
}
Island гидратируется только на клиенте, обеспечивая высокую производительность.
Для Dashboard важна удобная навигация. Fresh позволяет создавать многоуровневые меню с использованием компонентов Sidebar и NavBar:
export default function Sidebar() {
return (
<nav class="flex flex-col p-4 bg-gray-100 h-full">
<a href="/dashboard" class="mb-2">Главная</a>
<a href="/dashboard/analytics" class="mb-2">Аналитика</a>
<a href="/dashboard/users">Пользователи</a>
</nav>
);
}
Состояние приложения может храниться локально в islands или
управляться через Context API. Для сложных Dashboard полезно
интегрировать store-подходы, например
zustand или redux, но на небольших проектах
локального состояния достаточно.
Dashboard часто требует отображения динамических данных. Fresh позволяет напрямую работать с внешними API или базами данных через Deno runtime:
import { Client } from "https://deno.land/x/postgres/mod.ts";
const client = new Client({ user: "user", password: "pass", database: "dashboard" });
await client.connect();
const result = await client.queryArray("SELECT * FROM users");
await client.end();
Данные можно передавать в компоненты страницы через
ctx.render, обеспечивая серверный рендеринг и
SEO-оптимизацию.
Ключевые моменты для Dashboard:
Edge или
CDN.Графики и диаграммы интегрируются с помощью легковесных библиотек,
таких как Chart.js, или нативных canvas/ SVG. Использование
islands позволяет поддерживать интерактивность без полного JS-бандла на
каждой странице.
import { useEffect } FROM "preact/hooks";
import Chart from "chart.js/auto";
export default function AnalyticsChart({ data }: { data: number[] }) {
useEffect(() => {
const ctx = document.getElementById("chart") as HTMLCanvasElement;
new Chart(ctx, {
type: "line",
data: {
labels: data.map((_, i) => i),
datasets: [{ label: "Продажи", data }],
},
});
}, []);
return <canvas id="chart"></canvas>;
}
Для больших проектов структура должна оставаться модульной:
Fresh позволяет создавать Dashboard, которые остаются лёгкими и быстрыми даже при увеличении количества данных и страниц, благодаря серверному рендерингу, islands architecture и минимальному фронтенд-бандлу.