Skip to content

Commit 71c4f7f

Browse files
authored
Merge pull request #16 from oasisprotocol/mz/createViews
Setup creation flow
2 parents edbef88 + c4c72bc commit 71c4f7f

17 files changed

+452
-80
lines changed

src/components/Layout/Header.tsx

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { useState, type FC } from 'react';
2-
import { Link, NavLink } from 'react-router-dom';
2+
import { Link, NavLink, useNavigate } from 'react-router-dom';
3+
import { useCreate } from '../../pages/CreateApp/useCreate';
34
import Logotype from './logo.svg';
45
import { RainbowKitConnectButton } from '../RainbowKitConnectButton';
56
import { Menu, Plus } from 'lucide-react';
@@ -20,6 +21,15 @@ export const Header: FC = () => {
2021
const isMobile = useIsMobile();
2122
const { isConnected } = useAccount();
2223
const [isOpen, setIsOpen] = useState(false);
24+
const navigate = useNavigate();
25+
const createContext = useCreate();
26+
27+
const handleCreateClick = () => {
28+
if (createContext) {
29+
createContext.resetStep();
30+
}
31+
navigate('/create');
32+
};
2333

2434
return (
2535
<div className="w-full flex justify-between items-center">
@@ -30,11 +40,9 @@ export const Header: FC = () => {
3040
<div className="hidden md:flex">
3141
<div className="flex items-center gap-4">
3242
{isConnected && (
33-
<Button asChild>
34-
<Link to="/create">
35-
Create
36-
<Plus className="ml-2 h-4 w-4" />
37-
</Link>
43+
<Button onClick={handleCreateClick}>
44+
Create
45+
<Plus className="ml-2 h-4 w-4" />
3846
</Button>
3947
)}
4048
<RainbowKitConnectButton />

src/main.tsx

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { StrictMode } from 'react';
22
import { createRoot } from 'react-dom/client';
33
import { BrowserRouter, Route, Routes } from 'react-router-dom';
44
import { WagmiProvider } from 'wagmi';
5+
import { CreateContextProvider } from './pages/CreateApp/CreateContextProvider';
56
import { Landing } from './pages/Landing';
67
import { Dashboard } from './pages/Dashboard';
78
import { MyApps } from './pages/Dashboard/MyApps';
@@ -45,20 +46,22 @@ createRoot(document.getElementById('root')!).render(
4546
)}
4647
>
4748
<BrowserRouter>
48-
<Routes>
49-
<Route path="/" element={<Landing />} />
50-
<Route path="/dashboard" element={<MainLayout />}>
51-
<Route index element={<Dashboard />} />
52-
<Route path="apps" element={<MyApps />} />
53-
<Route path="apps/:id" element={<AppDetails />} />
54-
<Route path="machines" element={<Machines />} />
55-
<Route path="machines/:id" element={<MachinesDetails />} />
56-
</Route>
57-
<Route path="/create" element={<Create />} />
58-
<Route path="/explore" element={<MainLayout />}>
59-
<Route index element={<Explore />} />
60-
</Route>
61-
</Routes>
49+
<CreateContextProvider>
50+
<Routes>
51+
<Route path="/" element={<Landing />} />
52+
<Route path="/dashboard" element={<MainLayout />}>
53+
<Route index element={<Dashboard />} />
54+
<Route path="apps" element={<MyApps />} />
55+
<Route path="apps/:id" element={<AppDetails />} />
56+
<Route path="machines" element={<Machines />} />
57+
<Route path="machines/:id" element={<MachinesDetails />} />
58+
</Route>
59+
<Route path="/create" element={<Create />}></Route>
60+
<Route path="/explore" element={<MainLayout />}>
61+
<Route index element={<Explore />} />
62+
</Route>
63+
</Routes>
64+
</CreateContextProvider>
6265
</BrowserRouter>
6366
</RainbowKitProvider>
6467
</QueryClientProvider>

src/pages/CreateApp/AgentStep.tsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { type FC } from 'react';
2+
import { CreateLayout } from './CreateLayout';
3+
import { CreateFormHeader } from './CreateFormHeader';
4+
import { CreateFormNavigation } from './CreateFormNavigation';
5+
6+
type AgentStepProps = {
7+
handleNext: () => void;
8+
handleBack: () => void;
9+
};
10+
11+
export const AgentStep: FC<AgentStepProps> = ({ handleNext, handleBack }) => {
12+
return (
13+
<CreateLayout currentStep={2}>
14+
<div className="max-w-md mx-auto px-8 py-12 flex flex-col gap-8 items-center">
15+
<CreateFormHeader
16+
title="Agent Specific Stuff"
17+
description="At varius sit sit netus at integer vitae posuere id. Nulla imperdiet vestibulum amet ultrices egestas. Bibendum sed integer ac eget."
18+
/>
19+
<CreateFormNavigation handleNext={handleNext} handleBack={handleBack} />
20+
</div>
21+
</CreateLayout>
22+
);
23+
};
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { type FC } from 'react';
2+
import { Layout } from '@oasisprotocol/ui-library/src/components/ui/layout';
3+
import { Header } from '../../components/Layout/Header';
4+
import { Footer } from '../../components/Layout/Footer';
5+
import Bootstrap from './images/bootstrap.png';
6+
7+
export const BootstrapStep: FC = () => {
8+
return (
9+
<Layout headerContent={<Header />} footerContent={<Footer />}>
10+
<div className="w-full px-8 py-12 flex flex-col items-center justify-center">
11+
<img
12+
src={Bootstrap}
13+
alt="Bootstrap"
14+
className="w-[250px] h-auto mb-8"
15+
/>
16+
<div className="mb-8">
17+
<h1 className="text-2xl font-white font-bold mb-2 text-center">
18+
ROFL App Registration...
19+
</h1>
20+
<p className="text-muted-foreground text-md max-w-md text-center">
21+
At varius sit sit netus at integer vitae posuere id. Nulla imperdiet
22+
vestibulum amet ultrices egestas. Bibendum sed integer ac eget.
23+
</p>
24+
</div>
25+
</div>
26+
</Layout>
27+
);
28+
};

src/pages/CreateApp/BuildStep.tsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { type FC } from 'react';
2+
import { CreateLayout } from './CreateLayout';
3+
import { CreateFormHeader } from './CreateFormHeader';
4+
import { CreateFormNavigation } from './CreateFormNavigation';
5+
6+
type AgentStepProps = {
7+
handleNext: () => void;
8+
handleBack: () => void;
9+
};
10+
11+
export const BuildStep: FC<AgentStepProps> = ({ handleNext, handleBack }) => {
12+
return (
13+
<CreateLayout currentStep={3}>
14+
<div className="max-w-md mx-auto px-8 py-12 flex flex-col gap-8 items-center">
15+
<CreateFormHeader
16+
title="Build and Deploy"
17+
description="At varius sit sit netus at integer vitae posuere id. Nulla imperdiet vestibulum amet ultrices egestas. Bibendum sed integer ac eget."
18+
/>
19+
<CreateFormNavigation handleNext={handleNext} handleBack={handleBack} />
20+
</div>
21+
</CreateLayout>
22+
);
23+
};
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { createContext } from 'react';
2+
3+
type CreateContextType = {
4+
currentStep: number;
5+
setCurrentStep: (step: number) => void;
6+
resetStep: () => void;
7+
};
8+
9+
export const CreateContext = createContext<CreateContextType | undefined>(
10+
undefined
11+
);
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import type { ReactNode } from 'react';
2+
import { useState } from 'react';
3+
import { CreateContext } from './CreateContext';
4+
5+
export const CreateContextProvider = ({
6+
children,
7+
}: {
8+
children: ReactNode;
9+
}) => {
10+
const [currentStep, setCurrentStep] = useState(0);
11+
12+
const resetStep = () => {
13+
setCurrentStep(0);
14+
};
15+
16+
return (
17+
<CreateContext.Provider value={{ currentStep, setCurrentStep, resetStep }}>
18+
{children}
19+
</CreateContext.Provider>
20+
);
21+
};
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { type FC } from 'react';
2+
3+
type CreateFormHeaderProps = {
4+
title: string;
5+
description: string;
6+
};
7+
8+
export const CreateFormHeader: FC<CreateFormHeaderProps> = ({
9+
title,
10+
description,
11+
}) => {
12+
return (
13+
<div className="mb-8">
14+
<h1 className="text-2xl font-white font-bold mb-2">{title}</h1>
15+
<p className="text-muted-foreground text-md max-w-md">{description}</p>
16+
</div>
17+
);
18+
};
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { type FC } from 'react';
2+
import { Button } from '@oasisprotocol/ui-library/src/components/ui/button';
3+
4+
type CreateFormNavigationProps = {
5+
handleNext: () => void;
6+
handleBack?: () => void;
7+
};
8+
9+
export const CreateFormNavigation: FC<CreateFormNavigationProps> = ({
10+
handleNext,
11+
handleBack,
12+
}) => {
13+
return (
14+
<div className="flex gap-4 w-full">
15+
{handleBack && (
16+
<Button className="flex-1" variant="secondary" onClick={handleBack}>
17+
Back
18+
</Button>
19+
)}
20+
<Button className="flex-1" onClick={handleNext}>
21+
Continue
22+
</Button>
23+
</div>
24+
);
25+
};
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import type { FC, ReactNode } from 'react';
2+
import { Header } from '../../components/Layout/Header';
3+
import { Footer } from '../../components/Layout/Footer';
4+
import {
5+
Sidebar,
6+
SidebarContent,
7+
SidebarMenu,
8+
SidebarGroup,
9+
} from '@oasisprotocol/ui-library/src/components/ui/sidebar';
10+
import { Layout } from '@oasisprotocol/ui-library/src/components/ui/layout';
11+
import { SidebarItemLabel } from './SidebarItemLabel';
12+
13+
type CreateLayoutProps = {
14+
children: ReactNode;
15+
currentStep?: number;
16+
};
17+
18+
export const CreateLayout: FC<CreateLayoutProps> = ({
19+
children,
20+
currentStep = 1,
21+
}) => {
22+
// Steps are 0-indexed in the index.tsx file, but we're starting from 1 here
23+
// because the first step (Template) has its own layout
24+
const sidebarItems = [
25+
{ label: 'Metadata Input', active: currentStep === 1 },
26+
{ label: 'Agent Specific Stuff', active: currentStep === 2 },
27+
{ label: 'Build and Deploy', active: currentStep === 3 },
28+
{ label: 'Payment', active: currentStep === 4 },
29+
];
30+
31+
return (
32+
<Layout
33+
headerContent={<Header />}
34+
footerContent={<Footer />}
35+
sidebar={
36+
<Sidebar collapsible="icon" className="border-r !static !h-full p-6">
37+
<SidebarContent className="bg-sidebar-background">
38+
<SidebarGroup>
39+
<SidebarMenu>
40+
<span className="text-xl font-semibold text-white">
41+
ROFL App Creation
42+
</span>
43+
<span className="text-xs text-muted-foreground pb-8">
44+
with TEMPLATE_NAME
45+
</span>
46+
{sidebarItems.map((item, index) => (
47+
<SidebarItemLabel
48+
active={item.active}
49+
key={item.label}
50+
index={index}
51+
label={item.label}
52+
/>
53+
))}
54+
</SidebarMenu>
55+
</SidebarGroup>
56+
</SidebarContent>
57+
</Sidebar>
58+
}
59+
>
60+
<div className="flex-1 p-5 h-5/6">{children}</div>
61+
</Layout>
62+
);
63+
};

0 commit comments

Comments
 (0)