cleaned up admin

This commit is contained in:
Luke Berndt
2023-04-05 21:38:24 -04:00
parent f7f5265264
commit 346107eb1a
19 changed files with 76 additions and 269 deletions

View File

@@ -28,7 +28,7 @@ const ConfirmEmail = (props) => {
useEffect(() => { useEffect(() => {
checkConfirmation(userId, token); checkConfirmation(userId, token);
}, []); }, [userId, token]);
const dimmerProps = { active: loading }; const dimmerProps = { active: loading };

View File

@@ -1,14 +0,0 @@
import { connect } from "react-redux"
import ConfirmEmail from "./ConfirmEmail"
import * as userActions from "./user-actions"
const mapStateToProps = (state) => {
return {
user: state.user
}
}
export default connect(
mapStateToProps,
userActions
)(ConfirmEmail)

View File

@@ -1,8 +1,8 @@
import React, { useEffect, useState, } from "react"; import { useState } from "react";
import { useNavigate, useSearchParams, Link } from 'react-router-dom'; import { useNavigate, useSearchParams, Link } from 'react-router-dom';
import { loginUser } from "../features/user/userSlice"; import { loginUser } from "../features/user/userSlice";
import { useSelector, useDispatch } from 'react-redux' import { useDispatch } from 'react-redux'
import { import {
Container, Container,
Header, Header,
@@ -33,7 +33,7 @@ const Login = (props) => {
const [email, setEmail] = useState(""); const [email, setEmail] = useState("");
const [password, setPassword] = useState(""); const [password, setPassword] = useState("");
const navigate = useNavigate(); const navigate = useNavigate();
let [searchParams, setSearchParams] = useSearchParams(); let [searchParams] = useSearchParams();
const nextLocation = searchParams.get("nextLocation"); const nextLocation = searchParams.get("nextLocation");
const dispatch = useDispatch(); const dispatch = useDispatch();

View File

@@ -1,35 +0,0 @@
import { connect } from "react-redux"
import * as userActions from "./user-actions"
import Login from "./Login"
import queryString from '../query-string';
// Function passed in to `connect` to subscribe to Redux store updates.
// Any time it updates, mapStateToProps is called.
// The second argument "ownProps" contains props passed to the component
const mapStateToProps = (state, props) => {
let nextPathname = false;
try {nextPathname = props.location.state.nextPathname}
catch(err) {}
const uri = queryString.parse(props.location.search);
let nextLocation = uri['nextLocation'];
return {
user: state.user,
nextPathname, // this prop passed in by React Router
nextLocation
}
}
// Connects React component to the redux store
// It does not modify the component class passed to it
// Instead, it returns a new, connected component class, for you to use.
export default connect(
mapStateToProps,
userActions
)(Login)

View File

@@ -1,6 +1,5 @@
import React, { useEffect, useState, } from "react"; import { useState, } from "react";
import { useSelector, useDispatch } from 'react-redux' import { useSelector, useDispatch } from 'react-redux'
import { useNavigate, useSearchParams, Link } from 'react-router-dom';
import UserForm from "./UserForm"; import UserForm from "./UserForm";
import { import {
Container, Container,

View File

@@ -1,15 +0,0 @@
import { connect } from "react-redux"
import Profile from "./Profile"
import * as userActions from "./user-actions"
const mapStateToProps = (state) => {
return {
user: state.user,
isWaiting: state.user.isWaiting
}
}
export default connect(
mapStateToProps,
userActions
)(Profile)

View File

@@ -1,7 +1,7 @@
import React, { useState } from "react"; import { useState } from "react";
import { registerUser } from "../features/user/userSlice"; import { registerUser } from "../features/user/userSlice";
import { useNavigate, useSearchParams, Link } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { useSelector, useDispatch } from 'react-redux' import { useDispatch } from 'react-redux'
import { import {
Container, Container,
Header, Header,

View File

@@ -1,14 +0,0 @@
import { connect } from "react-redux"
import * as userActions from "./user-actions"
import Register from "./Register"
const mapStateToProps = (state) => {
return {
isWaiting: state.user.isWaiting
}
}
export default connect(
mapStateToProps,
userActions
)(Register)

View File

@@ -1,14 +0,0 @@
import { connect } from "react-redux"
import ResetPassword from "./ResetPassword"
import * as userActions from "./user-actions"
const mapStateToProps = (state) => {
return {
user: state.user
}
}
export default connect(
mapStateToProps,
userActions
)(ResetPassword)

View File

@@ -1,4 +1,4 @@
import React, { useState } from "react"; import { useState } from "react";
import { import {
Form, Form,
Grid, Grid,
@@ -9,14 +9,12 @@ import {
} from "semantic-ui-react"; } from "semantic-ui-react";
import { sendResetPassword } from "../features/user/userSlice"; import { sendResetPassword } from "../features/user/userSlice";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { useParams, useNavigate } from 'react-router-dom';
import { useDispatch } from 'react-redux' import { useDispatch } from 'react-redux'
const SendResetPassword = (props) => { const SendResetPassword = () => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const navigate = useNavigate();
const [checkInputMessages, setCheckInputMessages] = useState(""); const [checkInputMessages, setCheckInputMessages] = useState("");
const [email, setEmail] = useState(""); const [email, setEmail] = useState("");
const [emailError, setEmailError] = useState(false); const [emailError, setEmailError] = useState(false);

View File

@@ -1,14 +0,0 @@
import { connect } from "react-redux"
import SendResetPassword from "./SendResetPassword"
import * as userActions from "./user-actions"
const mapStateToProps = (state) => {
return {
user: state.user
}
}
export default connect(
mapStateToProps,
userActions
)(SendResetPassword)

View File

@@ -1,14 +0,0 @@
import { connect } from "react-redux"
import SentConfirmEmail from "./SentConfirmEmail"
import * as userActions from "./user-actions"
const mapStateToProps = (state) => {
return {
user: state.user
}
}
export default connect(
mapStateToProps,
userActions
)(SentConfirmEmail)

View File

@@ -1,84 +1,63 @@
import React, { Component } from "react"; import React, { useState } from "react";
import { import { Segment, Container, Button } from "semantic-ui-react";
Segment,
Container,
Button
} from "semantic-ui-react";
class Terms extends Component { const Terms = ({ user, acceptTerms }) => {
constructor(props) { const [requestMessage, setRequestMessage] = useState(null);
super(props);
this.handleAccept = this.handleAccept.bind(this);
this.handleDecline = this.handleDecline.bind(this);
}
const handleAccept = () => {
acceptTerms(user.userId).then((requestMessage) => {
if (requestMessage) {
setRequestMessage(requestMessage);
}
});
};
const handleDecline = () => {};
handleAccept() { return (
this.props <div>
.acceptTerms(this.props.user.userId) <Container text>
.then(requestMessage => { <Segment attached>
if (requestMessage) { The agreement is useful to The Guardian to set the rules and guidelines for visitors, users and customers:
// report to the user is there was a problem during registration
this.setState({
requestMessage
});
}
});
}
handleDecline() { Registration: inform users that they must agree to a set of rules when they register on your website or mobile app
Disable or terminate accounts: inform users that their accounts can be disabled or terminated if abuses happen on your website or mobile app, e.g. spamming, swearing etc.
Owner of content: notify users that you, the company, is the owner of the content appearing on your website or mobile app – except in cases where other users can post content (upload, share, create etc.) where the users are the owners of such content
Changes to the agreement: users should be informed about upcoming changes to the agreement before the changes are applied.
DMCA: The Guardian is also informing owners of copyright content that they can submit a DMCA notice to the website if they found infringing content in their DMCA clause.
And more
These are only a few examples of what kind of clauses and disclosures you can add in this kind of agreement.
} What is a Terms of Use
While a Terms of Use is recommended to have, it’s not mandatory by law as the Privacy Policy agreement is required.
render() { This agreement serves a single purpose: to inform users of rules that they must agree to. A Privacy Policy must inform users about your privacy practices (what data you collect, why, how, etc.)
return (
<div>
<Container text> The definition of a Terms of Use agreement is simple:
<Segment attached>
The agreement is useful to The Guardian to set the rules and guidelines for visitors, users and customers:
Registration: inform users that they must agree to a set of rules when they register on your website or mobile app Terms of service (also known as terms of use and terms and conditions, commonly abbreviated as ToS or TOS and TOU) are rules which one must agree to abide by in order to use a service.
Disable or terminate accounts: inform users that their accounts can be disabled or terminated if abuses happen on your website or mobile app, e.g. spamming, swearing etc.
Owner of content: notify users that you, the company, is the owner of the content appearing on your website or mobile app – except in cases where other users can post content (upload, share, create etc.) where the users are the owners of such content
Changes to the agreement: users should be informed about upcoming changes to the agreement before the changes are applied.
DMCA: The Guardian is also informing owners of copyright content that they can submit a DMCA notice to the website if they found infringing content in their DMCA clause.
And more
These are only a few examples of what kind of clauses and disclosures you can add in this kind of agreement.
What is a Terms of Use Wikipedia
While a Terms of Use is recommended to have, it’s not mandatory by law as the Privacy Policy agreement is required. Because this agreement simply acts as a contract between you, the company, and the users using or accessing your website or mobile app, the agreement can be named as you’d like:
This agreement serves a single purpose: to inform users of rules that they must agree to. A Privacy Policy must inform users about your privacy practices (what data you collect, why, how, etc.) Terms of Use (ToU)
Terms of Service (ToS)
The definition of a Terms of Use agreement is simple: Terms and Conditions (T&amp;C)
User Agreement
Terms of service (also known as terms of use and terms and conditions, commonly abbreviated as ToS or TOS and TOU) are rules which one must agree to abide by in order to use a service. Conditions of Use
And so on
Wikipedia The “Conditions of Use” of Amazon could be named “Terms of Use”:
Because this agreement simply acts as a contract between you, the company, and the users using or accessing your website or mobile app, the agreement can be named as you’d like:
Terms of Use (ToU)
Terms of Service (ToS)
Terms and Conditions (T&C)
User Agreement
Conditions of Use
And so on
The “Conditions of Use” of Amazon could be named “Terms of Use”:
</Segment> </Segment>
<Button.Group attached="bottom"> <Button.Group attached="bottom">
<Button <Button onClick={handleDecline}>Decline</Button>
onClick={this.handleDecline} <Button.Or />
>Decline</Button> <Button positive onClick={handleAccept}>
<Button.Or /> Accept
<Button positive </Button>
onClick={this.handleAccept} </Button.Group>
>Accept</Button> </Container>
</Button.Group> </div>
</Container> );
</div> };
);
}
}
export default Terms; export default Terms;

View File

@@ -1,14 +0,0 @@
import { connect } from "react-redux"
import * as userActions from "./user-actions"
import Terms from "./Terms"
function mapStateToProps(state) {
return {
user: state.user
}
}
export default connect(
mapStateToProps,
userActions
)(Terms)

View File

@@ -27,7 +27,7 @@ const UserForm = (props) => {
const [locationError, setLocationError] = useState(false); const [locationError, setLocationError] = useState(false);
const [passwordError, setPasswordError] = useState(false); const [passwordError, setPasswordError] = useState(false);
const [confirmPasswordError, setConfirmPasswordError] = useState(false); const [confirmPasswordError, setConfirmPasswordError] = useState(false);
const [isEditing, setIsEditing] = useState(props.isEditing); const [isEditing] = useState(props.isEditing);
const [changed, setChanged] = useState(false); const [changed, setChanged] = useState(false);
const requestMessage = props.requestMessage; const requestMessage = props.requestMessage;
@@ -156,7 +156,7 @@ const UserForm = (props) => {
</Message> </Message>
); );
} }
const buttonDisabled = changed?{}:{disabled:true}
return ( return (
<div> <div>
<Form <Form

View File

@@ -1,4 +1,3 @@
import React, { useState } from "react";
import { sendConfirmEmail } from "../features/user/userSlice"; import { sendConfirmEmail } from "../features/user/userSlice";
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { useSelector, useDispatch } from 'react-redux' import { useSelector, useDispatch } from 'react-redux'
@@ -9,8 +8,8 @@ const WaitConfirmEmail = () => {
const navigate = useNavigate(); const navigate = useNavigate();
const { email, userId } = useSelector((state) => state.user); const { email, userId } = useSelector((state) => state.user);
const handleSendConfirmEmail = async (event) => { const handleSendConfirmEmail = async () => {
const message = await dispatch(sendConfirmEmail(userId)).unwrap(); await dispatch(sendConfirmEmail(userId)).unwrap();
navigate("/sent-confirm-email") navigate("/sent-confirm-email")
}; };

View File

@@ -1,14 +0,0 @@
import { connect } from "react-redux"
import WaitConfirmEmail from "./WaitConfirmEmail"
import * as userActions from "./user-actions"
const mapStateToProps = (state) => {
return {
user: state.user
}
}
export default connect(
mapStateToProps,
userActions
)(WaitConfirmEmail)

View File

@@ -1,24 +1,7 @@
// Import the RTK Query methods from the React-specific entry point // Import the RTK Query methods from the React-specific entry point
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react' import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
import { createSelector } from '@reduxjs/toolkit'
/*
const axiosBaseQuery =
({ baseUrl } = { baseUrl: '' }) =>
async ({ url, method, data, params }) => {
try {
const result = await axios({ url: baseUrl + url, method, data, params })
return { data: result.data }
} catch (axiosError) {
let err = axiosError
return {
error: {
status: err.response?.status,
data: err.response?.data || err.message,
},
}
}
}*/
// Define our single API slice object // Define our single API slice object
export const apiSlice = createApi({ export const apiSlice = createApi({
@@ -56,9 +39,9 @@ export const apiSlice = createApi({
async onQueryStarted(group, { dispatch, queryFulfilled }) { async onQueryStarted(group, { dispatch, queryFulfilled }) {
try { try {
const { data: updatedGroup } = await queryFulfilled const { data: updatedGroup } = await queryFulfilled
const patchResult = dispatch( dispatch(
apiSlice.util.updateQueryData('getGroups', updatedGroup.shortName, (groups) => { apiSlice.util.updateQueryData('getGroups', updatedGroup.shortName, (groups) => {
const groupIndex = groups.findIndex((obj => obj.groupId == updatedGroup.groupId)); const groupIndex = groups.findIndex((obj => obj.groupId === updatedGroup.groupId));
groups[groupIndex] = updatedGroup; groups[groupIndex] = updatedGroup;
}) })
) )
@@ -75,7 +58,7 @@ export const apiSlice = createApi({
async onQueryStarted(group, { dispatch, queryFulfilled }) { async onQueryStarted(group, { dispatch, queryFulfilled }) {
try { try {
const { data: newGroup } = await queryFulfilled; const { data: newGroup } = await queryFulfilled;
const patchResult = dispatch( dispatch(
apiSlice.util.updateQueryData('getGroups', newGroup.shortName, (groups) => { apiSlice.util.updateQueryData('getGroups', newGroup.shortName, (groups) => {
groups.push(newGroup); groups.push(newGroup);
}) })
@@ -93,9 +76,9 @@ export const apiSlice = createApi({
async onQueryStarted(group, { dispatch, queryFulfilled }) { async onQueryStarted(group, { dispatch, queryFulfilled }) {
try { try {
await queryFulfilled await queryFulfilled
const patchResult = dispatch( dispatch(
apiSlice.util.updateQueryData('getGroups', group.shortName, (groups) => { apiSlice.util.updateQueryData('getGroups', group.shortName, (groups) => {
const groupIndex = groups.findIndex((obj => obj.groupId == group.groupId)); const groupIndex = groups.findIndex((obj => obj.groupId === group.groupId));
groups.splice(groupIndex,1); groups.splice(groupIndex,1);
}) })
) )
@@ -123,7 +106,7 @@ export const apiSlice = createApi({
async onQueryStarted({shortName,file}, { dispatch, queryFulfilled }) { async onQueryStarted({shortName,file}, { dispatch, queryFulfilled }) {
try { try {
const { data: newTalkgroups } = await queryFulfilled; const { data: newTalkgroups } = await queryFulfilled;
const patchResult = dispatch( dispatch(
apiSlice.util.updateQueryData('getTalkgroups', shortName, (talkgroups) => { apiSlice.util.updateQueryData('getTalkgroups', shortName, (talkgroups) => {
talkgroups.length = 0; // Clear your array talkgroups.length = 0; // Clear your array
talkgroups.push(...newTalkgroups); talkgroups.push(...newTalkgroups);
@@ -147,7 +130,7 @@ export const apiSlice = createApi({
async onQueryStarted(system, { dispatch, queryFulfilled }) { async onQueryStarted(system, { dispatch, queryFulfilled }) {
try { try {
const { data: newSystem } = await queryFulfilled const { data: newSystem } = await queryFulfilled
const patchResult = dispatch( dispatch(
apiSlice.util.updateQueryData('getSystems', undefined, (systemsData) => { apiSlice.util.updateQueryData('getSystems', undefined, (systemsData) => {
const systems = systemsData.systems; const systems = systemsData.systems;
systems.push(newSystem); systems.push(newSystem);
@@ -166,10 +149,10 @@ export const apiSlice = createApi({
async onQueryStarted(system, { dispatch, queryFulfilled }) { async onQueryStarted(system, { dispatch, queryFulfilled }) {
try { try {
const { data: updatedSystem } = await queryFulfilled const { data: updatedSystem } = await queryFulfilled
const patchResult = dispatch( dispatch(
apiSlice.util.updateQueryData('getSystems', undefined, (systemsData) => { apiSlice.util.updateQueryData('getSystems', undefined, (systemsData) => {
const systems = systemsData.systems; const systems = systemsData.systems;
const systemIndex = systems.findIndex((obj => obj.shortName == updatedSystem.shortName)); const systemIndex = systems.findIndex((obj => obj.shortName === updatedSystem.shortName));
systems[systemIndex] = updatedSystem; systems[systemIndex] = updatedSystem;
}) })
) )
@@ -185,10 +168,10 @@ export const apiSlice = createApi({
async onQueryStarted(shortName, { dispatch, queryFulfilled }) { async onQueryStarted(shortName, { dispatch, queryFulfilled }) {
try { try {
await queryFulfilled await queryFulfilled
const patchResult = dispatch( dispatch(
apiSlice.util.updateQueryData('getSystems', undefined, (systemsData) => { apiSlice.util.updateQueryData('getSystems', undefined, (systemsData) => {
const systems = systemsData.systems; const systems = systemsData.systems;
const systemIndex = systems.findIndex((obj => obj.shortName == shortName)); const systemIndex = systems.findIndex((obj => obj.shortName === shortName));
systems.splice(systemIndex, 1); systems.splice(systemIndex, 1);
}) })
) )

View File

@@ -1,7 +1,5 @@
import { import {
createSlice, createSlice,
createEntityAdapter,
createSelector,
createAsyncThunk createAsyncThunk
} from '@reduxjs/toolkit' } from '@reduxjs/toolkit'
@@ -145,7 +143,6 @@ export const resetPassword = createAsyncThunk(
export const sendResetPassword = createAsyncThunk( export const sendResetPassword = createAsyncThunk(
'user/sendResetPassword', 'user/sendResetPassword',
async (data) => { async (data) => {
const {userId, token, password} = data;
const url = process.env.REACT_APP_ACCOUNT_SERVER + "/api/send-reset-password" const url = process.env.REACT_APP_ACCOUNT_SERVER + "/api/send-reset-password"
const res = await fetch(url, { const res = await fetch(url, {
method: 'POST', method: 'POST',