mirror of
https://github.com/chartdb/chartdb.git
synced 2026-01-13 23:41:33 -06:00
fix(templates): fetch templates data from router (#321)
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import React from 'react';
|
||||
import ChartDBLogo from '@/assets/logo-light.png';
|
||||
import ChartDBDarkLogo from '@/assets/logo-dark.png';
|
||||
import { useTheme } from '@/hooks/use-theme';
|
||||
@@ -7,49 +7,27 @@ import { ThemeProvider } from '@/context/theme-context/theme-provider';
|
||||
import { Component, Star } from 'lucide-react';
|
||||
import { ListMenu } from '@/components/list-menu/list-menu';
|
||||
import { TemplateCard } from './template-card/template-card';
|
||||
import { useMatches, useParams } from 'react-router-dom';
|
||||
import { useLoaderData, useMatches, useParams } from 'react-router-dom';
|
||||
import type { Template } from '@/templates-data/templates-data';
|
||||
import { Spinner } from '@/components/spinner/spinner';
|
||||
import { removeDups } from '@/lib/utils';
|
||||
import { Helmet } from 'react-helmet-async';
|
||||
|
||||
export interface TemplatesPageLoaderData {
|
||||
templates: Template[] | undefined;
|
||||
allTags: string[] | undefined;
|
||||
}
|
||||
|
||||
const TemplatesPageComponent: React.FC = () => {
|
||||
const { effectiveTheme } = useTheme();
|
||||
const data = useLoaderData() as TemplatesPageLoaderData;
|
||||
|
||||
const { templates, allTags } = data ?? {};
|
||||
const { tag } = useParams<{ tag: string }>();
|
||||
const matches = useMatches();
|
||||
const [templates, setTemplates] = React.useState<Template[]>();
|
||||
const [tags, setTags] = React.useState<string[]>();
|
||||
|
||||
const isFeatured = matches.some(
|
||||
(match) => match.id === 'templates_featured'
|
||||
);
|
||||
const isAllTemplates = matches.some((match) => match.id === 'templates');
|
||||
const isTags = matches.some((match) => match.id === 'templates_tags');
|
||||
|
||||
useEffect(() => {
|
||||
const loadTemplates = async () => {
|
||||
const { templates: loadedTemplates } = await import(
|
||||
'@/templates-data/templates-data'
|
||||
);
|
||||
|
||||
let templatesToLoad = loadedTemplates;
|
||||
|
||||
if (isFeatured) {
|
||||
templatesToLoad = loadedTemplates.filter((t) => t.featured);
|
||||
}
|
||||
|
||||
if (isTags && tag) {
|
||||
templatesToLoad = loadedTemplates.filter((t) =>
|
||||
t.tags.includes(tag)
|
||||
);
|
||||
}
|
||||
|
||||
setTemplates(templatesToLoad);
|
||||
setTags(removeDups(loadedTemplates?.flatMap((t) => t.tags) ?? []));
|
||||
};
|
||||
|
||||
loadTemplates();
|
||||
}, [isFeatured, isTags, tag]);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -125,10 +103,10 @@ const TemplatesPageComponent: React.FC = () => {
|
||||
<h4 className="mt-4 text-left text-sm font-semibold">
|
||||
Tags
|
||||
</h4>
|
||||
{tags ? (
|
||||
{allTags ? (
|
||||
<ListMenu
|
||||
className="mt-1 w-44 shrink-0"
|
||||
items={tags.map((currentTag) => ({
|
||||
items={allTags.map((currentTag) => ({
|
||||
title: currentTag,
|
||||
href: `/templates/tags/${currentTag}`,
|
||||
selected: tag === currentTag,
|
||||
|
||||
@@ -2,6 +2,8 @@ import React from 'react';
|
||||
import type { RouteObject } from 'react-router-dom';
|
||||
import { createBrowserRouter } from 'react-router-dom';
|
||||
import type { TemplatePageLoaderData } from './pages/template-page/template-page';
|
||||
import type { TemplatesPageLoaderData } from './pages/templates-page/templates-page';
|
||||
import { getTemplatesAndAllTags } from './templates-data/template-utils';
|
||||
|
||||
const routes: RouteObject[] = [
|
||||
...['', 'diagrams/:diagramId'].map((path) => ({
|
||||
@@ -38,6 +40,15 @@ const routes: RouteObject[] = [
|
||||
element: <TemplatesPage />,
|
||||
};
|
||||
},
|
||||
|
||||
loader: async (): Promise<TemplatesPageLoaderData> => {
|
||||
const { tags, templates } = await getTemplatesAndAllTags();
|
||||
|
||||
return {
|
||||
allTags: tags,
|
||||
templates,
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'templates_featured',
|
||||
@@ -50,6 +61,16 @@ const routes: RouteObject[] = [
|
||||
element: <TemplatesPage />,
|
||||
};
|
||||
},
|
||||
loader: async (): Promise<TemplatesPageLoaderData> => {
|
||||
const { tags, templates } = await getTemplatesAndAllTags({
|
||||
featured: true,
|
||||
});
|
||||
|
||||
return {
|
||||
allTags: tags,
|
||||
templates,
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'templates_tags',
|
||||
@@ -62,6 +83,16 @@ const routes: RouteObject[] = [
|
||||
element: <TemplatesPage />,
|
||||
};
|
||||
},
|
||||
loader: async ({ params }): Promise<TemplatesPageLoaderData> => {
|
||||
const { tags, templates } = await getTemplatesAndAllTags({
|
||||
tag: params.tag,
|
||||
});
|
||||
|
||||
return {
|
||||
allTags: tags,
|
||||
templates,
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'templates_templateSlug',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { Diagram } from '@/lib/domain/diagram';
|
||||
import type { Template } from './templates-data';
|
||||
import { generateId } from '@/lib/utils';
|
||||
import { generateId, removeDups } from '@/lib/utils';
|
||||
import type { DBTable } from '@/lib/domain/db-table';
|
||||
import type { DBField } from '@/lib/domain/db-field';
|
||||
import type { DBIndex } from '@/lib/domain/db-index';
|
||||
@@ -87,3 +87,30 @@ export const convertTemplateToNewDiagram = (template: Template): Diagram => {
|
||||
tables,
|
||||
};
|
||||
};
|
||||
|
||||
export const getTemplatesAndAllTags = async ({
|
||||
featured,
|
||||
tag,
|
||||
}: {
|
||||
featured?: boolean;
|
||||
tag?: string;
|
||||
} = {}): Promise<{ templates: Template[]; tags: string[] }> => {
|
||||
const { templates } = await import('@/templates-data/templates-data');
|
||||
const allTags = removeDups(templates?.flatMap((t) => t.tags) ?? []);
|
||||
|
||||
if (featured) {
|
||||
return {
|
||||
templates: templates.filter((t) => t.featured),
|
||||
tags: allTags,
|
||||
};
|
||||
}
|
||||
|
||||
if (tag) {
|
||||
return {
|
||||
templates: templates.filter((t) => t.tags.includes(tag)),
|
||||
tags: allTags,
|
||||
};
|
||||
}
|
||||
|
||||
return { templates, tags: allTags };
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user