Updated home page
This commit is contained in:
parent
0ad6eb2e14
commit
b9a4828558
@ -18,6 +18,11 @@ router.get('/', updateUser, validateUser, async (req, res) => {
|
||||
res.json(knownUsers);
|
||||
});
|
||||
|
||||
router.get('/count', async (req, res) => {
|
||||
const count = await User.countDocuments();
|
||||
res.json(count);
|
||||
});
|
||||
|
||||
router.delete('/:id', updateUser, validateUser, async (req, res) => {
|
||||
const user = res.locals.user;
|
||||
user.username = `deleted-user-${generateInvite(6)}`;
|
||||
|
21
frontend/package-lock.json
generated
21
frontend/package-lock.json
generated
@ -34,6 +34,7 @@
|
||||
"react-dom": "^17.0.2",
|
||||
"react-hook-form": "^7.12.1",
|
||||
"react-modal": "^3.14.3",
|
||||
"react-number-format": "^4.7.3",
|
||||
"react-particles-js": "^3.5.3",
|
||||
"react-redux": "^7.2.4",
|
||||
"react-router-dom": "^5.2.0",
|
||||
@ -16524,6 +16525,18 @@
|
||||
"react-dom": "^0.14.0 || ^15.0.0 || ^16 || ^17"
|
||||
}
|
||||
},
|
||||
"node_modules/react-number-format": {
|
||||
"version": "4.7.3",
|
||||
"resolved": "https://registry.npmjs.org/react-number-format/-/react-number-format-4.7.3.tgz",
|
||||
"integrity": "sha512-4EvcANjstypQ5anhanmdEioGc49qbnErfS+yqbhatC0vzQ1okplkWNb0DIY7ABu4RhaxzttEz6pypEy8KsqgBQ==",
|
||||
"dependencies": {
|
||||
"prop-types": "^15.7.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^0.14 || ^15.0.0-0 || ^16.0.0-0 || ^17.0.0-0",
|
||||
"react-dom": "^0.14 || ^15.0.0-0 || ^16.0.0-0 || ^17.0.0-0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-particles-js": {
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/react-particles-js/-/react-particles-js-3.5.3.tgz",
|
||||
@ -34668,6 +34681,14 @@
|
||||
"warning": "^4.0.3"
|
||||
}
|
||||
},
|
||||
"react-number-format": {
|
||||
"version": "4.7.3",
|
||||
"resolved": "https://registry.npmjs.org/react-number-format/-/react-number-format-4.7.3.tgz",
|
||||
"integrity": "sha512-4EvcANjstypQ5anhanmdEioGc49qbnErfS+yqbhatC0vzQ1okplkWNb0DIY7ABu4RhaxzttEz6pypEy8KsqgBQ==",
|
||||
"requires": {
|
||||
"prop-types": "^15.7.2"
|
||||
}
|
||||
},
|
||||
"react-particles-js": {
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/react-particles-js/-/react-particles-js-3.5.3.tgz",
|
||||
|
@ -30,6 +30,7 @@
|
||||
"react-dom": "^17.0.2",
|
||||
"react-hook-form": "^7.12.1",
|
||||
"react-modal": "^3.14.3",
|
||||
"react-number-format": "^4.7.3",
|
||||
"react-particles-js": "^3.5.3",
|
||||
"react-redux": "^7.2.4",
|
||||
"react-router-dom": "^5.2.0",
|
||||
|
@ -1,3 +1,5 @@
|
||||
import './home-page.scoped.css';
|
||||
|
||||
import { Link } from 'react-router-dom';
|
||||
import Navbar from '../navigation/navbar';
|
||||
import PageWrapper from './page-wrapper';
|
||||
@ -6,10 +8,19 @@ import Chat from '../../assets/home/chat.svg';
|
||||
import Devices from '../../assets/home/devices.svg';
|
||||
import Friends from '../../assets/home/friends.svg';
|
||||
import Secure from '../../assets/home/secure.svg';
|
||||
|
||||
import './home-page.scoped.css';
|
||||
import { useEffect } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { countUsers } from '../../store/users';
|
||||
import NumberFormat from 'react-number-format';
|
||||
|
||||
const HomePage: React.FunctionComponent = () => {
|
||||
const dispatch = useDispatch();
|
||||
const userCount = useSelector((s: Store.AppState) => s.meta.userCount);
|
||||
|
||||
useEffect(() => {
|
||||
setTimeout(() => dispatch(countUsers()), 1000);
|
||||
}, []);
|
||||
|
||||
const ImageCard = (props: { title: string, src: any }) => (
|
||||
<div>
|
||||
<h3 className="text-center text-1xl font-black font mb-4">{props.title}</h3>
|
||||
@ -37,7 +48,16 @@ const HomePage: React.FunctionComponent = () => {
|
||||
<h1>It's time to ditch Discord and Zoom.</h1>
|
||||
<div className="flex justify-center">
|
||||
<div className="lead font-light mt-2 max-w-xl">
|
||||
All-in-one guild and text chat for you that's free, secure, and works on both your desktop and phone. Stop paying for Discord guild boosts and hassling with Zoom. Simplify your life.
|
||||
All-in-one text and voice chat, just like Discord.
|
||||
Stop paying for Discord boosts and hassling with Zoom.
|
||||
{userCount && (
|
||||
<span className="pl-1">
|
||||
Join <NumberFormat
|
||||
value={userCount}
|
||||
displayType={'text'}
|
||||
thousandSeparator={true}/> Accord users that simplified their life.
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<button className="font-primary shadow-md bg-green text-dark">
|
||||
|
@ -5,11 +5,13 @@ const slice = createSlice({
|
||||
initialState: {
|
||||
fetchedEntities: false,
|
||||
hasListenedToWS: false,
|
||||
userCount: NaN,
|
||||
} as Store.AppState['meta'],
|
||||
reducers: {
|
||||
fetchedEntities: (meta) => { meta.fetchedEntities = true },
|
||||
listenedToWS: (meta) => { meta.hasListenedToWS = true },
|
||||
ping: (meta, { payload }) => { meta.ping = payload },
|
||||
updatedUserCount: (meta, { payload }) => { meta.userCount = payload },
|
||||
}
|
||||
});
|
||||
export const actions = slice.actions;
|
||||
|
@ -28,7 +28,7 @@ export default store => next => async action => {
|
||||
callback && callback(payload);
|
||||
} catch (error) {
|
||||
const response = (error as any).response;
|
||||
store.dispatch(actions.restCallFailed(response));
|
||||
store.dispatch(actions.restCallFailed({ url, response }));
|
||||
store.dispatch(openDialog({
|
||||
content: response?.data?.message ?? 'Unknown Error',
|
||||
variant: 'error',
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { createSlice, createSelector } from '@reduxjs/toolkit';
|
||||
import { WS } from '../types/ws';
|
||||
import { actions as api } from './api';
|
||||
import { actions as meta } from './meta';
|
||||
import { unique } from './utils/filter';
|
||||
import { token } from './utils/rest-headers';
|
||||
|
||||
@ -58,6 +59,13 @@ export const deleteSelf = () => (dispatch) => {
|
||||
}));
|
||||
}
|
||||
|
||||
export const countUsers = () => (dispatch) => {
|
||||
dispatch(api.restCallBegan({
|
||||
onSuccess: [meta.updatedUserCount.type],
|
||||
url: '/users/count',
|
||||
}));
|
||||
}
|
||||
|
||||
export const getUser = (id: string) =>
|
||||
createSelector<Store.AppState, Entity.User[], Entity.User>(
|
||||
state => state.entities.users,
|
||||
|
1
types/store.d.ts
vendored
1
types/store.d.ts
vendored
@ -33,6 +33,7 @@ declare namespace Store {
|
||||
fetchedEntities: boolean;
|
||||
hasListenedToWS: boolean;
|
||||
ping?: number;
|
||||
userCount?: number;
|
||||
};
|
||||
ui: {
|
||||
openDropdown?: string;
|
||||
|
Loading…
x
Reference in New Issue
Block a user