Implement layout for creating new project with template (#6)

* Create layout for create project with template

* Handle create project with tempalte form

* Refactor pages folder according to routes

* Add navigation to create project with template page

---------

Co-authored-by: neeraj <neeraj.rtly@gmail.com>
This commit is contained in:
Nabarun Gogoi 2023-12-18 16:58:17 +05:30 committed by GitHub
parent 1bde6b3fd6
commit cc071dddcf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 199 additions and 33 deletions

View File

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { createBrowserRouter, RouterProvider } from 'react-router-dom'; import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import Home from './pages'; import Home from './pages/index';
import { homeRoutes } from './pages/routes'; import { homeRoutes } from './pages/routes';
const router = createBrowserRouter([ const router = createBrowserRouter([

View File

@ -0,0 +1,99 @@
import React from 'react';
import { useForm, Controller } from 'react-hook-form';
import Dropdown from './Dropdown';
const USER_OPTIONS = [
{ value: 'saugatyadav1', label: 'saugatyadav1' },
{ value: 'brad102', label: 'brad102' },
{ value: 'erin20', label: 'erin20' },
];
const CreateRepo = () => {
const { register, handleSubmit, control } = useForm({
defaultValues: {
framework: 'reactNative',
repoName: '',
isPrivate: false,
account: { value: 'saugatyadav1', label: 'saugatyadav1' },
},
});
return (
<form onSubmit={handleSubmit(() => {})}>
<div className="mb-2">
<h3>Create a repository</h3>
<p className="text-sm text-gray-400">
The project will be cloned into this repository
</p>
</div>
<div className="mb-2">
<h5>Framework</h5>
<div className="flex items-center gap-2">
<label className="inline-flex items-center w-1/2 border rounded-lg p-2">
<input
type="radio"
{...register('framework')}
value="reactNative"
className="h-5 w-5 text-indigo-600 rounded"
/>
<span className="ml-2">^React Native</span>
</label>
<label className="inline-flex items-center w-1/2 border rounded-lg p-2">
<input
type="radio"
{...register('framework')}
className="h-5 w-5 text-indigo-600 rounded"
value="expo"
/>
<span className="ml-2">^Expo</span>
</label>
</div>
</div>
<div className="mb-2">
<h5>Git account</h5>
<div>
<Controller
name="account"
control={control}
render={({ field: { onChange, value } }) => (
<Dropdown
onChange={onChange}
value={value}
options={USER_OPTIONS}
/>
)}
/>
</div>
</div>
<div className="mb-2">
<h5>Name the repo</h5>
<div>
<input
type="text"
className="border border-gray-300 rounded p-2 w-full focus:border-blue-300 focus:outline-none focus:shadow-outline-blue"
placeholder=""
{...register('repoName')}
/>
</div>
</div>
<div className="mb-2">
<label className="inline-flex items-center">
<input
type="checkbox"
className="h-5 w-5 text-indigo-600 rounded"
{...register('isPrivate')}
/>
<span className="ml-2">Make this repo private</span>
</label>
</div>
<div className="mb-2">
<button className="bg-blue-500 rounded-xl p-2" type="submit">
Deploy ^
</button>
</div>
</form>
);
};
export default CreateRepo;

View File

@ -4,7 +4,7 @@ import deploymentDetails from '../assets/deployments.json';
import DeployDetailsCard from './DeploymentDetailsCard'; import DeployDetailsCard from './DeploymentDetailsCard';
import Dropdown from './Dropdown'; import Dropdown from './Dropdown';
const statusOptions = [ const STATUS_OPTIONS = [
{ value: 'production', label: 'Production' }, { value: 'production', label: 'Production' },
{ value: 'preview', label: 'Preview' }, { value: 'preview', label: 'Preview' },
]; ];
@ -30,8 +30,8 @@ const Deployments = () => {
<div className="col-span-1"> <div className="col-span-1">
<Dropdown <Dropdown
placeholder="All status" placeholder="All status"
options={statusOptions} options={STATUS_OPTIONS}
handler={() => {}} onChange={() => {}}
/> />
</div> </div>
</div> </div>

View File

@ -11,19 +11,21 @@ interface Option {
} }
interface DropdownProps { interface DropdownProps {
placeholder: string;
options: Option[]; options: Option[];
handler: (arg: ReactDropdownOption) => void; onChange: (arg: ReactDropdownOption) => void;
placeholder?: string;
value?: Option;
} }
const Dropdown = ({ placeholder, options, handler }: DropdownProps) => { const Dropdown = ({ placeholder, options, onChange, value }: DropdownProps) => {
return ( return (
<ReactDropdown <ReactDropdown
options={options} options={options}
placeholder={placeholder} placeholder={placeholder}
className="h-full" className="h-full"
controlClassName="h-full" controlClassName="h-full"
onChange={handler} onChange={onChange}
value={value}
/> />
); );
}; };

View File

@ -1,5 +1,7 @@
import React from 'react'; import React from 'react';
import { Link } from 'react-router-dom';
interface TemplateDetails { interface TemplateDetails {
framework: string; framework: string;
icon: string; icon: string;
@ -10,9 +12,14 @@ interface TemplateCardProps {
const TemplateCard: React.FC<TemplateCardProps> = ({ framework }) => { const TemplateCard: React.FC<TemplateCardProps> = ({ framework }) => {
return ( return (
<div className="bg-gray-200 text-gray-500 text-xs border-gray-200 rounded-lg shadow p-4"> <div className="group bg-gray-200 text-gray-500 text-xs border-gray-200 rounded-lg shadow p-4 flex items-center justify-between">
{framework.icon} <div>
{framework.framework} {framework.icon}
{framework.framework}
</div>
<Link to={'/projects/create/template'}>
<button className="hidden group-hover:block">{'>'}</button>
</Link>
</div> </div>
); );
}; };

View File

@ -1,14 +1,8 @@
import React from 'react'; import React from 'react';
import { Link } from 'react-router-dom'; import { Outlet, useNavigate } from 'react-router-dom';
import templateDetails from '../../assets/templates.json';
import TemplateCard from '../../components/TemplateCard';
import RepositoryList from '../../components/RepositoryList';
import ConnectAccount from '../../components/ConnectAccount';
const IS_GIT_AUTH = true;
const CreateProject = () => { const CreateProject = () => {
const navigate = useNavigate();
return ( return (
<div className="bg-white rounded-3xl h-full p-4"> <div className="bg-white rounded-3xl h-full p-4">
<div className="flex p-2"> <div className="flex p-2">
@ -16,22 +10,18 @@ const CreateProject = () => {
<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 className="p-4">
<Link to="/"> <button
<button className="bg-slate-300 text-gray-700 text-sm px-4 py-2 border rounded-full"> className="bg-slate-300 text-gray-700 text-sm px-4 py-2 border rounded-full"
X onClick={() => {
</button> navigate(-1);
</Link> }}
>
X
</button>
</div> </div>
</div> </div>
<hr className="h-px bg-slate-200 border-0" /> <hr className="h-px bg-slate-200 border-0" />
<h5 className="mt-4 ml-4">Start with template</h5> <Outlet />
<div className="grid grid-cols-3 p-4 gap-4">
{templateDetails.map((framework, key) => {
return <TemplateCard framework={framework} key={key} />;
})}
</div>
<h5 className="mt-4 ml-4">Import a repository</h5>
{IS_GIT_AUTH ? <RepositoryList /> : <ConnectAccount />}
</div> </div>
); );
}; };

View File

@ -0,0 +1,26 @@
import React from 'react';
import CreateRepo from '../../../components/CreateRepo';
const CreateWithTemplate = () => {
return (
<div className="flex flex-col items-center">
<div className="flex justify-between w-5/6 my-4 bg-gray-200 rounded-xl p-6">
<div>^</div>
<div className="grow">React native</div>
<div>^snowball-tools/react-native-starter</div>
</div>
<div className="grid grid-cols-3 w-5/6 p-6">
<div>
<div>1 Create repository</div>
<div>2 Deploy</div>
</div>
<div className="col-span-2">
<CreateRepo />
</div>
</div>
</div>
);
};
export default CreateWithTemplate;

View File

@ -0,0 +1,25 @@
import React from 'react';
import templateDetails from '../../../assets/templates.json';
import TemplateCard from '../../../components/TemplateCard';
import RepositoryList from '../../../components/RepositoryList';
import ConnectAccount from '../../../components/ConnectAccount';
const IS_GIT_AUTH = true;
const NewProject = () => {
return (
<>
<h5 className="mt-4 ml-4">Start with template</h5>
<div className="grid grid-cols-3 p-4 gap-4">
{templateDetails.map((framework, key) => {
return <TemplateCard framework={framework} key={key} />;
})}
</div>
<h5 className="mt-4 ml-4">Import a repository</h5>
{IS_GIT_AUTH ? <RepositoryList /> : <ConnectAccount />}
</>
);
};
export default NewProject;

View File

@ -0,0 +1,15 @@
import React from 'react';
import NewProject from './index';
import CreateWithTemplate from './Template';
export const createProjectRoutes = [
{
index: true,
element: <NewProject />,
},
{
path: 'template',
element: <CreateWithTemplate />,
},
];

View File

@ -2,6 +2,7 @@ import React from 'react';
import CreateProject from './Create'; import CreateProject from './Create';
import Project from './Project'; import Project from './Project';
import { createProjectRoutes } from './create/routes';
export const projectsRoutes = [ export const projectsRoutes = [
{ {
@ -11,5 +12,6 @@ export const projectsRoutes = [
{ {
path: 'create', path: 'create',
element: <CreateProject />, element: <CreateProject />,
children: createProjectRoutes,
}, },
]; ];

View File

@ -6,7 +6,7 @@ import { projectsRoutes } from './projects/routes';
export const homeRoutes = [ export const homeRoutes = [
{ {
path: '/', index: true,
element: <Projects />, element: <Projects />,
}, },
{ {