Implement projects page with cards (#7)
* Implement layout for the projects page * Organize pages according to routes * Handle data from search bar * Get search data on submit --------- Co-authored-by: neeraj <neeraj.rtly@gmail.com>
This commit is contained in:
parent
4f6a523f56
commit
c6c3ab03c3
@ -12,6 +12,7 @@
|
|||||||
"@types/react-dom": "^18.2.17",
|
"@types/react-dom": "^18.2.17",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
"react-hook-form": "^7.49.0",
|
||||||
"react-router-dom": "^6.20.1",
|
"react-router-dom": "^6.20.1",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
"typescript": "^4.9.5",
|
"typescript": "^4.9.5",
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
|
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
|
||||||
|
|
||||||
import Dashboard from './pages/dashboard';
|
import Home from './pages';
|
||||||
import { dashboardRoutes } from './pages/dashboard/routes';
|
import { homeRoutes } from './pages/routes';
|
||||||
|
|
||||||
const router = createBrowserRouter([
|
const router = createBrowserRouter([
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
element: <Dashboard />,
|
element: <Home />,
|
||||||
children: dashboardRoutes,
|
children: homeRoutes,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
22
packages/frontend/src/components/Card.tsx
Normal file
22
packages/frontend/src/components/Card.tsx
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
const Card = () => {
|
||||||
|
return (
|
||||||
|
<div className="bg-white border border-gray-200 rounded-lg shadow">
|
||||||
|
<div className="flex gap-2 p-2 items-center">
|
||||||
|
<div>^</div>
|
||||||
|
<div className="grow">
|
||||||
|
<p className="text-sm text-gray-750">iglotools</p>
|
||||||
|
<p className="text-sm text-gray-400">iglotools.com</p>
|
||||||
|
</div>
|
||||||
|
<div>...</div>
|
||||||
|
</div>
|
||||||
|
<div className="border-slate-200 border-t-2 border-solid p-4 text-gray-500 text-xs">
|
||||||
|
<p>Hello world</p>
|
||||||
|
<p>3 day ago main</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Card;
|
42
packages/frontend/src/components/SearchBar.tsx
Normal file
42
packages/frontend/src/components/SearchBar.tsx
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { useForm, SubmitHandler } from 'react-hook-form';
|
||||||
|
|
||||||
|
interface SearchBarProps {
|
||||||
|
handler: (searchText: SearchInputs) => void;
|
||||||
|
placeholder?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SearchInputs {
|
||||||
|
search: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SearchBar: React.FC<SearchBarProps> = ({
|
||||||
|
handler,
|
||||||
|
placeholder = 'Search',
|
||||||
|
}) => {
|
||||||
|
const { register, handleSubmit } = useForm({
|
||||||
|
defaultValues: {
|
||||||
|
search: '',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const onSubmit: SubmitHandler<SearchInputs> = (data) => {
|
||||||
|
handler(data);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="w-full flex">
|
||||||
|
<div className="text-gray-300">^</div>
|
||||||
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
|
<input
|
||||||
|
{...register('search')}
|
||||||
|
type="text"
|
||||||
|
placeholder={placeholder}
|
||||||
|
className="grow text-gray-700 border-none focus:outline-none text-xs"
|
||||||
|
/>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SearchBar;
|
@ -4,7 +4,7 @@ import { NavLink } from 'react-router-dom';
|
|||||||
const Sidebar = () => {
|
const Sidebar = () => {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col h-full p-4">
|
<div className="flex flex-col h-full p-4">
|
||||||
<div className="basis-1/2 flex flex-col justify-start gap-4">
|
<div className="grow">
|
||||||
<div>
|
<div>
|
||||||
<h3 className="text-black text-2xl">Snowball</h3>
|
<h3 className="text-black text-2xl">Snowball</h3>
|
||||||
</div>
|
</div>
|
||||||
@ -26,7 +26,7 @@ const Sidebar = () => {
|
|||||||
</NavLink>
|
</NavLink>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="basis-1/2 flex flex-col justify-end gap-4">
|
<div className="grow flex flex-col justify-end">
|
||||||
<div>Documentation</div>
|
<div>Documentation</div>
|
||||||
<div>Support</div>
|
<div>Support</div>
|
||||||
</div>
|
</div>
|
39
packages/frontend/src/pages/Projects.tsx
Normal file
39
packages/frontend/src/pages/Projects.tsx
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import SearchBar from '../components/SearchBar';
|
||||||
|
import Card from '../components/Card';
|
||||||
|
|
||||||
|
const Projects = () => {
|
||||||
|
return (
|
||||||
|
<div className="bg-white rounded-3xl h-full">
|
||||||
|
<div className="flex p-4">
|
||||||
|
<div className="grow">
|
||||||
|
<SearchBar handler={() => {}} />
|
||||||
|
</div>
|
||||||
|
<div className="text-gray-300">^</div>
|
||||||
|
<div className="text-gray-300">^</div>
|
||||||
|
<div className="text-gray-300">^</div>
|
||||||
|
</div>
|
||||||
|
<hr className="h-px bg-slate-200 border-0" />
|
||||||
|
<div className="flex p-4">
|
||||||
|
<div className="grow">
|
||||||
|
<h3 className="text-gray-750 text-2xl">Projects</h3>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{/* TODO: Create button component */}
|
||||||
|
<button className="bg-sky-600 text-white text-sm px-4 py-2 border rounded-full">
|
||||||
|
Create project
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="grid grid-cols-3 gap-5 p-5">
|
||||||
|
<Card />
|
||||||
|
<Card />
|
||||||
|
<Card />
|
||||||
|
<Card />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Projects;
|
@ -1,7 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
const Projects = () => {
|
|
||||||
return <div className="bg-white rounded-3xl h-full">Projects</div>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Projects;
|
|
@ -1,19 +1,19 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Outlet } from 'react-router-dom';
|
import { Outlet } from 'react-router-dom';
|
||||||
|
|
||||||
import Sidebar from '../../components/dashboard/Sidebar';
|
import Sidebar from '../components/Sidebar';
|
||||||
|
|
||||||
const Dashboard = () => {
|
const Home = () => {
|
||||||
return (
|
return (
|
||||||
<div className="grid grid-cols-5 h-screen bg-sky-100">
|
<div className="grid grid-cols-5 h-screen bg-sky-100">
|
||||||
<div className="h-screen">
|
<div className="h-full">
|
||||||
<Sidebar />
|
<Sidebar />
|
||||||
</div>
|
</div>
|
||||||
<div className="col-span-4 h-screen p-3">
|
<div className="col-span-4 h-full p-3">
|
||||||
<Outlet />
|
<Outlet />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Dashboard;
|
export default Home;
|
@ -1,19 +1,9 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import Projects from './Projects';
|
|
||||||
import Project from './Project';
|
|
||||||
import Settings from './Settings';
|
|
||||||
import CreateProject from './CreateProject';
|
import CreateProject from './CreateProject';
|
||||||
|
import Project from './Project';
|
||||||
|
|
||||||
export const dashboardRoutes = [
|
export const projectsRoutes = [
|
||||||
{
|
|
||||||
path: '/',
|
|
||||||
element: <Projects />,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'settings',
|
|
||||||
element: <Settings />,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: ':id',
|
path: ':id',
|
||||||
element: <Project />,
|
element: <Project />,
|
20
packages/frontend/src/pages/routes.tsx
Normal file
20
packages/frontend/src/pages/routes.tsx
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import Projects from './Projects';
|
||||||
|
import Settings from './Settings';
|
||||||
|
import { projectsRoutes } from './projects/routes';
|
||||||
|
|
||||||
|
export const homeRoutes = [
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
element: <Projects />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'settings',
|
||||||
|
element: <Settings />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'projects',
|
||||||
|
children: projectsRoutes,
|
||||||
|
},
|
||||||
|
];
|
@ -10125,6 +10125,11 @@ react-error-overlay@^6.0.11:
|
|||||||
resolved "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz"
|
resolved "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz"
|
||||||
integrity sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==
|
integrity sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==
|
||||||
|
|
||||||
|
react-hook-form@^7.49.0:
|
||||||
|
version "7.49.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.49.0.tgz#9a91edfba6b6983d4b443653a9b225a780a42b3e"
|
||||||
|
integrity sha512-gf4qyY4WiqK2hP/E45UUT6wt3Khl49pleEVcIzxhLBrD6m+GMWtLRk0vMrRv45D1ZH8PnpXFwRPv0Pewske2jw==
|
||||||
|
|
||||||
react-is@^16.13.1:
|
react-is@^16.13.1:
|
||||||
version "16.13.1"
|
version "16.13.1"
|
||||||
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
|
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
|
||||||
|
Loading…
Reference in New Issue
Block a user