feat(auth): add register view + action (wip)
+ 188
- 335
@@ -1,5 +1,5 @@
 {
-  "_generatedAtUnix": 1662913620980,
+  "_generatedAtUnix": 1663228194515,
   "_hashAlgorithm": "sha1",
   "_version": 2,
   "islands": {

...
@@ -17,21 +17,17 @@
     }
   },
   "views": {
-    "DocHomeView": {
-      "hash": "82b1841cde408e5bb5f85b457d58185f46a27263",
-      "pathSource": "./app/views/DocHomeView.tsx"
-    },
-    "DocPageView": {
-      "hash": "a4bc809908735c5a6aff81137fdb31c4d8d7da86",
-      "pathSource": "./app/views/DocPageView.tsx"
-    },
     "HomeView": {
-      "hash": "220c689add1c039287faae6e7d2b678c13a8d0ba",
+      "hash": "68b106be682a83650061c345bd5d7ac084fd9768",
       "pathSource": "./app/views/HomeView.tsx"
     },
     "InternalErrorView": {
       "hash": "389861a6e7f9ff12026ddf5e91bdf4f06646116e",
       "pathSource": "./app/views/InternalErrorView.tsx"
+    },
+    "RegisterView": {
+      "hash": "b56f4d1bde44d5f2ecea87c3a91467032b5cc1de",
+      "pathSource": "./app/views/auth/RegisterView.tsx"
     }
   }
 }

new file
app/components/PageWrapper.tsx
@@ -0,0 +1,15 @@
+import styled from "styled-components";
+
+export const PageWrapper = styled.div`
+  display: flex;
+  flex-flow: column nowrap;
+  justify-content: center;
+  align-items: center;
+
+  max-width: 1176px;
+  width: 100%;
+
+  margin: 0 auto;
+  padding: 24px 16px 64px 16px;
+  gap: 24px;
+`;

app/components/index.ts
@@ -6,4 +6,5 @@ export { MarkdownToJsx } from "./MarkdownToJsx";
 export { MenuItem } from "./MenuItem";
 export { MenuDivider } from "./MenuDivider";
 export { PageHeader } from "./PageHeader";
+export { PageWrapper } from "./PageWrapper";
 export { TextEllipsis } from "./TextEllipsis.styled";

app/controllers/HomeController.ts
@@ -1,27 +1,9 @@
 // 1st-party
 import { ReqHandler } from "@ethicdevs/react-monolith";
-// app
-import { makeAuthService } from "../services/auth";
 // app views
 import HomeView, { HomeViewProps } from "../views/HomeView";
 
 export const getHomeView: ReqHandler = async (request, reply) => {
-  const authService = makeAuthService({ request });
   const reqHandler = reply.makeRequestHandler(request, reply);
-
-  const foo = authService.isExistingUsername("test");
-  const user = authService.findUserByUid((request.params as any).uid);
-
-  const never = await authService.validateUserEmailAddress(
-    "user-uid",
-    "email@address.tld"
-  );
-
-  // TODO: Create a User model in db where to store user data.
-  user; // so typescript do not complains about unused variable.
-  never;
-
-  return reqHandler<HomeViewProps>(HomeView.name, {
-    foo,
-  });
+  return reqHandler<HomeViewProps>(HomeView.name, {});
 };

new file
app/controllers/auth/getRegisterView.ts
@@ -0,0 +1,11 @@
+// 3rd-party
+import type { ReqHandler } from "@ethicdevs/react-monolith";
+// app
+import RegisterView, { RegisterViewProps } from "../../views/auth/RegisterView";
+
+const getRegisterView: ReqHandler = (request, reply) => {
+  const reqHandler = reply.makeRequestHandler(request, reply);
+  return reqHandler<RegisterViewProps>(RegisterView.name, {});
+};
+
+export default getRegisterView;

new file
app/controllers/auth/index.ts
@@ -0,0 +1,9 @@
+// import { default as getLoginView } from "./getLoginView";
+import { default as getRegisterView } from "./getRegisterView";
+import { default as postRegisterAction } from "./postRegisterAction";
+
+export const AuthController = {
+  // getLoginView,
+  getRegisterView,
+  postRegisterAction,
+};

new file
app/controllers/auth/postRegisterAction.ts
@@ -0,0 +1,19 @@
+// 3rd-party
+import type { ReqHandler } from "@ethicdevs/react-monolith";
+// app
+import { AppRoute, AppRoutesParams } from "../../routes";
+import RegisterView, { RegisterViewProps } from "../../views/auth/RegisterView";
+
+const postRegisterView: ReqHandler = (request, reply) => {
+  const { username, password } =
+    request.body as AppRoutesParams[AppRoute.AUTH_REGISTER_ACTION]["body"];
+
+  password;
+
+  const reqHandler = reply.makeRequestHandler(request, reply);
+  return reqHandler<RegisterViewProps>(RegisterView.name, {
+    initialValues: { username },
+  });
+};
+
+export default postRegisterView;

@@ -2,24 +2,66 @@
 import type { IRouteParams } from "@ethicdevs/react-monolith";
 import { AppRouter, AppRouterGroup, Router } from "@ethicdevs/react-monolith";
 // 3rd-party
+import { FastifySchema } from "fastify";
 import React from "react";
-// app
-/* controllers */
+// app controllers
+import { AuthController } from "./controllers/auth";
 import * as HomeController from "./controllers/HomeController";
 import * as ThemeController from "./controllers/ThemeController";
 
 export enum AppRoute {
   HOME = "home",
-  THEME_SET = "theme.set",
+  SET_THEME = "set_theme.action",
+  AUTH_REGISTER = "auth.register",
+  AUTH_REGISTER_ACTION = "auth.register.action",
+  AUTH_LOGIN = "auth.login",
 }
 
 export interface AppRoutesParams extends IRouteParams {
   [AppRoute.HOME]: undefined;
-  [AppRoute.THEME_SET]: {
+  [AppRoute.SET_THEME]: {
     themeScheme: string;
   };
+  [AppRoute.AUTH_REGISTER]: undefined;
+  [AppRoute.AUTH_REGISTER_ACTION]: {
+    body: {
+      username: string;
+      password: string;
+    };
+  };
+  [AppRoute.AUTH_LOGIN]: undefined;
 }
 
+export const AppRoutesSchemas: Record<AppRoute, undefined | FastifySchema> = {
+  [AppRoute.HOME]: undefined,
+  [AppRoute.SET_THEME]: {
+    params: {
+      type: "object",
+      required: ["themeScheme"],
+      additionalProperties: false,
+      properties: {
+        themeScheme: {
+          type: "string",
+          enum: ["light", "dark"],
+        },
+      },
+    },
+  },
+  [AppRoute.AUTH_REGISTER]: undefined,
+  [AppRoute.AUTH_REGISTER_ACTION]: {
+    body: {
+      type: "object",
+      required: ["username", "password"],
+      additionalProperties: false,
+      properties: {
+        username: { type: "string" },
+        password: { type: "string" },
+      },
+    },
+  },
+  [AppRoute.AUTH_LOGIN]: undefined,
+};
+
 const RootAppRouter: AppRouter = () => (
   <Router.Root>
     <></>

...
@@ -31,11 +73,25 @@ const RootAppRouter: AppRouter = () => (
         handler={HomeController.getHomeView}
       />
       <Router.Route
-        name={AppRoute.THEME_SET}
+        name={AppRoute.SET_THEME}
         method={"GET"}
         path={"/theme/:themeScheme"}
+        schema={AppRoutesSchemas[AppRoute.SET_THEME]}
         handler={ThemeController.getTheme}
       />
+      <Router.Route
+        name={AppRoute.AUTH_REGISTER}
+        method={"GET"}
+        path={"/auth/register"}
+        handler={AuthController.getRegisterView}
+      />
+      <Router.Route
+        name={AppRoute.AUTH_REGISTER_ACTION}
+        method={"POST"}
+        path={"/auth/register"}
+        schema={AppRoutesSchemas[AppRoute.AUTH_REGISTER_ACTION]}
+        handler={AuthController.postRegisterAction}
+      />
     </Router.Group>
   </Router.Root>
 );

@@ -13,6 +13,7 @@ import fastifyCookie, { CookieSerializeOptions } from "@fastify/cookie";
 import fastifyCustomSession, {
   PrismaSessionAdapter,
 } from "@ethicdevs/fastify-custom-session";
+import fastifyFormBody from "@fastify/formbody";
 import fastifyGitServer, { GitServer } from "@ethicdevs/fastify-git-server";
 import fastifyServeStatic from "fastify-static";
 // generated via script[generate:prisma]

...
@@ -129,6 +130,8 @@ async function main(): Promise<AppServer> {
 
       s.register(prismaPlugin, { prisma });
 
+      s.register(fastifyFormBody);
+
       s.register(fastifyServeStatic, {
         root: Paths.PUBLIC_FOLDER,
         prefix: publicBaseUrl,

...
@@ -208,27 +211,24 @@ async function main(): Promise<AppServer> {
             gitRepositoryDir: orgRepo.gitRepositoryDir,
           };
         },
-        onPush({ data, message, type }) {
-          const { request: _, ...dataRest } = data;
-          console.log("event.type:", type);
-          console.log("event.data:", dataRest);
-
+        onPush({ data, message }) {
+          message.write("\n");
           if (data.packType === GitServer.PackType.RECEIVE) {
             // client has done something like "git push"
             // it is uploading, we are receiving
-            message.write("\n");
+            console.log("receive-pack");
             message.write("🖖 See the details of your push at:\n");
             message.write(
               `🧲 ${Env.DEPLOYMENT_SCHEME}://${Env.DEPLOYMENT_DOMAIN}:${PORT}/${data.repoSlug}/commits/some_commit_hash\n`
             );
-            message.write("\n");
           } else if (data.packType === GitServer.PackType.UPLOAD) {
             // client has done something like "git clone"
             // it is receiving, we are uploading
-            message.write("\n");
+            console.log("upload-pack");
             message.write(`🖖 Welcome at GitFOSS ${data.username}!\n`);
-            message.write("\n");
           }
+          message.write("\n");
+          message.accept();
         },
       });
 

file deleted
app/views/DocHomeView.tsx
@@ -1,46 +0,0 @@
-// 3rd-party
-import React from "react";
-import type { ReactView } from "@ethicdevs/react-monolith";
-import styled from "styled-components";
-
-// app
-import type { CommonProps } from "../types";
-import { Layout } from "../components";
-
-export interface DocHomeViewProps extends CommonProps {}
-
-const DocHomeView: ReactView<DocHomeViewProps> = (props) => {
-  const { commonProps } = props;
-  return (
-    <Layout {...commonProps} showSideMenu={true}>
-      <StyledDocHomeWrapper>
-        <StyledDocSectionEntryCardsGrid></StyledDocSectionEntryCardsGrid>
-      </StyledDocHomeWrapper>
-    </Layout>
-  );
-};
-
-const StyledDocHomeWrapper = styled.div`
-  display: flex;
-  flex-flow: column nowrap;
-  justify-content: flex-start;
-  align-items: flex-start;
-
-  gap: 24px;
-  padding: 24px;
-  width: 100%;
-  max-width: 1176px;
-  margin: 0 auto;
-`;
-
-const StyledDocSectionEntryCardsGrid = styled.div`
-  display: flex;
-  flex-flow: row wrap;
-  align-items: stretch;
-  justify-content: center;
-  gap: 16px;
-  margin-top: 24px;
-`;
-
-DocHomeView.displayName = "DocHomeView";
-export default DocHomeView;

file deleted
app/views/DocPageView.tsx
@@ -1,226 +0,0 @@
-// 3rd-party
-import type { ReactView } from "@ethicdevs/react-monolith";
-import React from "react";
-import styled, { css } from "styled-components";
-// app
-import type { CommonProps, Page, WithThemeSchemeProp } from "../types";
-import { Layout, MarkdownToJsx, TextEllipsis } from "../components";
-import { NamedColors } from "../utils/style";
-
-export interface DocPageViewProps extends CommonProps {
-  page: Page;
-}
-
-const DocPageView: ReactView<DocPageViewProps> = ({ commonProps, page }) => {
-  const { themeScheme } = commonProps;
-  return (
-    <Layout
-      {...commonProps}
-      showSideMenu
-      showSideExamples={
-        page.metas.showExamples != null
-          ? Boolean(page.metas.showExamples)
-          : false
-      }
-    >
-      <StyledDocPageWrapper>
-        {page.metas.title != null && (
-          <h1 style={{ width: "100%", textAlign: "center" }}>
-            {page.metas.title}
-          </h1>
-        )}
-        {page.metas.summary != null && (
-          <div
-            style={{
-              width: "100%",
-              textAlign: "center",
-              color: NamedColors.TEXT_MUTED[themeScheme],
-            }}
-          >
-            <MarkdownToJsx
-              themeScheme={themeScheme}
-              markdown={page.metas.summary}
-            />
-          </div>
-        )}
-        <StyledDocContentRow>
-          <StyledDocContentCol>
-            <MarkdownToJsx themeScheme={themeScheme} markdown={page.content} />
-          </StyledDocContentCol>
-          {page.tableOfContent != null && page.tableOfContent.length >= 1 && (
-            <StyledDocTableOfContentsCol>
-              <h4
-                style={{
-                  margin: 0,
-                  marginBottom: 16,
-                  color: NamedColors.TEXT_DEFAULT[themeScheme],
-                }}
-              >
-                Table of Contents
-              </h4>
-              {page.tableOfContent.map((entry) => (
-                <StyledDocTableOfContentsItem
-                  depth={entry.depth}
-                  href={`#${entry.targetAnchor}`}
-                  key={entry.targetAnchor}
-                  title={entry.title}
-                  themeScheme={themeScheme}
-                >
-                  <TextEllipsis numberOfLines={2}>{entry.title}</TextEllipsis>
-                </StyledDocTableOfContentsItem>
-              ))}
-            </StyledDocTableOfContentsCol>
-          )}
-        </StyledDocContentRow>
-        {(page.metas?.prevPage != null || page.metas?.nextPage != null) && (
-          <StyledDocNavigationRow themeScheme={themeScheme}>
-            {page.metas?.prevPage != null ? (
-              <StyledDocNavigationLinkCol
-                href={page.metas.prevPage.href}
-                themeScheme={themeScheme}
-              >
-                <span>&lsaquo; {page.metas.prevPage.title}</span>
-                <span>{page.metas.prevPage?.subtitle || "Previous"}</span>
-              </StyledDocNavigationLinkCol>
-            ) : (
-              <StyledDocNavigationLinkCol themeScheme={themeScheme} />
-            )}
-            {page.metas?.nextPage != null ? (
-              <StyledDocNavigationLinkCol
-                href={page.metas.nextPage.href}
-                themeScheme={themeScheme}
-              >
-                <span>{page.metas.nextPage.title} &rsaquo;</span>
-                <span>{page.metas.nextPage?.subtitle || "Up Next"}</span>
-              </StyledDocNavigationLinkCol>
-            ) : (
-              <StyledDocNavigationLinkCol themeScheme={themeScheme} />
-            )}
-          </StyledDocNavigationRow>
-        )}
-      </StyledDocPageWrapper>
-    </Layout>
-  );
-};
-
-const StyledDocPageWrapper = styled.div`
-  display: flex;
-  flex-flow: column nowrap;
-  justify-content: flex-start;
-  align-items: flex-start;
-
-  gap: 24px;
-  padding: 24px;
-  width: 100%;
-  max-width: 960px;
-  margin: 0 auto;
-`;
-
-const StyledDocContentRow = styled.div`
-  display: flex;
-  flex-flow: row wrap;
-  justify-content: flex-start;
-  align-items: flex-start;
-  width: 100%;
-`;
-
-const StyledDocContentCol = styled.main`
-  display: flex;
-  flex-flow: column wrap;
-  justify-content: flex-start;
-  align-items: flex-start;
-  flex: 1;
-`;
-
-const StyledDocTableOfContentsCol = styled.aside`
-  display: flex;
-  flex-flow: column wrap;
-  justify-content: flex-start;
-  align-items: flex-start;
-  flex: 0.3;
-
-  position: sticky;
-  top: ${72 + 24}px;
-
-  margin-left: 24px;
-`;
-
-const StyledDocTableOfContentsItem = styled.a<
-  { depth: number } & WithThemeSchemeProp
->`
-  dipslay: flex;
-  flex-flow: row nowrap;
-  justify-content: flex-start;
-  align-item: center;
-
-  width: 100%;
-
-  font-size: 14px;
-  font-weight: bold;
-  line-height: 16px;
-  text-decoration: none;
-
-  &:hover {
-    text-decoration: underline;
-  }
-
-  padding: 4px 10px 4px 0px;
-  ${({ depth }) => css`
-    margin-left: ${Math.max(0, (depth - 2) * 8)}px;
-  `};
-
-  ${({ themeScheme }) => css`
-    color: ${NamedColors.TEXT_MUTED[themeScheme]};
-  `};
-`;
-
-const StyledDocNavigationLinkCol = styled.a<WithThemeSchemeProp>`
-  display: flex;
-  flex-flow: column nowrap;
-  justify-content: flex-start;
-  align-items: flex-start;
-
-  ${({ themeScheme }) => css`
-    color: ${NamedColors.TEXT_LINK[themeScheme]};
-  `};
-
-  font-weight: bold;
-  text-decoration: none;
-
-  &:hover {
-    text-decoration: underline;
-  }
-
-  & > span:first-child {
-    font-size: 16px;
-  }
-
-  & > span:last-child {
-    margin-top: 4px;
-    font-size: 14px;
-    font-weight: normal;
-    opacity: 0.87;
-  }
-`;
-
-const StyledDocNavigationRow = styled.div<WithThemeSchemeProp>`
-  display: flex;
-  flex-flow: row nowrap;
-  justify-content: space-between;
-  align-items: center;
-
-  width: 100%;
-  margin-top: 0;
-  padding-top: 24px;
-
-  ${({ themeScheme }) => css`
-    border-top: 1px solid ${NamedColors.BORDER_DEFAULT[themeScheme]};
-  `};
-
-  & > ${StyledDocNavigationLinkCol}:last-child {
-    align-items: flex-end;
-  }
-`;
-
-DocPageView.displayName = "DocPageView";
-export default DocPageView;

app/views/HomeView.tsx
@@ -5,7 +5,7 @@ import styled from "styled-components";
 
 // app
 import type { CommonProps } from "../types";
-import { ButtonAnchor, Layout } from "../components";
+import { ButtonAnchor, Layout, PageWrapper } from "../components";
 
 export interface HomeViewProps extends CommonProps {
   foo?: boolean;

...
@@ -15,29 +15,16 @@ const HomeView: ReactView<HomeViewProps> = (props) => {
   const { commonProps } = props;
   return (
     <Layout {...commonProps} showSideMenu={false}>
-      <StyledHomeWrapper>
+      <PageWrapper>
         <StyledButtonsRow>
           <ButtonAnchor href={"/auth/register"}>Get Started</ButtonAnchor>
           <ButtonAnchor href={"/features"}>Learn More</ButtonAnchor>
         </StyledButtonsRow>
-      </StyledHomeWrapper>
+      </PageWrapper>
     </Layout>
   );
 };
 
-const StyledHomeWrapper = styled.div`
-  display: flex;
-  flex-flow: column nowrap;
-  justify-content: center;
-  align-items: center;
-
-  gap: 24px;
-  padding: 24px 16px 64px 16px;
-  width: 100%;
-  max-width: 1176px;
-  margin: 0 auto;
-`;
-
 const StyledButtonsRow = styled.div`
   display: flex;
   flex-flow: row wrap;

new file
app/views/auth/RegisterView.tsx
@@ -0,0 +1,48 @@
+import type { ReactView } from "@ethicdevs/react-monolith";
+import React from "react";
+// app
+import type { CommonProps } from "../../types";
+import { Button, Layout, PageWrapper } from "../../components";
+
+export interface RegisterViewProps extends CommonProps {
+  initialValues?: {
+    username?: string;
+    password?: string;
+  };
+}
+
+const RegisterView: ReactView<RegisterViewProps> = ({
+  commonProps,
+  initialValues = undefined,
+}) => {
+  return (
+    <Layout {...commonProps} showSideMenu={false}>
+      <PageWrapper>
+        <form action={`/auth/register`} method={"POST"}>
+          <div>
+            <label htmlFor={"username"}>Username:</label>
+            <input
+              type={"text"}
+              name={"username"}
+              placeholder={"Choose a username (i.e. john.doe)..."}
+              defaultValue={initialValues?.username}
+            />
+          </div>
+          <div>
+            <label htmlFor={"username"}>Password:</label>
+            <input
+              type={"password"}
+              name={"password"}
+              placeholder={"Choose a great password..."}
+              defaultValue={initialValues?.password}
+            />
+          </div>
+          <Button type={"submit"}>Create my Account</Button>
+        </form>
+      </PageWrapper>
+    </Layout>
+  );
+};
+
+RegisterView.displayName = "RegisterView";
+export default RegisterView;

@@ -28,7 +28,7 @@
   },
   "dependencies": {
     "@ethicdevs/fastify-custom-session": "^0.6.0",
-    "@ethicdevs/fastify-git-server": "^1.3.1",
+    "@ethicdevs/fastify-git-server": "^1.4.3",
     "@ethicdevs/fastify-stream-react-views": "^1.9.9",
     "@ethicdevs/react-monolith": "^1.6.1",
     "@fastify/cookie": "6.0.0",

new file
public/instant-router.js.map
@@ -0,0 +1 @@
+{"version":3,"names":["__defProp","Object","defineProperty","__defProps","defineProperties","__getOwnPropDescs","getOwnPropertyDescriptors","__getOwnPropSymbols","getOwnPropertySymbols","__hasOwnProp","prototype","hasOwnProperty","__propIsEnum","propertyIsEnumerable","__defNormalProp","obj","key","value","enumerable","configurable","writable","__spreadValues","a","b","prop","call","__spreadProps","__name","target","__async","__this","__arguments","generator","Promise","resolve","reject","fulfilled","step","next","e","rejected","throw","x","done","then","apply","domParser","DOMParser","fetchAnchorHref","anchorHref","currentLocationHref","method","body","headers","this","url","toLowerCase","fetch","referer","accept","fetchAndPushState","targetHref","refererHref","targetHtml","document","dispatchEvent","CustomEvent","ClientSideRouterEvents","LOADING","detail","request","res","status","locationHeaderHref","get","text","LOADED","response","html","err","error","LOAD_ERROR","Error","targetDoc","parseFromString","targetBody","head","targetHead","title","targetTitle","targetStyles","childNodes","forEach","node","nodeType","nodeName","push","_a","NAVIGATING","innerHTML","scrollingElement","scrollTo","behavior","top","window","history","state","targetUrl","URL","pushState","pathname","join","NAVIGATED","NAVIGATION_ERROR","clientSideRouter","arguments","opts","fetchAnchorsOn","pageHref","location","href","onClientSideRouterMouseDown","ev","targetEl","tagName","trim","doNavigate","pollWaitFetchDoneIntervalId","navigateOrWait","removeEventListener","onClickHandler","setTimeout","clearTimeout","subEv","preventDefault","addEventListener","_","onClientSideRouterSubmit","targetAction","action","targetMethod","includes","targetFormData","FormData","targetFormDataEntries","v","k","bodyFormEncoded","entries","map","event","ClientSideRouterEventPrefix","replace","toString","catch"],"sources":["0"],"mappings":"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"}

@@ -303,9 +303,9 @@
     pg "^8.7.3"
     pg-pool "^3.5.1"
 
-"@ethicdevs/fastify-git-server@^1.3.1":
-  version "1.3.1"
-  resolved "https://registry.yarnpkg.com/@ethicdevs/fastify-git-server/-/fastify-git-server-1.3.1.tgz#f140f63b1d996b81d8a5c7d0bc889dd5f7ba3393"
+"@ethicdevs/fastify-git-server@^1.4.3":
+  version "1.4.3"
+  resolved "https://registry.yarnpkg.com/@ethicdevs/fastify-git-server/-/fastify-git-server-1.4.3.tgz#c415827f265266896df413797dd8f1172b2d982a"
   dependencies:
     debug "^4.3.4"
     fastify-plugin "^3.0.1"