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:
Nabarun Gogoi 2023-12-14 16:27:53 +05:30 committed by GitHub
parent bb723ee58a
commit 348ff92fa9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 137 additions and 10 deletions

View File

@ -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"
}, },

View File

@ -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",

View File

@ -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>

View 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;

View File

@ -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 (

View File

@ -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;

View File

@ -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"