diff --git a/src/App.tsx b/src/App.tsx
index 5e6485c..253ac02 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -17,6 +17,7 @@ import { PrivilegeLevel } from './auth/ducks/types';
import { C4CState } from './store';
import { getPrivilegeLevel } from './auth/ducks/selectors';
import { useSelector } from 'react-redux';
+import Onboarding from './containers/onboarding';
const { Content } = Layout;
@@ -32,6 +33,7 @@ export enum Routes {
FORGOT_PASSWORD_REQUEST = '/forgot-password',
FORGOT_PASSWORD_RESET = '/forgot-password-reset/:key',
VERIFY_EMAIL = '/verify/:key',
+ ONBOARDING = '/onboarding',
}
const App: React.FC = () => {
@@ -72,6 +74,11 @@ const App: React.FC = () => {
exact
component={VerifyEmail}
/>
+
);
@@ -96,6 +103,11 @@ const App: React.FC = () => {
exact
component={VerifyEmail}
/>
+
);
diff --git a/src/api/protectedApiClient.ts b/src/api/protectedApiClient.ts
index c1a55c5..2f96657 100644
--- a/src/api/protectedApiClient.ts
+++ b/src/api/protectedApiClient.ts
@@ -6,6 +6,10 @@ export interface ProtectedApiClient {
newPassword: string;
}) => Promise;
readonly deleteUser: (request: { password: string }) => Promise;
+ readonly postOnboardingForm: (
+ request: PostRequestData,
+ ) => Promise;
+ readonly getOnboardingData: () => Promise;
}
export enum ProtectedApiClientRoutes {
@@ -13,6 +17,37 @@ export enum ProtectedApiClientRoutes {
DELETE_USER = '/api/v1/protected/user/',
}
+export interface PostRequestData {
+ title: string;
+ body: string;
+ userId: number;
+}
+
+export interface GetResponseData {
+ id: number;
+ title: string;
+ body: string;
+ userId: number;
+}
+
+const postOnboardingForm = async (
+ request: PostRequestData,
+): Promise => {
+ const res = await AppAxiosInstance.post(
+ 'https://jsonplaceholder.typicode.com/posts',
+ request,
+ { headers: { 'Access-Control-Allow-Origin': '*' } },
+ );
+ return res.data;
+};
+
+const getOnboardingData = async (): Promise => {
+ const res = await AppAxiosInstance.get(
+ 'https://jsonplaceholder.typicode.com/posts',
+ );
+ return res.data;
+};
+
const changePassword = (request: {
currentPassword: string;
newPassword: string;
@@ -34,6 +69,8 @@ const deleteUser = (request: { password: string }): Promise => {
const Client: ProtectedApiClient = Object.freeze({
changePassword,
deleteUser,
+ postOnboardingForm,
+ getOnboardingData,
});
export default Client;
diff --git a/src/components/onboarding/index.tsx b/src/components/onboarding/index.tsx
new file mode 100644
index 0000000..7fcce0f
--- /dev/null
+++ b/src/components/onboarding/index.tsx
@@ -0,0 +1,24 @@
+import { Card, Typography } from 'antd';
+import React from 'react';
+const { Title, Paragraph } = Typography;
+
+interface ResponseCardProps {
+ id: number;
+ title: string;
+ body: string;
+ userId: number;
+}
+
+export const ResponseCard: React.FC = ({
+ id,
+ title,
+ body,
+ userId,
+}) => {
+ return (
+
+ {id}
+ {body}
+
+ );
+};
diff --git a/src/containers/onboarding/index.tsx b/src/containers/onboarding/index.tsx
new file mode 100644
index 0000000..b132704
--- /dev/null
+++ b/src/containers/onboarding/index.tsx
@@ -0,0 +1,178 @@
+import React, { useState } from 'react';
+import { Button, Card, Form, Input, Typography } from 'antd';
+import styled from 'styled-components';
+import { ResponseCard } from '../../components/onboarding';
+import ProtectedApiClient, {
+ GetResponseData,
+ PostRequestData,
+} from '../../api/protectedApiClient';
+import {
+ AsyncRequest,
+ AsyncRequestCompleted,
+ AsyncRequestFailed,
+ asyncRequestIsComplete,
+ AsyncRequestLoading,
+ AsyncRequestNotStarted,
+} from '../../utils/asyncRequest';
+
+const { Title, Paragraph } = Typography;
+
+const Container = styled.div`
+ display: flex;
+ flex-direction: column;
+ flex-wrap: wrap;
+ align-items: center;
+ width: 100%;
+`;
+
+const FormCard = styled(Card)`
+ display: flex;
+ width: 50%;
+ border-radius: 5px;
+`;
+
+const OnboardingPageTitle = styled(Title)`
+ display: flex;
+ width: 100%;
+ justify-content: center;
+`;
+
+const FormInput = styled(Input)`
+ display: flex;
+ width: 80%;
+ border: 1px 1px black;
+`;
+
+const StyledButton = styled(Button)`
+ width: 30%;
+ margin-top: 16px;
+`;
+
+const ResponseContainer = styled.div`
+ width: 75%;
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ justify-content: space-evenly;
+ margin-top: 16px;
+`;
+
+const SuccessMessage = styled(Paragraph)`
+ color: green;
+`;
+
+const Onboarding: React.FC = () => {
+ const [createPostRequest, setCreatePostRequest] = useState<
+ AsyncRequest
+ >(AsyncRequestNotStarted());
+ const [getPostsRequest, setGetPostsRequest] = useState<
+ AsyncRequest
+ >(AsyncRequestNotStarted());
+
+ const getPosts = async () => {
+ setCreatePostRequest(AsyncRequestLoading());
+ await ProtectedApiClient.getOnboardingData()
+ .then((res) => {
+ setCreatePostRequest(AsyncRequestCompleted(res));
+ })
+ .catch((error) => {
+ setCreatePostRequest(AsyncRequestFailed(error));
+ });
+ };
+
+ const onFinish = async (values: PostRequestData) => {
+ setGetPostsRequest(AsyncRequestLoading());
+ await ProtectedApiClient.postOnboardingForm(values)
+ .then((res) => {
+ setGetPostsRequest(AsyncRequestCompleted(res));
+ })
+ .catch((error) => {
+ setGetPostsRequest(AsyncRequestFailed(error));
+ });
+ };
+
+ const onFinishFailed = (errorInfo: any) => {
+ setGetPostsRequest(AsyncRequestFailed(errorInfo));
+ };
+
+ return (
+ <>
+
+
+ Code4Community Frontend Onboarding Tutorial!
+
+
+ Form!
+ This is an example form card to create a post.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {asyncRequestIsComplete(getPostsRequest) && (
+
+ Successfully created getPostsRequest with title '
+ {getPostsRequest.result.title}'!
+
+ )}
+
+ Get Posts
+
+ {asyncRequestIsComplete(createPostRequest) &&
+ createPostRequest.result.map((post: GetResponseData, i: number) => {
+ return (
+
+ );
+ })}
+
+
+ >
+ );
+};
+
+export default Onboarding;
diff --git a/src/utils/test/asyncRequest.test.ts b/src/utils/test/asyncRequest.test.ts
index 7b2d1d9..b67d234 100644
--- a/src/utils/test/asyncRequest.test.ts
+++ b/src/utils/test/asyncRequest.test.ts
@@ -6,7 +6,9 @@ import {
AsyncRequest,
AsyncRequestCompleted,
AsyncRequestFailed,
- asyncRequestIsComplete, asyncRequestIsFailed, asyncRequestIsLoading,
+ asyncRequestIsComplete,
+ asyncRequestIsFailed,
+ asyncRequestIsLoading,
asyncRequestIsNotStarted,
AsyncRequestLoading,
AsyncRequestNotStarted,
@@ -183,7 +185,6 @@ describe('asyncRequest ', () => {
);
});
-
it('asyncRequestIsFailed identifies Failed asyncRequests', () => {
asyncRequests.map(
(asyncRequest: AsyncRequest, index: number) => {
@@ -195,6 +196,5 @@ describe('asyncRequest ', () => {
},
);
});
-
});
});