-
Messages
-
- {messages?.map(message => (
-
-
{message.username}
-
{message.text}
-
- ))}
+ useEffect(() => {
+ messagesEndRef?.current?.scrollIntoView({
+ block: "end",
+ behavior: "smooth",
+ });
+ });
+
+ const showMessages = messages?.map(message => {
+ let color = getRandomColor();
+ return (
+
+
+
{message.username}
+
+ {new Date(message.added).toLocaleDateString("default", {
+ year: "numeric",
+ month: "2-digit",
+ day: "2-digit",
+ hour: "2-digit",
+ minute: "2-digit",
+ })}
+
-
- )
-}
+
+ {message.text}
+
+
+ );
+ });
+
+ return (
+
+ {!!messages && (
+
+ {!last && (
+
+
+
+ )}
+ {showMessages}
+
+ )}
+
+ );
+};
+
+const StyledBoard = styled.main`
+
+ .loader {
+ min-height: 3rem;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+
+ .height{
+ height: 100%;
+ }
+
+ .messages-section {
+ height: 100%;
+ padding: 0.5rem 1rem;
+ overflow-y: hidden;
+ }
+ h3 {
+ padding-bottom: 0.5rem;
+ }
+ .message {
+ color: #363f4d;
+ padding: 18px 20px;
+ line-height: 26px;
+ font-size: 16px;
+ border-radius: 7px;
+ margin-bottom: 30px;
+ width: fit-content;
+ max-width: 100%;
+ position: relative;
+ white-space: initial;
+ border: none;
+
+ &::after {
+ content: "";
+ bottom: 98%;
+ left: 0.7rem;
+ border: solid transparent;
+ content: " ";
+ height: 0;
+ width: 0;
+ position: absolute;
+ pointer-events: none;
+ border-bottom-color: inherit;
+ border-width: 7px;
+ margin-left: -7px;
+ }
+ }
+ .message-header {
+ display: flex;
+ p {
+ flex: 1;
+ text-align: end;
+ padding-left: 0.5rem;
+ opacity: 0.4;
+ }
+ }
+ .messages-animate {
+ -webkit-animation: slide-top 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
+ animation: slide-top 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
+ }
+ @-webkit-keyframes slide-top {
+ 0% {
+ -webkit-transform: translateY(100px);
+ transform: translateY(100px);
+ }
+ 100% {
+ -webkit-transform: translateY(0px);
+ transform: translateY(0px);
+ }
+ }
+ @keyframes slide-top {
+ 0% {
+ -webkit-transform: translateY(100px);
+ transform: translateY(100px);
+ }
+ 100% {
+ -webkit-transform: translateY(0px);
+ transform: translateY(0px);
+ }
+ }
+`;
-export default Board
\ No newline at end of file
+export default Board;
diff --git a/client/src/components/Button.tsx b/client/src/components/Button.tsx
new file mode 100644
index 0000000..276c1b7
--- /dev/null
+++ b/client/src/components/Button.tsx
@@ -0,0 +1,55 @@
+import styled from "styled-components";
+
+type ButtonProps = {
+ type: "button" | "submit" | "reset" | undefined;
+ disabled: boolean | undefined;
+};
+
+const Button = ({ type, disabled }: ButtonProps) => {
+ return (
+
+
+
+
+
+ );
+};
+
+const StyledButton = styled.button`
+ background: none;
+ border: none;
+ padding: 20px 20px;
+ border-radius: 0 8px 8px 0;
+ background-color: #f8f8f8;
+ cursor: pointer;
+ transition: 0.5s all ease-out;
+
+ &:hover {
+ background: #ffffff;
+ box-shadow: 10px 10px 20px #ededed, -10px -10px 20px #ffffff;
+ }
+ & svg {
+ fill: var(--dark);
+ }
+
+ &:hover svg {
+ fill: #504464;
+ }
+
+ &:disabled {
+ background: linear-gradient(145deg, #f0efef, #ffffff);
+ box-shadow: 6px 6px 12px #f3f3f3, -6px -6px 12px #f1eded;
+ }
+
+ &:disabled svg {
+ cursor: wait;
+ fill: #cac9c9;
+ }
+`;
+
+export default Button;
diff --git a/client/src/components/Card.tsx b/client/src/components/Card.tsx
new file mode 100644
index 0000000..1ea15a0
--- /dev/null
+++ b/client/src/components/Card.tsx
@@ -0,0 +1,107 @@
+import styled from "styled-components";
+
+type Cardprops = {
+ children: JSX.Element | JSX.Element[];
+};
+
+const Card = ({ children }: Cardprops) => {
+ return (
+
+
+
+ {children}
+
+ );
+};
+
+const StyledCard = styled.div`
+ width: 95vw;
+ height: 90vh;
+ position: relative;
+ margin: 0 auto;
+ background-color: var(--white);
+ border-radius: 8px;
+ z-index: 1;
+ box-shadow: rgba(50, 50, 93, 0.25) 0px 6px 12px -2px,
+ rgba(0, 0, 0, 0.3) 0px 3px 7px -3px;
+
+ .tools {
+ position: absolute;
+ border-radius: 8px 8px 0 0;
+ background: #2f283b;
+ width: 100%;
+ display: flex;
+ align-items: center;
+ padding: 9px;
+ .circle {
+ padding: 0 4px;
+ }
+
+ .box {
+ display: inline-block;
+ align-items: center;
+ width: 10px;
+ height: 10px;
+ padding: 1px;
+ border-radius: 50%;
+ }
+
+ .red {
+ background-color: #ff605c;
+ }
+
+ .yellow {
+ background-color: #ffbd44;
+ }
+
+ .green {
+ background-color: #00ca4e;
+ }
+ }
+ .attribution {
+ position: absolute;
+ top: 9px;
+ left: 50%;
+ transform: translateX(-50%);
+ color: #aaa2c9;
+ a {
+ padding-left: .2rem;
+ text-decoration: none;
+ color: #dab3b4;
+ }
+ }
+
+ .card__content {
+ padding: 2.5rem 9px 9px;
+ height: 100%;
+ border-radius: 8px;
+ }
+
+ @media (min-width: 900px) {
+ width: 50vw;
+ }
+`;
+
+export default Card;
diff --git a/client/src/components/Emoji.tsx b/client/src/components/Emoji.tsx
new file mode 100644
index 0000000..972579f
--- /dev/null
+++ b/client/src/components/Emoji.tsx
@@ -0,0 +1,63 @@
+import { useRef, useState } from "react";
+import EmojiPicker from "emoji-picker-react";
+import styled from "styled-components";
+import { useOnClickOutside } from "../hooks/useOnClickOutside";
+import { FormikState, useFormikContext } from "formik";
+import { MessageForm } from "../types/messageType";
+
+type EmojiProp = {
+ setEmoji: React.Dispatch
>
+}
+
+const Emoji = ({setEmoji}:EmojiProp) => {
+ const { values , resetForm} = useFormikContext();
+
+ const [isPickerVisible, setIsPickerVisible] = useState(false);
+ const emojiPickerRef = useRef(null);
+
+ const handlePicker = ()=> setIsPickerVisible(!isPickerVisible);
+
+ useOnClickOutside(emojiPickerRef, () => handlePicker());
+
+
+ return (
+
+ {isPickerVisible && (
+
+ {
+ setEmoji(e.emoji)
+ handlePicker()
+ }}
+ />
+
+ )}
+ handlePicker()}>
+
+
+
+ );
+};
+
+const StyledEmoji = styled.div`
+ position: relative;
+ width: 45px;
+ .picker {
+ z-index: 11;
+ bottom: 1rem;
+ position: absolute;
+ }
+ button{
+ border: none;
+ height: 100%;
+ width: 100%;
+ border-radius: 8px 0 0 8px;
+ font-size: 1.5rem;
+ background: #f8f8f8;
+ }
+ button:hover{
+ background: #e4e3e3;
+ }
+`;
+
+export default Emoji;
diff --git a/client/src/components/Input.tsx b/client/src/components/Input.tsx
new file mode 100644
index 0000000..b45d36b
--- /dev/null
+++ b/client/src/components/Input.tsx
@@ -0,0 +1,86 @@
+import { Field } from "formik";
+import styled from "styled-components";
+
+type InputProps = {
+ id: string;
+ name: string;
+ placeholder: string;
+ className?: string;
+};
+
+const Input = ({ id, name, placeholder, className="" }: InputProps) => {
+ return (
+
+
+
+
+ );
+};
+
+const StyledInput = styled.div`
+ --width-of-input: 100%;
+ --border-height: 1px;
+ --border-before-color: rgba(221, 221, 221, 0.39);
+ --border-after-color: #434b5c;
+ --input-hovered-color: #6062641f;
+ position: relative;
+ width: var(--width-of-input);
+
+ &.error::after{
+ content: 'Required';
+ position: absolute;
+ right: .5rem;
+ top: 50%;
+ transform: translateY(-50%);
+ color: salmon;
+ opacity: .7;
+ }
+
+ /* styling of Input */
+ .input {
+ color: var(--dark);
+ font-size: 0.9rem;
+ background-color: transparent;
+ width: 100%;
+ box-sizing: border-box;
+ padding-inline: 0.5em;
+ padding-block: 0.7em;
+ border: none;
+ border-bottom: var(--border-height) solid var(--border-before-color);
+ }
+ .input.error{
+ border-bottom: var(--border-height) solid salmon;
+ }
+ .input.error::after{
+ content: 'd';
+ }
+ /* styling of animated border */
+ .input-border {
+ position: absolute;
+ background: var(--border-after-color);
+ width: 0%;
+ height: 2px;
+ bottom: 0;
+ left: 0;
+ transition: 0.3s;
+ }
+ /* Hover on Input */
+ input:hover {
+ background: var(--input-hovered-color);
+ }
+
+ input:focus {
+ outline: none;
+ }
+ /* here is code of animated border */
+ input:focus ~ .input-border {
+ width: 100%;
+ }
+`;
+
+export default Input;
diff --git a/client/src/components/Loading.tsx b/client/src/components/Loading.tsx
new file mode 100644
index 0000000..d6aba9c
--- /dev/null
+++ b/client/src/components/Loading.tsx
@@ -0,0 +1,108 @@
+import React from "react";
+import styled from "styled-components";
+
+
+const Loading = () => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+const StyledLoading = styled.div`
+ .jelly {
+ --uib-size: 40px;
+ --uib-speed: 0.8s;
+ --uib-color: #2c2b2b;
+ position: relative;
+ height: calc(var(--uib-size) / 2);
+ width: var(--uib-size);
+ filter: url("#uib-jelly-ooze");
+ animation: rotate72317 calc(var(--uib-speed) * 2) linear infinite;
+ }
+
+ .jelly::before,
+ .jelly::after {
+ content: "";
+ position: absolute;
+ top: 0%;
+ left: 25%;
+ width: 50%;
+ height: 100%;
+ background: var(--uib-color);
+ border-radius: 100%;
+ }
+
+ .jelly::before {
+ animation: shift-left var(--uib-speed) ease infinite;
+ }
+
+ .jelly::after {
+ animation: shift-right var(--uib-speed) ease infinite;
+ }
+
+ .jelly-maker {
+ width: 0;
+ height: 0;
+ position: absolute;
+ }
+
+ @keyframes rotate72317 {
+ 0%,
+ 49.999%,
+ 100% {
+ transform: none;
+ }
+
+ 50%,
+ 99.999% {
+ transform: rotate(90deg);
+ }
+ }
+
+ @keyframes shift-left {
+ 0%,
+ 100% {
+ transform: translateX(0%);
+ }
+
+ 50% {
+ transform: scale(0.65) translateX(-75%);
+ }
+ }
+
+ @keyframes shift-right {
+ 0%,
+ 100% {
+ transform: translateX(0%);
+ }
+
+ 50% {
+ transform: scale(0.65) translateX(75%);
+ }
+ }
+`;
+
+export default Loading;
diff --git a/client/src/components/SendMessage.tsx b/client/src/components/SendMessage.tsx
new file mode 100644
index 0000000..24cbbd1
--- /dev/null
+++ b/client/src/components/SendMessage.tsx
@@ -0,0 +1,104 @@
+import EmojiPicker from "emoji-picker-react";
+import { Formik, Field, Form } from "formik";
+import { FormikHelpers } from "formik/dist/types";
+import { useEffect, useRef, useState } from "react";
+import styled from "styled-components";
+import { createMessage } from "../service/message";
+import { Message, MessageForm } from "../types/messageType";
+import Button from "./Button";
+import Emoji from "./Emoji";
+import Input from "./Input";
+
+type FormValues = {
+ username: string;
+ text: string;
+};
+
+type SendMessageProps = {
+ setMessages: React.Dispatch>;
+};
+
+const SendMessage = ({ setMessages }: SendMessageProps) => {
+ const initialValues: FormValues = { username: "", text: "" };
+
+ const handleSubmit = async (
+ values: FormValues,
+ actions: FormikHelpers
+ ) => {
+ await createMessage(values)
+ .then(res => {
+ console.log(res);
+ setMessages(m => [...m!, res.messageDB]);
+ })
+ .catch(err => console.log(err))
+ .finally(()=>{
+ actions.resetForm()
+ })
+ };
+
+ return (
+
+
+ initialValues={initialValues}
+ validate={values => {
+ const errors: { username?: string; text?: string } = {};
+
+ if (!values.username) {
+ errors.username = "Required";
+ }
+
+ if (!values.text) {
+ errors.text = "Required";
+ }
+
+ return errors;
+ }}
+ onSubmit={handleSubmit}>
+ {({ isSubmitting, errors, setFieldValue, values}) => {
+ const [emoji, setEmoji] = useState('');
+
+ useEffect(() => {
+ setFieldValue('text', values.text.concat(emoji) , false);
+ }, [emoji]);
+
+ return (
+
+ );
+ }}
+
+
+ );
+};
+
+const StyledSendMessage = styled.div`
+ padding: 1rem 0;
+ form {
+ display: flex;
+ }
+ .inputs {
+ flex: 1;
+ }
+`;
+
+export default SendMessage;
diff --git a/client/src/components/SvgPattern.tsx b/client/src/components/SvgPattern.tsx
new file mode 100644
index 0000000..464b463
--- /dev/null
+++ b/client/src/components/SvgPattern.tsx
@@ -0,0 +1,26 @@
+type SvgPatternProps = {
+ className?: string;
+};
+
+const SvgPattern = ({ className = "" }: SvgPatternProps) => {
+ return (
+
+ );
+};
+
+export default SvgPattern;
diff --git a/client/src/hooks/useInfiniteScroll.ts b/client/src/hooks/useInfiniteScroll.ts
new file mode 100644
index 0000000..4876d58
--- /dev/null
+++ b/client/src/hooks/useInfiniteScroll.ts
@@ -0,0 +1,29 @@
+import { useState, useCallback, useEffect, useRef } from 'react';
+
+export const useInfiniteScroll = () => {
+ const [skip, setSkip] = useState(0);
+ const loadMoreRef = useRef(null);
+
+ const handleObserver = useCallback((entries:any) => {
+ const [target] = entries;
+ if (target.isIntersecting) {
+ setSkip(a => a + 10);
+ }
+ }, []);
+
+ useEffect(() => {
+ const option = {
+ root: null,
+ rootMargin: '0px',
+ threshold: 1.0,
+ };
+
+ const observer = new IntersectionObserver(handleObserver, option);
+
+ if (loadMoreRef.current) observer.observe(loadMoreRef.current);
+ }, [handleObserver]);
+
+ return { loadMoreRef, skip };
+ }
+
+ export default useInfiniteScroll;
\ No newline at end of file
diff --git a/client/src/hooks/useOnClickOutside.ts b/client/src/hooks/useOnClickOutside.ts
new file mode 100644
index 0000000..77ac4f4
--- /dev/null
+++ b/client/src/hooks/useOnClickOutside.ts
@@ -0,0 +1,22 @@
+import { useEffect } from 'react';
+
+
+export function useOnClickOutside(
+ ref: React.RefObject,
+ handler: () => void
+) {
+ useEffect(() => {
+ const listener = (event: any) => {
+ if (!ref.current || ref.current.contains(event.target)) {
+ return;
+ }
+ handler();
+ };
+ document.addEventListener("mousedown", listener);
+ document.addEventListener("touchstart", listener);
+ return () => {
+ document.removeEventListener("mousedown", listener);
+ document.removeEventListener("touchstart", listener);
+ };
+ }, [ref, handler]);
+}
\ No newline at end of file
diff --git a/client/src/service/message.ts b/client/src/service/message.ts
index 34abf48..f2650d3 100644
--- a/client/src/service/message.ts
+++ b/client/src/service/message.ts
@@ -1,8 +1,31 @@
import { Message } from "../types/messageType";
-export const getMessage = async() => {
- const res = await fetch('https://mini-message-board-server.onrender.com/new');
- const data = await res.json();
-
+export const getMessage = async (since?: number) => {
+ console.log(since);
+
+ const res = await fetch(`${import.meta.env.VITE_SERVER}${since ? `/?since=${since}`:''}`);
+ const data = await res.json();
+
return [...data.messages] as Message[]
}
+
+export const createMessage = async (data: Omit) => {
+
+ try {
+ const res = await fetch(import.meta.env.VITE_SERVER, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify(data)
+ });
+ const json = await res.json();
+
+ return json;
+ } catch (error) {
+
+ alert('server not')
+ }
+}
+
+
diff --git a/client/src/theme/GlobalStyle.tsx b/client/src/theme/GlobalStyle.tsx
index b9ee507..39859dc 100644
--- a/client/src/theme/GlobalStyle.tsx
+++ b/client/src/theme/GlobalStyle.tsx
@@ -1,22 +1,71 @@
import { createGlobalStyle } from "styled-components";
-
+export const palette = ["#FACCAA", "#A1BCE7", "#9ED9B3", "#DAB3B4", "#AAA2C9"];
export const GlobalStyle = createGlobalStyle`
+ :root{
+ --white-bg: #F2F3F7;
+ --white: #FFFFFF;
+ --dark: #2F283B;
+ --thumb-bg: #d2d2e0;
+ }
+
+ ::-webkit-scrollbar {
+ width: 5px;
+ height: 5px;
+ }
+
+ ::-webkit-scrollbar-thumb {
+ background: var(--thumb-bg);
+ border-radius: var(--radius);
+ }
+
+ ::-webkit-scrollbar-thumb:active,
+ ::-webkit-scrollbar-thumb:hover {
+ background: var(--dark);
+ }
+
+ ::-webkit-scrollbar-track {
+ background: #80808014;
+ }
- * {
- box-sizing: border-box;
- line-height: normal;
- }
-
- body {
- height: 100vh;
- overflow-x: hidden;
- -webkit-text-size-adjust: 100%;
- -webkit-font-smoothing: antialiased;
- font-family: 'Outfit', sans-serif;
- font-size: 14px;
- line-height: 17.64px;
- }
+ * {
+ padding: 0;
+ margin: 0;
+ box-sizing: border-box;
+ line-height: normal;
+ }
+
+ body {
+ min-height: 100vh;
+ overflow-x: hidden;
+ -webkit-text-size-adjust: 100%;
+ -webkit-font-smoothing: antialiased;
+ font-family: 'Outfit', sans-serif;
+ font-size: 14px;
+ line-height: 17.64px;
+ background-color: var(--white-bg);
+ font-family: 'Lato', sans-serif;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ position: relative;
+ }
+
+ h1,h2,h3,h4,h5,h6{
+ /* color: #6F718A; */
+ font-family: 'Syne', sans-serif;
+ }
+
+ .pattern{
+ position: absolute;
+ bottom: 5rem;
+ right: -6rem;
+ }
+ .pattern-2{
+ position: absolute;
+ top: -5rem;
+ left: -5rem;
+ }
-`;
\ No newline at end of file
+`;
diff --git a/client/src/types/messageType.ts b/client/src/types/messageType.ts
index 283bce9..d993bf5 100644
--- a/client/src/types/messageType.ts
+++ b/client/src/types/messageType.ts
@@ -4,3 +4,8 @@ export interface Message {
text: string,
added: string,
}
+
+export interface MessageForm {
+ username: string,
+ text: string,
+}
\ No newline at end of file
diff --git a/client/src/utils/getColor.ts b/client/src/utils/getColor.ts
new file mode 100644
index 0000000..1bf3d1d
--- /dev/null
+++ b/client/src/utils/getColor.ts
@@ -0,0 +1,6 @@
+import { palette } from "../theme/GlobalStyle"
+
+export const getRandomColor = () => {
+ const randomIndex = Math.floor(Math.random() * palette.length);
+ return palette[randomIndex];
+}
\ No newline at end of file
diff --git a/client/yarn.lock b/client/yarn.lock
index e4612f8..46c900e 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -493,6 +493,11 @@ chalk@^2.0.0:
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
+clsx@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12"
+ integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==
+
color-convert@^1.9.0:
version "1.9.3"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
@@ -546,6 +551,13 @@ electron-to-chromium@^1.4.251:
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz#61046d1e4cab3a25238f6bf7413795270f125592"
integrity sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==
+emoji-picker-react@^4.4.7:
+ version "4.4.7"
+ resolved "https://registry.yarnpkg.com/emoji-picker-react/-/emoji-picker-react-4.4.7.tgz#faff798cf7acad41c5eb6b103c93480e777f2222"
+ integrity sha512-HcB1Fr57W6M+gLLm/W4YhbAnUQqYBUAhZBOHmPlSQODLtsDI8vecyqNIF9RrStZHfZwzUSLlpZMfY07AA6gxmA==
+ dependencies:
+ clsx "^1.2.1"
+
esbuild@^0.16.3:
version "0.16.7"
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.16.7.tgz#3288f685a83c6097dea8ddf1759ca30d6e06535b"
diff --git a/screenshot.png b/screenshot.png
new file mode 100644
index 0000000..bba1f9e
Binary files /dev/null and b/screenshot.png differ
diff --git a/server/controllers/new.ts b/server/controllers/new.ts
index eacc79d..e710cc0 100644
--- a/server/controllers/new.ts
+++ b/server/controllers/new.ts
@@ -4,8 +4,9 @@ import Message from '../models/message'
export const getMessages = async (req: Request, res: Response) => {
const { limit = 10, since = 0 } = req.query;
-
+
const messages = await Message.find()
+ .sort({$natural:-1})
.skip(Number(since))
.limit(Number(limit))
diff --git a/server/models/server.ts b/server/models/server.ts
index 8a91fde..f286fb9 100644
--- a/server/models/server.ts
+++ b/server/models/server.ts
@@ -1,5 +1,6 @@
import express, { Application } from 'express';
import cors from 'cors';
+import morgan from 'morgan'
import newRouter from '../routes/new';
import { dbConnection } from '../database/config';
@@ -29,6 +30,7 @@ class Server {
middlewares() {
this.app.use(express.json());
this.app.use(cors())
+ this.app.use(morgan('dev'))
}
routes(){
diff --git a/server/package.json b/server/package.json
index 39dda12..d56bfbc 100644
--- a/server/package.json
+++ b/server/package.json
@@ -7,6 +7,7 @@
"scripts": {
"build": "tsc",
"start": " node dist/app.js",
+ "dev": "nodemon app.ts",
"deploy": "yarn build && yarn start"
},
"dependencies": {
@@ -16,10 +17,13 @@
"express": "^4.18.2",
"express-validator": "^6.14.2",
"mongoose": "^6.8.0",
+ "morgan": "^1.10.0",
"tslint": "^6.1.3",
"typescript": "^4.9.4"
},
"devDependencies": {
- "@types/cors": "^2.8.13"
+ "@types/cors": "^2.8.13",
+ "@types/morgan": "^1.9.4",
+ "ts-node": "^10.9.1"
}
}
diff --git a/server/routes/new.ts b/server/routes/new.ts
index b33f0e2..1b93433 100644
--- a/server/routes/new.ts
+++ b/server/routes/new.ts
@@ -8,8 +8,8 @@ const router = Router();
router.get('/',getMessages);
router.post('/',[
- check('username', 'Username is requires').exists(),
- check('text', 'Text is requires').exists(),
+ check('username', 'Username is requires').not().isEmpty(),
+ check('text', 'Text is requires').not().isEmpty(),
validateFields
],newMessage);
diff --git a/server/yarn.lock b/server/yarn.lock
index 4032e27..036172c 100644
--- a/server/yarn.lock
+++ b/server/yarn.lock
@@ -767,6 +767,51 @@
chalk "^2.0.0"
js-tokens "^4.0.0"
+"@cspotcode/source-map-support@^0.8.0":
+ version "0.8.1"
+ resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1"
+ integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==
+ dependencies:
+ "@jridgewell/trace-mapping" "0.3.9"
+
+"@jridgewell/resolve-uri@^3.0.3":
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78"
+ integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==
+
+"@jridgewell/sourcemap-codec@^1.4.10":
+ version "1.4.14"
+ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24"
+ integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==
+
+"@jridgewell/trace-mapping@0.3.9":
+ version "0.3.9"
+ resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9"
+ integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==
+ dependencies:
+ "@jridgewell/resolve-uri" "^3.0.3"
+ "@jridgewell/sourcemap-codec" "^1.4.10"
+
+"@tsconfig/node10@^1.0.7":
+ version "1.0.9"
+ resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2"
+ integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==
+
+"@tsconfig/node12@^1.0.7":
+ version "1.0.11"
+ resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d"
+ integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==
+
+"@tsconfig/node14@^1.0.0":
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1"
+ integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==
+
+"@tsconfig/node16@^1.0.2":
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e"
+ integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==
+
"@types/body-parser@*":
version "1.19.2"
resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0"
@@ -813,6 +858,13 @@
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10"
integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==
+"@types/morgan@^1.9.4":
+ version "1.9.4"
+ resolved "https://registry.yarnpkg.com/@types/morgan/-/morgan-1.9.4.tgz#99965ad2bdc7c5cee28d8ce95cfa7300b19ea562"
+ integrity sha512-cXoc4k+6+YAllH3ZHmx4hf7La1dzUk6keTR4bF4b4Sc0mZxU/zK4wO7l+ZzezXm/jkYj/qC+uYGZrarZdIVvyQ==
+ dependencies:
+ "@types/node" "*"
+
"@types/node@*":
version "18.11.16"
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.16.tgz#966cae211e970199559cfbd295888fca189e49af"
@@ -857,6 +909,16 @@ accepts@~1.3.8:
mime-types "~2.1.34"
negotiator "0.6.3"
+acorn-walk@^8.1.1:
+ version "8.2.0"
+ resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1"
+ integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==
+
+acorn@^8.4.1:
+ version "8.8.2"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a"
+ integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==
+
ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
@@ -864,6 +926,11 @@ ansi-styles@^3.2.1:
dependencies:
color-convert "^1.9.0"
+arg@^4.1.0:
+ version "4.1.3"
+ resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
+ integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
+
argparse@^1.0.7:
version "1.0.10"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
@@ -886,6 +953,13 @@ base64-js@^1.3.1:
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
+basic-auth@~2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-2.0.1.tgz#b998279bf47ce38344b4f3cf916d4679bbf51e3a"
+ integrity sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==
+ dependencies:
+ safe-buffer "5.1.2"
+
body-parser@1.20.1:
version "1.20.1"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668"
@@ -1011,6 +1085,11 @@ cors@^2.8.5:
object-assign "^4"
vary "^1"
+create-require@^1.1.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
+ integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
+
debug@2.6.9:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
@@ -1025,7 +1104,7 @@ debug@4.x:
dependencies:
ms "2.1.2"
-depd@2.0.0:
+depd@2.0.0, depd@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
@@ -1274,6 +1353,11 @@ lodash@^4.17.21:
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
+make-error@^1.1.1:
+ version "1.3.6"
+ resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
+ integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
+
media-typer@0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
@@ -1363,6 +1447,17 @@ mongoose@^6.8.0:
ms "2.1.3"
sift "16.0.1"
+morgan@^1.10.0:
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.10.0.tgz#091778abc1fc47cd3509824653dae1faab6b17d7"
+ integrity sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==
+ dependencies:
+ basic-auth "~2.0.1"
+ debug "2.6.9"
+ depd "~2.0.0"
+ on-finished "~2.3.0"
+ on-headers "~1.0.2"
+
mpath@0.9.0:
version "0.9.0"
resolved "https://registry.yarnpkg.com/mpath/-/mpath-0.9.0.tgz#0c122fe107846e31fc58c75b09c35514b3871904"
@@ -1412,6 +1507,18 @@ on-finished@2.4.1:
dependencies:
ee-first "1.1.1"
+on-finished@~2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
+ integrity sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==
+ dependencies:
+ ee-first "1.1.1"
+
+on-headers@~1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f"
+ integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==
+
once@^1.3.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
@@ -1483,6 +1590,11 @@ resolve@^1.3.2:
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
+safe-buffer@5.1.2:
+ version "5.1.2"
+ resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
+ integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
+
safe-buffer@5.2.1:
version "5.2.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
@@ -1612,6 +1724,25 @@ tr46@^3.0.0:
dependencies:
punycode "^2.1.1"
+ts-node@^10.9.1:
+ version "10.9.1"
+ resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b"
+ integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==
+ dependencies:
+ "@cspotcode/source-map-support" "^0.8.0"
+ "@tsconfig/node10" "^1.0.7"
+ "@tsconfig/node12" "^1.0.7"
+ "@tsconfig/node14" "^1.0.0"
+ "@tsconfig/node16" "^1.0.2"
+ acorn "^8.4.1"
+ acorn-walk "^8.1.1"
+ arg "^4.1.0"
+ create-require "^1.1.0"
+ diff "^4.0.1"
+ make-error "^1.1.1"
+ v8-compile-cache-lib "^3.0.1"
+ yn "3.1.1"
+
tslib@^1.11.1, tslib@^1.13.0, tslib@^1.8.1:
version "1.14.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
@@ -1676,6 +1807,11 @@ uuid@^8.3.2:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
+v8-compile-cache-lib@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
+ integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==
+
validator@^13.7.0:
version "13.7.0"
resolved "https://registry.yarnpkg.com/validator/-/validator-13.7.0.tgz#4f9658ba13ba8f3d82ee881d3516489ea85c0857"
@@ -1703,3 +1839,8 @@ wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
+
+yn@3.1.1:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
+ integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==