forked from cerc-io/snowballtools-base
Refactor routes with layout and show search bar in project details page (#23)
* Refactor routes with layout and show search bar in project details page * Set common search layout for child routes
This commit is contained in:
parent
e93cca598a
commit
ef72a0351e
@ -1,14 +1,41 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
|
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
|
||||||
|
|
||||||
|
import DashboardLayout from './layouts/Dashboard';
|
||||||
import Home from './pages/index';
|
import Home from './pages/index';
|
||||||
import { homeRoutes } from './pages/routes';
|
import Settings from './pages/Settings';
|
||||||
|
import {
|
||||||
|
projectsRoutesWithSearch,
|
||||||
|
projectsRoutesWithoutSearch,
|
||||||
|
} from './pages/projects/routes';
|
||||||
|
import ProjectSearchLayout from './layouts/ProjectSearch';
|
||||||
|
|
||||||
const router = createBrowserRouter([
|
const router = createBrowserRouter([
|
||||||
|
{
|
||||||
|
element: <DashboardLayout />,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
element: <ProjectSearchLayout />,
|
||||||
|
children: [
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
element: <Home />,
|
element: <Home />,
|
||||||
children: homeRoutes,
|
},
|
||||||
|
{
|
||||||
|
path: 'projects',
|
||||||
|
children: projectsRoutesWithSearch,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'settings',
|
||||||
|
element: <Settings />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'projects',
|
||||||
|
children: projectsRoutesWithoutSearch,
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ const ProjectCard: React.FC<ProjectCardProps> = ({ project }) => {
|
|||||||
</MenuList>
|
</MenuList>
|
||||||
</Menu>
|
</Menu>
|
||||||
</div>
|
</div>
|
||||||
<div className="border-slate-200 border-t-2 border-solid p-4 bg-gray-50">
|
<div className="border-t-2 border-solid p-4 bg-gray-50">
|
||||||
<Typography variant="small" color="gray">
|
<Typography variant="small" color="gray">
|
||||||
{project.latestCommit.message}
|
{project.latestCommit.message}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
@ -17,7 +17,7 @@ interface ProjectsSearchProps {
|
|||||||
onChange?: (data: ProjectDetails) => void;
|
onChange?: (data: ProjectDetails) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProjectSearch = ({ onChange }: ProjectsSearchProps) => {
|
const ProjectSearchBar = ({ onChange }: ProjectsSearchProps) => {
|
||||||
const [items, setItems] = useState<ProjectDetails[]>([]);
|
const [items, setItems] = useState<ProjectDetails[]>([]);
|
||||||
const [selectedItem, setSelectedItem] = useState<ProjectDetails | null>(null);
|
const [selectedItem, setSelectedItem] = useState<ProjectDetails | null>(null);
|
||||||
|
|
||||||
@ -105,4 +105,4 @@ const ProjectSearch = ({ onChange }: ProjectsSearchProps) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ProjectSearch;
|
export default ProjectSearchBar;
|
@ -31,7 +31,7 @@ const DeployStep = ({
|
|||||||
const [collapse, setCollapse] = useState(false);
|
const [collapse, setCollapse] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="border-b-2 border-slate-200">
|
<div className="border-b-2">
|
||||||
<div className="flex justify-between p-2 gap-2">
|
<div className="flex justify-between p-2 gap-2">
|
||||||
{status === DeployStatus.NOT_STARTED && <div>{step}</div>}
|
{status === DeployStatus.NOT_STARTED && <div>{step}</div>}
|
||||||
{status === DeployStatus.PROCESSING && <div>O</div>}
|
{status === DeployStatus.PROCESSING && <div>O</div>}
|
||||||
|
@ -57,8 +57,8 @@ const DeleteProjectDialog = ({
|
|||||||
>
|
>
|
||||||
<DialogBody className="flex flex-col gap-2">
|
<DialogBody className="flex flex-col gap-2">
|
||||||
<Typography variant="paragraph">
|
<Typography variant="paragraph">
|
||||||
Deleting your project is irreversible. Enter your project’s name
|
Deleting your project is irreversible. Enter your project’s
|
||||||
|
name
|
||||||
<span className="bg-blue-100 text-blue-700">({project.name})</span>
|
<span className="bg-blue-100 text-blue-700">({project.name})</span>
|
||||||
below to confirm you want to permanently delete it:
|
below to confirm you want to permanently delete it:
|
||||||
</Typography>
|
</Typography>
|
||||||
|
21
packages/frontend/src/layouts/Dashboard.tsx
Normal file
21
packages/frontend/src/layouts/Dashboard.tsx
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Outlet } from 'react-router-dom';
|
||||||
|
|
||||||
|
import Sidebar from '../components/Sidebar';
|
||||||
|
|
||||||
|
const Dashboard = () => {
|
||||||
|
return (
|
||||||
|
<div className="grid grid-cols-5 h-screen bg-light-blue-50">
|
||||||
|
<div className="h-full">
|
||||||
|
<Sidebar />
|
||||||
|
</div>
|
||||||
|
<div className="col-span-4 h-full p-3">
|
||||||
|
<div className="bg-white rounded-3xl h-full">
|
||||||
|
<Outlet />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Dashboard;
|
31
packages/frontend/src/layouts/ProjectSearch.tsx
Normal file
31
packages/frontend/src/layouts/ProjectSearch.tsx
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Outlet } from 'react-router-dom';
|
||||||
|
|
||||||
|
import HorizontalLine from '../components/HorizontalLine';
|
||||||
|
import { IconButton, Typography } from '@material-tailwind/react';
|
||||||
|
import ProjectSearchBar from '../components/projects/ProjectSearchBar';
|
||||||
|
|
||||||
|
const ProjectSearch = () => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className="flex p-5">
|
||||||
|
<div className="grow mr-2">
|
||||||
|
<ProjectSearchBar onChange={() => {}} />
|
||||||
|
</div>
|
||||||
|
<IconButton color="blue" className="rounded-full mr-2">
|
||||||
|
<Typography variant="h5">+</Typography>
|
||||||
|
</IconButton>
|
||||||
|
<div className="mr-2 flex items-center">
|
||||||
|
<Typography>^</Typography>
|
||||||
|
</div>
|
||||||
|
<div className="px-2 py-1 bg-blue-gray-50 rounded-lg">
|
||||||
|
<Typography variant="lead">SY</Typography>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<HorizontalLine />
|
||||||
|
<Outlet />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ProjectSearch;
|
@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
const Settings = () => {
|
const Settings = () => {
|
||||||
return <div className="bg-white rounded-3xl h-full">Settings page</div>;
|
return <div className="p-5">Settings page</div>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Settings;
|
export default Settings;
|
||||||
|
@ -1,19 +1,40 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Outlet } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
import Sidebar from '../components/Sidebar';
|
import { Button, Typography, Chip } from '@material-tailwind/react';
|
||||||
|
|
||||||
const Home = () => {
|
import ProjectCard from '../components/projects/ProjectCard';
|
||||||
|
import projectsDetail from '../assets/projects.json';
|
||||||
|
|
||||||
|
const Projects = () => {
|
||||||
return (
|
return (
|
||||||
<div className="grid grid-cols-5 h-screen bg-light-blue-50">
|
<div>
|
||||||
<div className="h-full">
|
<div className="flex p-5">
|
||||||
<Sidebar />
|
<div className="grow">
|
||||||
|
<div className="flex gap-2 items-center">
|
||||||
|
<Typography variant="h4">Projects</Typography>
|
||||||
|
<Chip
|
||||||
|
className="bg-gray-300 rounded-full static"
|
||||||
|
value={projectsDetail.length}
|
||||||
|
size="sm"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-span-4 h-full p-3">
|
</div>
|
||||||
<Outlet />
|
<div>
|
||||||
|
<Link to="/projects/create">
|
||||||
|
<Button className="rounded-full" color="blue">
|
||||||
|
Create project
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="grid grid-cols-3 gap-5 p-5">
|
||||||
|
{projectsDetail.map((project, key) => {
|
||||||
|
return <ProjectCard project={project} key={key} />;
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Home;
|
export default Projects;
|
||||||
|
@ -1,20 +1,22 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Outlet, Link } from 'react-router-dom';
|
import { Outlet, Link } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { IconButton } from '@material-tailwind/react';
|
||||||
|
|
||||||
import HorizontalLine from '../../components/HorizontalLine';
|
import HorizontalLine from '../../components/HorizontalLine';
|
||||||
|
|
||||||
const CreateProject = () => {
|
const CreateProject = () => {
|
||||||
return (
|
return (
|
||||||
<div className="bg-white rounded-3xl h-full p-4">
|
<div className="h-full">
|
||||||
<div className="flex p-2">
|
<div className="flex p-4 items-center">
|
||||||
<div className="grow p-4">
|
<div className="grow">
|
||||||
<h3 className="text-gray-750 text-2xl">Create new project</h3>
|
<h3 className="text-gray-750 text-2xl">Create new project</h3>
|
||||||
</div>
|
</div>
|
||||||
<div className="p-4">
|
<div>
|
||||||
<Link to="/">
|
<Link to="/">
|
||||||
<button className="bg-slate-300 text-gray-700 text-sm px-4 py-2 border rounded-full">
|
<IconButton className="rounded-full" variant="outlined">
|
||||||
X
|
X
|
||||||
</button>
|
</IconButton>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -19,7 +19,7 @@ const Project = () => {
|
|||||||
const project = useMemo(() => getProject(Number(id)), [id]);
|
const project = useMemo(() => getProject(Number(id)), [id]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-white rounded-3xl h-full">
|
<div className="h-full">
|
||||||
{project ? (
|
{project ? (
|
||||||
<>
|
<>
|
||||||
<div className="flex p-4 gap-4 items-center">
|
<div className="flex p-4 gap-4 items-center">
|
||||||
|
@ -1,31 +1,14 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
import { Button, IconButton, Typography, Chip } from '@material-tailwind/react';
|
import { Button, Typography, Chip } from '@material-tailwind/react';
|
||||||
|
|
||||||
import ProjectCard from '../components/projects/ProjectCard';
|
import ProjectCard from '../../components/projects/ProjectCard';
|
||||||
import HorizontalLine from '../components/HorizontalLine';
|
import projectsDetail from '../../assets/projects.json';
|
||||||
import projectsDetail from '../assets/projects.json';
|
|
||||||
import ProjectSearch from '../components/projects/ProjectSearch';
|
|
||||||
|
|
||||||
const Projects = () => {
|
const Projects = () => {
|
||||||
return (
|
return (
|
||||||
<div className="bg-white rounded-3xl h-full">
|
<div>
|
||||||
<div className="flex p-4">
|
|
||||||
<div className="grow mr-2">
|
|
||||||
<ProjectSearch onChange={() => {}} />
|
|
||||||
</div>
|
|
||||||
<IconButton color="blue" className="rounded-full mr-2">
|
|
||||||
<Typography variant="h5">+</Typography>
|
|
||||||
</IconButton>
|
|
||||||
<div className="mr-2 flex items-center">
|
|
||||||
<Typography>^</Typography>
|
|
||||||
</div>
|
|
||||||
<div className="px-2 py-1 bg-blue-gray-50 rounded-lg">
|
|
||||||
<Typography variant="lead">SY</Typography>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<HorizontalLine />
|
|
||||||
<div className="flex p-5">
|
<div className="flex p-5">
|
||||||
<div className="grow">
|
<div className="grow">
|
||||||
<div className="flex gap-2 items-center">
|
<div className="flex gap-2 items-center">
|
@ -4,14 +4,17 @@ import CreateProject from './Create';
|
|||||||
import Project from './Project';
|
import Project from './Project';
|
||||||
import { createProjectRoutes } from './create/routes';
|
import { createProjectRoutes } from './create/routes';
|
||||||
|
|
||||||
export const projectsRoutes = [
|
export const projectsRoutesWithoutSearch = [
|
||||||
{
|
|
||||||
path: ':id',
|
|
||||||
element: <Project />,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: 'create',
|
path: 'create',
|
||||||
element: <CreateProject />,
|
element: <CreateProject />,
|
||||||
children: createProjectRoutes,
|
children: createProjectRoutes,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const projectsRoutesWithSearch = [
|
||||||
|
{
|
||||||
|
path: ':id',
|
||||||
|
element: <Project />,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
import Projects from './Projects';
|
|
||||||
import Settings from './Settings';
|
|
||||||
import { projectsRoutes } from './projects/routes';
|
|
||||||
|
|
||||||
export const homeRoutes = [
|
|
||||||
{
|
|
||||||
index: true,
|
|
||||||
element: <Projects />,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'settings',
|
|
||||||
element: <Settings />,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'projects',
|
|
||||||
children: projectsRoutes,
|
|
||||||
},
|
|
||||||
];
|
|
Loading…
Reference in New Issue
Block a user