Implement tabs functionality in project details page (#2)
* Add navigation for project page * Use tab component for switching panels * Get project details only on id changes --------- Co-authored-by: neeraj <neeraj.rtly@gmail.com>
This commit is contained in:
parent
bb723ee58a
commit
348ff92fa9
@ -16,6 +16,7 @@
|
|||||||
"react-hook-form": "^7.49.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",
|
||||||
|
"react-tabs": "^6.0.2",
|
||||||
"typescript": "^4.9.5",
|
"typescript": "^4.9.5",
|
||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4"
|
||||||
},
|
},
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
|
"id": 1,
|
||||||
"icon": "^",
|
"icon": "^",
|
||||||
"title": "iglotools",
|
"title": "iglotools",
|
||||||
"domain": "iglotools.com",
|
"domain": "iglotools.com",
|
||||||
@ -10,9 +11,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"id": 2,
|
||||||
"icon": "^",
|
"icon": "^",
|
||||||
"title": "iglotools",
|
"title": "snowball-starter-kit",
|
||||||
"domain": "iglotools.com",
|
"domain": "snowball-starter-kit.com",
|
||||||
"latestCommit": {
|
"latestCommit": {
|
||||||
"message": "404 added",
|
"message": "404 added",
|
||||||
"time": "2023-12-11T04:20:00",
|
"time": "2023-12-11T04:20:00",
|
||||||
@ -20,9 +22,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"id": 3,
|
||||||
"icon": "^",
|
"icon": "^",
|
||||||
"title": "iglotools",
|
"title": "passkeys-demo",
|
||||||
"domain": "iglotools.com",
|
"domain": "passkeys-demo.com",
|
||||||
"latestCommit": {
|
"latestCommit": {
|
||||||
"message": "Design system integrated",
|
"message": "Design system integrated",
|
||||||
"time": "2023-12-11T04:20:00",
|
"time": "2023-12-11T04:20:00",
|
||||||
@ -30,6 +33,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"id": 4,
|
||||||
"icon": "^",
|
"icon": "^",
|
||||||
"title": "watcher-tool",
|
"title": "watcher-tool",
|
||||||
"domain": "azimuth-watcher.com",
|
"domain": "azimuth-watcher.com",
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
interface projectDetails {
|
interface projectDetails {
|
||||||
icon: string;
|
icon: string;
|
||||||
title: string;
|
title: string;
|
||||||
domain: string;
|
domain: string;
|
||||||
|
id: number;
|
||||||
latestCommit: {
|
latestCommit: {
|
||||||
[key: string]: string;
|
[key: string]: string;
|
||||||
};
|
};
|
||||||
@ -20,7 +22,9 @@ const ProjectCard: React.FC<ProjectCardProps> = ({ project }) => {
|
|||||||
<div className="flex gap-2 p-2 items-center">
|
<div className="flex gap-2 p-2 items-center">
|
||||||
<div>{project.icon}</div>
|
<div>{project.icon}</div>
|
||||||
<div className="grow">
|
<div className="grow">
|
||||||
<p className="text-sm text-gray-750">{project.title}</p>
|
<Link to={`projects/${project.id}`} className="text-sm text-gray-700">
|
||||||
|
{project.title}
|
||||||
|
</Link>
|
||||||
<p className="text-sm text-gray-400">{project.domain}</p>
|
<p className="text-sm text-gray-400">{project.domain}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>...</div>
|
<div>...</div>
|
||||||
|
80
packages/frontend/src/components/Tab.tsx
Normal file
80
packages/frontend/src/components/Tab.tsx
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
|
||||||
|
|
||||||
|
const Overview = () => (
|
||||||
|
<div>
|
||||||
|
Content of overview tab
|
||||||
|
<p className="block">
|
||||||
|
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
const Deployments = () => (
|
||||||
|
<div>
|
||||||
|
Content of deployments tab
|
||||||
|
<p className="block">
|
||||||
|
Contrary to popular belief, Lorem Ipsum is not simply random text.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
const Database = () => (
|
||||||
|
<div>
|
||||||
|
Content of database tab
|
||||||
|
<p className="block">
|
||||||
|
It is a long established fact that a reader will be distracted by the
|
||||||
|
readable content of a page when looking at its layout.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
const Integrations = () => (
|
||||||
|
<div>
|
||||||
|
Content of integrations tab
|
||||||
|
<p className="block">
|
||||||
|
There are many variations of passages of Lorem Ipsum available.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
const Settings = () => (
|
||||||
|
<div>
|
||||||
|
Content of settings tab
|
||||||
|
<p className="block">
|
||||||
|
It uses a dictionary of over 200 Latin words, combined with a handful of
|
||||||
|
model sentence.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
const ProjectTab = () => {
|
||||||
|
return (
|
||||||
|
<Tabs
|
||||||
|
selectedTabClassName={
|
||||||
|
'border-b-2 border-gray-900 text-gray-900 focus:outline-none'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<TabList className="flex border-b border-gray-300 text-gray-400">
|
||||||
|
<Tab className={'p-2 cursor-pointer'}>Overview</Tab>
|
||||||
|
<Tab className={'p-2 cursor-pointer'}>Deployments</Tab>
|
||||||
|
<Tab className={'p-2 cursor-pointer'}>Database</Tab>
|
||||||
|
<Tab className={'p-2 cursor-pointer'}>Integrations</Tab>
|
||||||
|
<Tab className={'p-2 cursor-pointer'}>Settings</Tab>
|
||||||
|
</TabList>
|
||||||
|
<TabPanel>
|
||||||
|
<Overview />
|
||||||
|
</TabPanel>
|
||||||
|
<TabPanel>
|
||||||
|
<Deployments />
|
||||||
|
</TabPanel>
|
||||||
|
<TabPanel>
|
||||||
|
<Database />
|
||||||
|
</TabPanel>
|
||||||
|
<TabPanel>
|
||||||
|
<Integrations />
|
||||||
|
</TabPanel>
|
||||||
|
<TabPanel>
|
||||||
|
<Settings />
|
||||||
|
</TabPanel>
|
||||||
|
</Tabs>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ProjectTab;
|
@ -6,7 +6,7 @@ import TemplateCard from '../../components/TemplateCard';
|
|||||||
import RepositoryList from '../../components/RepositoryList';
|
import RepositoryList from '../../components/RepositoryList';
|
||||||
import ConnectAccount from '../../components/ConnectAccount';
|
import ConnectAccount from '../../components/ConnectAccount';
|
||||||
|
|
||||||
const isGitAuth = false;
|
const isGitAuth = true;
|
||||||
|
|
||||||
const CreateProject = () => {
|
const CreateProject = () => {
|
||||||
return (
|
return (
|
||||||
|
@ -1,10 +1,35 @@
|
|||||||
import React from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
|
|
||||||
|
import HorizontalLine from '../../components/HorizontalLine';
|
||||||
|
import projects from '../../assets/projects.json';
|
||||||
|
import ProjectTab from '../../components/Tab';
|
||||||
|
|
||||||
|
const getProject = (id: number) => {
|
||||||
|
return projects.find((project) => {
|
||||||
|
return project.id === id;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const Project = () => {
|
const Project = () => {
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const project = useMemo(() => getProject(Number(id)), [id]);
|
||||||
|
|
||||||
return <div className="bg-white rounded-3xl h-full">Project page: {id}</div>;
|
return (
|
||||||
|
<div className="bg-white rounded-3xl h-full">
|
||||||
|
<div className="flex p-4 gap-4">
|
||||||
|
<button onClick={() => navigate(-1)}>{'<'}</button>
|
||||||
|
<h3 className="grow">{project?.title} </h3>
|
||||||
|
<button>Open Repo</button>
|
||||||
|
<button>Go to app</button>
|
||||||
|
</div>
|
||||||
|
<HorizontalLine />
|
||||||
|
<div className="p-4">
|
||||||
|
<ProjectTab />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Project;
|
export default Project;
|
||||||
|
15
yarn.lock
15
yarn.lock
@ -4048,6 +4048,11 @@ clone@^1.0.2:
|
|||||||
resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
|
resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
|
||||||
integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==
|
integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==
|
||||||
|
|
||||||
|
clsx@^2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.0.0.tgz#12658f3fd98fafe62075595a5c30e43d18f3d00b"
|
||||||
|
integrity sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==
|
||||||
|
|
||||||
cmd-shim@6.0.1:
|
cmd-shim@6.0.1:
|
||||||
version "6.0.1"
|
version "6.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-6.0.1.tgz#a65878080548e1dca760b3aea1e21ed05194da9d"
|
resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-6.0.1.tgz#a65878080548e1dca760b3aea1e21ed05194da9d"
|
||||||
@ -10012,7 +10017,7 @@ promzard@^1.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
read "^2.0.0"
|
read "^2.0.0"
|
||||||
|
|
||||||
prop-types@^15.8.1:
|
prop-types@^15.5.0, prop-types@^15.8.1:
|
||||||
version "15.8.1"
|
version "15.8.1"
|
||||||
resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz"
|
resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz"
|
||||||
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
|
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
|
||||||
@ -10255,6 +10260,14 @@ react-scripts@5.0.1:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents "^2.3.2"
|
fsevents "^2.3.2"
|
||||||
|
|
||||||
|
react-tabs@^6.0.2:
|
||||||
|
version "6.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-tabs/-/react-tabs-6.0.2.tgz#bc1065c3828561fee285a8fd045f22e0fcdde1eb"
|
||||||
|
integrity sha512-aQXTKolnM28k3KguGDBSAbJvcowOQr23A+CUJdzJtOSDOtTwzEaJA+1U4KwhNL9+Obe+jFS7geuvA7ICQPXOnQ==
|
||||||
|
dependencies:
|
||||||
|
clsx "^2.0.0"
|
||||||
|
prop-types "^15.5.0"
|
||||||
|
|
||||||
react@^18.2.0:
|
react@^18.2.0:
|
||||||
version "18.2.0"
|
version "18.2.0"
|
||||||
resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz"
|
resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz"
|
||||||
|
Loading…
Reference in New Issue
Block a user