Skip to content

Commit

Permalink
DAC-367
Browse files Browse the repository at this point in the history
  • Loading branch information
amnambiar committed Dec 4, 2022
1 parent 6f86bb0 commit 9e34de7
Show file tree
Hide file tree
Showing 5 changed files with 201 additions and 17 deletions.
16 changes: 12 additions & 4 deletions react-web/src/components/PrivateRoutes/PrivateRoutes.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from "react";
import { Outlet, useLocation } from "react-router-dom";
import { Outlet, useLocation, Navigate } from "react-router-dom";


import { useAppSelector } from "store/store";

Expand All @@ -9,13 +10,20 @@ const PrivateRoutes = () => {
const location = useLocation();
const renderNoAuthPage = () => {
if (location.pathname === "/") {
return <h1 style={{textAlign: "center"}}>Welcome to testing tool</h1>;
return <></>;
} else {
return <NotAuthorized />;
}
};
const { isLoggedIn } = useAppSelector((state) => state.auth);
return isLoggedIn ? <Outlet /> : renderNoAuthPage();
const renderOutlets = (userDetails: any) => {
if (location.pathname !== "/profile" && (!userDetails.dappOwner || !userDetails.dappRepository)) {
return <Navigate replace to="/profile" />;
} else {
return <Outlet />
}
}
const { isLoggedIn, userDetails } = useAppSelector((state) => state.auth);
return isLoggedIn ? renderOutlets(userDetails) : renderNoAuthPage();
}

export default PrivateRoutes;
17 changes: 17 additions & 0 deletions react-web/src/pages/userProfile/UserProfile.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#profileContainer {
max-width: 400px;
margin: 20px auto 0;
.input-wrapper {
.input {
&.disabled {
opacity: 1;
}
}
}
}

.button-wrapper {
display: flex;
justify-content: center;
gap: 20px;
}
128 changes: 122 additions & 6 deletions react-web/src/pages/userProfile/UserProfile.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,124 @@
import React from "react";
import MaintenancePage from "pages/maintenance/Maintenance";
import React, { useState, useEffect } from "react";
import Button from "components/Button/Button";
import { Input } from "compositions/Form/components/Input";
import { Form } from "compositions/Form/Form";
import { postData } from "api/api";
import { getProfileDetails } from "store/slices/auth.slice";
import { useAppDispatch, useAppSelector } from "store/store";
import { useForm } from "hooks/useForm";
import "./UserProfile.scss";
import { userProfileSchema } from "./userProfile.schema";
import { useNavigate } from "react-router-dom";

function UserProfile() {
return <MaintenancePage />;
}
const UserProfile = () => {
const dispatch = useAppDispatch();
const navigate = useNavigate();
const { userDetails } = useAppSelector((state: any) => state.auth);
const [isEdit, setIsEdit] = useState(false);
const form: any = useForm({
schema: userProfileSchema,
mode: "onChange",
});

export default UserProfile;
useEffect(()=> {if (!userDetails.dappOwner || !userDetails.dappRepository) {
setIsEdit(true);
}})

useEffect(() => {
const { dappOwner, dappRepository, company, vendor, linkedIn } =
userDetails;
form.reset({ dappOwner, dappRepository, company, vendor, linkedIn });
}, [userDetails]);

const formHandler = (formData: any) => {
const submitProfile = async () => {
await postData.get("static/data/current-profile.json", formData);
// await postData.put("/profile/current", formData);
await dispatch(
getProfileDetails({
address: localStorage.getItem("address"),
url: "static/data/new-profile.json",
})
);
navigate('/')
};
submitProfile();
};

return (
<div id="profileContainer">
<div>
<Form form={form} onSubmit={formHandler}>
<Input
label="dApp Owner"
disabled={!isEdit || userDetails.dappOwner}
type="text"
disablefocus="true"
{...form.register("dappOwner")}
/>
<Input
label="dApp Repository"
disabled={!isEdit || userDetails.dappOwner}
type="text"
disablefocus="true"
{...form.register("dappRepository")}
/>
<Input
label="Company"
type="text"
id="company"
disabled={!isEdit}
disablefocus="true"
{...form.register("company")}
/>
<Input
label="Vendor"
type="text"
id="vendor"
disablefocus="true"
disabled={!isEdit}
{...form.register("vendor")}
/>
<Input
label="LinkedIn Url"
type="text"
id="linkedIn"
disablefocus="true"
disabled={!isEdit}
{...form.register("linkedIn")}
/>
<div className="button-wrapper">
{!isEdit ? (
<Button
type="button"
buttonLabel={"Edit"}
onClick={(e) => {
setIsEdit(!isEdit);
}}
/>
) : (
<>
<Button
type="button"
displayStyle="secondary"
buttonLabel={"Cancel"}
onClick={() => {
setIsEdit(false);
}}
/>
<Button
disabled={!form.formState.isValid}
type="submit"
buttonLabel={"Save"}
onClick={() => {}}
/>
</>
)}
</div>
</Form>
</div>
</div>
);
};

export default UserProfile;
6 changes: 6 additions & 0 deletions react-web/src/pages/userProfile/userProfile.schema.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import * as yup from "yup";

export const userProfileSchema = yup.object().shape({
dappOwner: yup.string().required("This field is required."),
dappRepository: yup.string().required("This field is required.")
});
51 changes: 44 additions & 7 deletions react-web/src/store/slices/auth.slice.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,66 @@
import { createSlice } from "@reduxjs/toolkit";
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import { postData } from "api/api";

// Define a type for the slice state
interface AuthState {
isLoggedIn: boolean;
address: string;
userDetails: {
company?: string;
vendor?: string;
website?: string;
linkedIn?: string;
dappOwner?: string; //will be received only if pre-set
dappRepository?: string; //will be received only if pre-set
};
loading: boolean;
}

// Define the initial state using that type
const initialState: AuthState = {
isLoggedIn: false,
address: '',
userDetails: {},
loading: false
};

export const getProfileDetails: any = createAsyncThunk("getProfileDetails", async (data: any, { rejectWithValue }) => {
try {
// const response = await postData.get("/profile/current")
const response = await postData.get(data.url || 'static/data/current-profile.json', data)
return response.data
} catch(e) {
return rejectWithValue(e)
}
})

export const authSlice = createSlice({
name: "auth",
// `createSlice` will infer the state type from the `initialState` argument
initialState,
reducers: {
login: (state) => {
state.isLoggedIn = true;
},
logout: (state) => {
state.isLoggedIn = false;
localStorage.removeItem('address')
return initialState
},
},
extraReducers: {
[getProfileDetails.pending]: (state) => {state.loading = true;},
[getProfileDetails.fulfilled]: (state, actions) => {
state.loading = false;
state.isLoggedIn = true;
state.userDetails = actions.payload;
state.address = actions.meta.arg.address;
localStorage.setItem('address', state.address)
},
[getProfileDetails.rejected]: (state) => {
localStorage.removeItem('address')
return initialState
}
}
});

export const { login, logout } = authSlice.actions;

export default authSlice.reducer;
export const { logout } = authSlice.actions;

export default authSlice.reducer;

0 comments on commit 9e34de7

Please sign in to comment.