Skip to content

Commit

Permalink
feat(web): Re:Earth Beta routing and basic component structure (#444)
Browse files Browse the repository at this point in the history
  • Loading branch information
KaWaite committed May 26, 2023
1 parent a1391d1 commit 75b7bb9
Show file tree
Hide file tree
Showing 8 changed files with 211 additions and 32 deletions.
80 changes: 48 additions & 32 deletions web/src/app.tsx
@@ -1,5 +1,5 @@
import React, { Suspense } from "react";
import { BrowserRouter as Router, useRoutes, Navigate, useParams } from "react-router-dom";
import { BrowserRouter as Router, Navigate, useParams, Routes, Route } from "react-router-dom";

import Loading from "@reearth/classic/components/atoms/Loading";
import NotificationBanner from "@reearth/classic/components/organisms/Notification";
Expand All @@ -24,39 +24,15 @@ import { Provider as Auth0Provider } from "./services/auth";
import { Provider as GqlProvider } from "./services/gql";
import { Provider as ThemeProvider, styled } from "./services/theme";

const BetaEditor = React.lazy(() => import("@reearth/beta/pages/Editor"));

const EarthEditor = React.lazy(() => import("@reearth/classic/components/pages/EarthEditor"));
const Dashboard = React.lazy(() => import("@reearth/classic/components/pages/Dashboard"));
const GraphQLPlayground = React.lazy(
() => import("@reearth/classic/components/pages/GraphQLPlayground"),
);
const PluginEditor = React.lazy(() => import("./classic/components/pages/PluginEditor"));

function AppRoutes() {
return useRoutes([
{ path: "/", element: <RootPage /> },
{ path: "/login", element: <LoginPage /> },
{ path: "/signup", element: <SignupPage /> },
{ path: "/password-reset", element: <PasswordResetPage /> },
{ path: "/dashboard/:workspaceId", element: <Dashboard /> },
{ path: "/edit/:sceneId", element: <EarthEditor /> },
{ path: "/edit/:sceneId/preview", element: <Preview /> },
{ path: "/settings", element: <Navigate to="/settings/account" /> },
{ path: "/settings/account", element: <AccountSettings /> },
{ path: "/settings/workspaces", element: <WorkspaceList /> },
{ path: "/settings/workspaces/:workspaceId", element: <WorkspaceSettings /> },
{ path: "/settings/workspaces/:workspaceId/projects", element: <SettingsProjectList /> },
{ path: "/settings/workspaces/:workspaceId/asset", element: <AssetSettings /> },
{ path: "/settings/projects/:projectId", element: <ProjectSettings /> },
{ path: "/settings/projects/:projectId/public", element: <PublicSettings /> },
{ path: "/settings/projects/:projectId/dataset", element: <DatasetSettings /> },
{ path: "/settings/projects/:projectId/plugins", element: <PluginSettings /> },
{ path: "/plugin-editor", element: <PluginEditor /> },
{ path: "/graphql", element: import.meta.env.DEV && <GraphQLPlayground /> },
...redirects,
{ path: "*", element: <NotFound /> },
]);
}

export default function App() {
return (
<Auth0Provider>
Expand All @@ -66,7 +42,50 @@ export default function App() {
<Suspense fallback={<Loading />}>
<NotificationBanner />
<StyledRouter>
<AppRoutes />
<Routes>
<Route path="/" element={<RootPage />} />
<Route path="/login" element={<LoginPage />} />
<Route path="/signup" element={<SignupPage />} />
<Route path="/password-reset" element={<PasswordResetPage />} />
<Route path="/dashboard/:workspaceId" element={<Dashboard />} />
{/* classic routes - start */}
<Route path="/edit/:sceneId" element={<EarthEditor />} />
<Route path="/edit/:sceneId/preview" element={<Preview />} />
<Route path="/plugin-editor" element={<PluginEditor />} />
{/* classic routes - end */}
<Route path="/scene/:sceneId" element={<BetaEditor />}>
<Route path="story" element={<BetaEditor />} />
<Route path="widgets" element={<BetaEditor />} />
<Route path="publish" element={<BetaEditor />} />
</Route>
<Route path="settings" element={<Navigate to="/settings/account" />} />
<Route path="/settings/account" element={<AccountSettings />} />
<Route path="/settings/workspaces" element={<WorkspaceList />} />
<Route path="/settings/workspaces/:workspaceId" element={<WorkspaceSettings />} />
<Route
path="/settings/workspaces/:workspaceId/projects"
element={<SettingsProjectList />}
/>
<Route
path="/settings/workspaces/:workspaceId/asset"
element={<AssetSettings />}
/>
<Route path="/settings/projects/:projectId" element={<ProjectSettings />} />
<Route path="/settings/projects/:projectId/public" element={<PublicSettings />} />
<Route
path="/settings/projects/:projectId/dataset"
element={<DatasetSettings />}
/>
<Route
path="/settings/projects/:projectId/plugins"
element={<PluginSettings />}
/>
<Route path="/graphql" element={<GraphQLPlayground />} />
{...redirects.map(([from, to]) => (
<Route key={from} path={from} element={<Redirect to={to} />} />
))}
<Route path="*" element={<NotFound />} />
</Routes>
</StyledRouter>
</Suspense>
</I18nProvider>
Expand All @@ -89,10 +108,7 @@ const redirects = [
["/settings/project/:projectId/public", "/settings/projects/:projectId/public"],
["/settings/project/:projectId/dataset", "/settings/projects/:projectId/dataset"],
["/settings/project/:projectId/plugins", "/settings/projects/:projectId/plugins"],
].map(([from, to]) => ({
path: from,
element: <Redirect to={to} />,
}));
];

function Redirect({ to }: { to: string }) {
const { teamId, projectId } = useParams();
Expand Down
12 changes: 12 additions & 0 deletions web/src/beta/features/LeftPanel/index.tsx
@@ -0,0 +1,12 @@
import { styled } from "@reearth/services/theme";

const LeftPanel: React.FC = () => {
return <Wrapper>LeftPanel</Wrapper>;
};

export default LeftPanel;

const Wrapper = styled.div`
background: #232226;
width: 235px;
`;
54 changes: 54 additions & 0 deletions web/src/beta/features/Navbar/index.tsx
@@ -0,0 +1,54 @@
import { useEditorNavigation, Tab } from "@reearth/beta/hooks";
import { styled } from "@reearth/services/theme";

export type { Tab };

type Props = {
sceneId?: string;
currentTab?: Tab;
};

const Navbar: React.FC<Props> = ({ sceneId, currentTab }) => {
const handleEditorNavigation = useEditorNavigation({ sceneId });

return (
<Wrapper>
<p>Navbar</p>
<div>
<p>current path: {location.pathname}</p>
<p> current tab: {currentTab}</p>
</div>
<div>
<button
onClick={() => handleEditorNavigation("scene")}
style={{ background: "white", marginRight: "3px" }}>
Scene
</button>
<button
onClick={() => handleEditorNavigation("story")}
style={{ background: "white", marginRight: "3px" }}>
Storytelling
</button>
<button
onClick={() => handleEditorNavigation("widgets")}
style={{ background: "white", marginRight: "3px" }}>
Widgets
</button>
<button
onClick={() => handleEditorNavigation("publish")}
style={{ background: "white", marginRight: "3px" }}>
Publish
</button>
</div>
</Wrapper>
);
};

export default Navbar;

const Wrapper = styled.div`
display: flex;
justify-content: space-between;
height: 53px;
background: #171618;
`;
12 changes: 12 additions & 0 deletions web/src/beta/features/RightPanel/index.tsx
@@ -0,0 +1,12 @@
import { styled } from "@reearth/services/theme";

const RightPanel: React.FC = () => {
return <Wrapper>RightPanel</Wrapper>;
};

export default RightPanel;

const Wrapper = styled.div`
background: #232226;
width: 235px;
`;
12 changes: 12 additions & 0 deletions web/src/beta/features/Visualizer/index.tsx
@@ -0,0 +1,12 @@
import { styled } from "@reearth/services/theme";

const Visualizer: React.FC = () => {
return <Wrapper>Visualizer</Wrapper>;
};

export default Visualizer;

const Wrapper = styled.div`
background: #3f3d45;
flex: 1;
`;
2 changes: 2 additions & 0 deletions web/src/beta/hooks/index.ts
@@ -0,0 +1,2 @@
export { useEditorNavigation } from "./navigationHooks";
export type { Tab } from "./navigationHooks";
15 changes: 15 additions & 0 deletions web/src/beta/hooks/navigationHooks.ts
@@ -0,0 +1,15 @@
import { useCallback } from "react";
import { useNavigate } from "react-router-dom";

export type Tab = "scene" | "story" | "widgets" | "publish";

export const useEditorNavigation = ({ sceneId }: { sceneId?: string }) => {
const navigate = useNavigate();

return useCallback(
(tab: Tab) => {
navigate(tab !== "scene" ? `/scene/${sceneId}/${tab}` : "");
},
[sceneId, navigate],
);
};
56 changes: 56 additions & 0 deletions web/src/beta/pages/Editor/index.tsx
@@ -0,0 +1,56 @@
import { useEffect, useState } from "react";
import { useLocation, useParams } from "react-router-dom";

import LeftPanel from "@reearth/beta/features/LeftPanel";
import Navbar, { Tab } from "@reearth/beta/features/Navbar";
import RightPanel from "@reearth/beta/features/RightPanel";
import Visualizer from "@reearth/beta/features/Visualizer";
import { styled } from "@reearth/services/theme";

type Props = {};

const tabs = ["scene", "story", "widgets", "publish"];

const Editor: React.FC<Props> = () => {
const [currentTab, setTab] = useState<Tab | undefined>();
const location = useLocation();
const { sceneId } = useParams();

useEffect(() => {
const splitPathname = location.pathname.split("/");
const tab =
splitPathname[
splitPathname.length === 4 ? splitPathname.length - 1 : splitPathname.length - 2
];

if (!tabs.includes(tab)) {
setTab("scene");
} else {
setTab(tab as Tab);
}
}, [location.pathname]);

return (
<Wrapper>
<Navbar sceneId={sceneId} currentTab={currentTab} />
<MainSection>
<LeftPanel />
<Visualizer />
<RightPanel />
</MainSection>
</Wrapper>
);
};

export default Editor;

const Wrapper = styled.div`
display: flex;
flex-direction: column;
height: 100%;
`;

const MainSection = styled.div`
display: flex;
flex: 1;
`;

0 comments on commit 75b7bb9

Please sign in to comment.