diff --git a/code/.eslintrc.json b/code/.eslintrc.json
index c9c0675c3..3905eed2b 100644
--- a/code/.eslintrc.json
+++ b/code/.eslintrc.json
@@ -26,6 +26,7 @@
"react-hooks"
],
"rules": {
+ "linebreak-style": 0,
"react/function-component-definition": [
2,
{
diff --git a/code/package-lock.json b/code/package-lock.json
index f7e97e1e9..10f28e25d 100644
--- a/code/package-lock.json
+++ b/code/package-lock.json
@@ -9,14 +9,18 @@
"version": "1.0.0",
"dependencies": {
"babel-eslint": "^10.1.0",
+ "date-fns": "^2.29.3",
"eslint": "^8.21.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsx-a11y": "^6.6.1",
"eslint-plugin-react": "^7.30.1",
"eslint-plugin-react-hooks": "^4.6.0",
+ "javascript-time-ago": "^2.5.9",
"react": "^18.2.0",
- "react-dom": "^18.2.0"
+ "react-confetti": "^6.1.0",
+ "react-dom": "^18.2.0",
+ "react-time-ago": "^7.2.1"
},
"devDependencies": {
"react-scripts": "5.0.1"
@@ -6205,6 +6209,18 @@
"node": ">=10"
}
},
+ "node_modules/date-fns": {
+ "version": "2.29.3",
+ "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz",
+ "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==",
+ "engines": {
+ "node": ">=0.11"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/date-fns"
+ }
+ },
"node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -9539,6 +9555,14 @@
"node": ">=8"
}
},
+ "node_modules/javascript-time-ago": {
+ "version": "2.5.9",
+ "resolved": "https://registry.npmjs.org/javascript-time-ago/-/javascript-time-ago-2.5.9.tgz",
+ "integrity": "sha512-pQ8mNco/9g9TqWXWWjP0EWl6i/lAQScOyEeXy5AB+f7MfLSdgyV9BJhiOD1zrIac/lrxPYOWNbyl/IW8CW5n0A==",
+ "dependencies": {
+ "relative-time-format": "^1.1.6"
+ }
+ },
"node_modules/jest": {
"version": "27.5.1",
"resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz",
@@ -11966,6 +11990,11 @@
"node": ">= 4.0.0"
}
},
+ "node_modules/memoize-one": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
+ "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
+ },
"node_modules/merge-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
@@ -12682,8 +12711,7 @@
"node_modules/performance-now": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
- "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==",
- "dev": true
+ "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow=="
},
"node_modules/picocolors": {
"version": "1.0.0",
@@ -14306,7 +14334,6 @@
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz",
"integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==",
- "dev": true,
"dependencies": {
"performance-now": "^2.1.0"
}
@@ -14393,6 +14420,20 @@
"node": ">=14"
}
},
+ "node_modules/react-confetti": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/react-confetti/-/react-confetti-6.1.0.tgz",
+ "integrity": "sha512-7Ypx4vz0+g8ECVxr88W9zhcQpbeujJAVqL14ZnXJ3I23mOI9/oBVTQ3dkJhUmB0D6XOtCZEM6N0Gm9PMngkORw==",
+ "dependencies": {
+ "tween-functions": "^1.2.0"
+ },
+ "engines": {
+ "node": ">=10.18"
+ },
+ "peerDependencies": {
+ "react": "^16.3.0 || ^17.0.1 || ^18.0.0"
+ }
+ },
"node_modules/react-dev-utils": {
"version": "12.0.1",
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz",
@@ -14639,6 +14680,21 @@
"node": ">=10"
}
},
+ "node_modules/react-time-ago": {
+ "version": "7.2.1",
+ "resolved": "https://registry.npmjs.org/react-time-ago/-/react-time-ago-7.2.1.tgz",
+ "integrity": "sha512-X5zwJDZHa1fsMwMvh8mrHN31g85s84zMCp+d7YL6IX50kNnr6YMAS2wpt1BmO9OxBV2Ue5J1ptD6JI8Zjd35HA==",
+ "dependencies": {
+ "memoize-one": "^6.0.0",
+ "prop-types": "^15.8.1",
+ "raf": "^3.4.1"
+ },
+ "peerDependencies": {
+ "javascript-time-ago": "^2.3.7",
+ "react": ">=0.16.8",
+ "react-dom": ">=0.16.8"
+ }
+ },
"node_modules/read-cache": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
@@ -14816,6 +14872,11 @@
"node": ">= 0.10"
}
},
+ "node_modules/relative-time-format": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/relative-time-format/-/relative-time-format-1.1.6.tgz",
+ "integrity": "sha512-aCv3juQw4hT1/P/OrVltKWLlp15eW1GRcwP1XdxHrPdZE9MtgqFpegjnTjLhi2m2WI9MT/hQQtE+tjEWG1hgkQ=="
+ },
"node_modules/renderkid": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz",
@@ -16301,6 +16362,11 @@
"typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta"
}
},
+ "node_modules/tween-functions": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/tween-functions/-/tween-functions-1.2.0.tgz",
+ "integrity": "sha512-PZBtLYcCLtEcjL14Fzb1gSxPBeL7nWvGhO5ZFPGqziCcr8uvHp0NDmdjBchp6KHL+tExcg0m3NISmKxhU394dA=="
+ },
"node_modules/type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@@ -21996,6 +22062,11 @@
"whatwg-url": "^8.0.0"
}
},
+ "date-fns": {
+ "version": "2.29.3",
+ "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz",
+ "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA=="
+ },
"debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -24429,6 +24500,14 @@
}
}
},
+ "javascript-time-ago": {
+ "version": "2.5.9",
+ "resolved": "https://registry.npmjs.org/javascript-time-ago/-/javascript-time-ago-2.5.9.tgz",
+ "integrity": "sha512-pQ8mNco/9g9TqWXWWjP0EWl6i/lAQScOyEeXy5AB+f7MfLSdgyV9BJhiOD1zrIac/lrxPYOWNbyl/IW8CW5n0A==",
+ "requires": {
+ "relative-time-format": "^1.1.6"
+ }
+ },
"jest": {
"version": "27.5.1",
"resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz",
@@ -26264,6 +26343,11 @@
"fs-monkey": "^1.0.3"
}
},
+ "memoize-one": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
+ "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
+ },
"merge-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
@@ -26796,8 +26880,7 @@
"performance-now": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
- "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==",
- "dev": true
+ "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow=="
},
"picocolors": {
"version": "1.0.0",
@@ -27802,7 +27885,6 @@
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz",
"integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==",
- "dev": true,
"requires": {
"performance-now": "^2.1.0"
}
@@ -27873,6 +27955,14 @@
"whatwg-fetch": "^3.6.2"
}
},
+ "react-confetti": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/react-confetti/-/react-confetti-6.1.0.tgz",
+ "integrity": "sha512-7Ypx4vz0+g8ECVxr88W9zhcQpbeujJAVqL14ZnXJ3I23mOI9/oBVTQ3dkJhUmB0D6XOtCZEM6N0Gm9PMngkORw==",
+ "requires": {
+ "tween-functions": "^1.2.0"
+ }
+ },
"react-dev-utils": {
"version": "12.0.1",
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz",
@@ -28061,6 +28151,16 @@
}
}
},
+ "react-time-ago": {
+ "version": "7.2.1",
+ "resolved": "https://registry.npmjs.org/react-time-ago/-/react-time-ago-7.2.1.tgz",
+ "integrity": "sha512-X5zwJDZHa1fsMwMvh8mrHN31g85s84zMCp+d7YL6IX50kNnr6YMAS2wpt1BmO9OxBV2Ue5J1ptD6JI8Zjd35HA==",
+ "requires": {
+ "memoize-one": "^6.0.0",
+ "prop-types": "^15.8.1",
+ "raf": "^3.4.1"
+ }
+ },
"read-cache": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
@@ -28203,6 +28303,11 @@
"integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==",
"dev": true
},
+ "relative-time-format": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/relative-time-format/-/relative-time-format-1.1.6.tgz",
+ "integrity": "sha512-aCv3juQw4hT1/P/OrVltKWLlp15eW1GRcwP1XdxHrPdZE9MtgqFpegjnTjLhi2m2WI9MT/hQQtE+tjEWG1hgkQ=="
+ },
"renderkid": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz",
@@ -29331,6 +29436,11 @@
"tslib": "^1.8.1"
}
},
+ "tween-functions": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/tween-functions/-/tween-functions-1.2.0.tgz",
+ "integrity": "sha512-PZBtLYcCLtEcjL14Fzb1gSxPBeL7nWvGhO5ZFPGqziCcr8uvHp0NDmdjBchp6KHL+tExcg0m3NISmKxhU394dA=="
+ },
"type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
diff --git a/code/package.json b/code/package.json
index 68869f589..3cf2ac3bf 100644
--- a/code/package.json
+++ b/code/package.json
@@ -4,14 +4,18 @@
"private": true,
"dependencies": {
"babel-eslint": "^10.1.0",
+ "date-fns": "^2.29.3",
"eslint": "^8.21.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsx-a11y": "^6.6.1",
"eslint-plugin-react": "^7.30.1",
"eslint-plugin-react-hooks": "^4.6.0",
+ "javascript-time-ago": "^2.5.9",
"react": "^18.2.0",
- "react-dom": "^18.2.0"
+ "react-confetti": "^6.1.0",
+ "react-dom": "^18.2.0",
+ "react-time-ago": "^7.2.1"
},
"scripts": {
"start": "react-scripts start",
diff --git a/code/public/index.html b/code/public/index.html
index e6730aa66..dd30e6f4d 100644
--- a/code/public/index.html
+++ b/code/public/index.html
@@ -3,7 +3,8 @@
-
+
+
- Technigo React App
+ Giorgio happy thought's project
diff --git a/code/src/App.js b/code/src/App.js
index f2007d229..037753e47 100644
--- a/code/src/App.js
+++ b/code/src/App.js
@@ -1,9 +1,18 @@
import React from 'react';
+import Background from 'components/Background.js';
+import Header from 'components/Header.js';
+import Feed from 'components/Feed.js';
+import Footer from 'components/Footer.js';
export const App = () => {
return (
-
- Find me in src/app.js!
-
- );
-}
+ <>
+
+
+
+
+
+
+ >
+ )
+};
\ No newline at end of file
diff --git a/code/src/animations.css b/code/src/animations.css
new file mode 100644
index 000000000..d55aad1f8
--- /dev/null
+++ b/code/src/animations.css
@@ -0,0 +1,192 @@
+/* BACKGROUND */
+.smileys span {
+ position: fixed;
+ bottom: -80px;
+ animation: animate 10s linear infinite;
+ font-size: 60px;
+ z-index: -1;
+ }
+
+ .smileys span:nth-child(1){
+ left: 60px;
+ animation-delay: 0.6s;
+ }
+ .smileys span:nth-child(2){
+ left: 10%;
+ animation-delay: 3s;
+ }
+ .smileys span:nth-child(3){
+ left: 20%;
+ animation-delay: 2s;
+ }
+ .smileys span:nth-child(4){
+ left: 30%;
+ animation-delay: 5s;
+ }
+ .smileys span:nth-child(5){
+ left: 40%;
+ animation-delay: 1s;
+ }
+ .smileys span:nth-child(6){
+ left: 50%;
+ animation-delay: 7s;
+ }
+ .smileys span:nth-child(7){
+ left: 60%;
+ animation-delay: 6s;
+ }
+ .smileys span:nth-child(8){
+ left: 70%;
+ animation-delay: 8s;
+ }
+ .smileys span:nth-child(9){
+ left: 80%;
+ animation-delay: 6s;
+ }
+ .smileys span:nth-child(10){
+ left: 90%;
+ animation-delay: 4s;
+ }
+
+ @keyframes animate{
+ 0% {
+ transform: translateY(0);
+ opacity: 1
+ }
+ 70%{
+ opacity: .8;
+ }
+ 100% {
+ transform: translateY(-800px) rotate(360deg);
+ opacity: 0
+ }
+ }
+
+ /* HEADER */
+ header {
+ padding: 30px 30px 15px 30px;
+ text-align: center;
+ margin: 0 auto;
+ animation: bounce 2s ease-in 0s 1 normal forwards;
+ }
+
+ @keyframes bounce {
+ 0% {
+ animation-timing-function: ease-in;
+ opacity: 1;
+ transform: translateY(-45px);
+ }
+
+ 24% {
+ opacity: 1;
+ }
+
+ 40% {
+ animation-timing-function: ease-in;
+ transform: translateY(-24px);
+ }
+
+ 65% {
+ animation-timing-function: ease-in;
+ transform: translateY(-12px);
+ }
+
+ 82% {
+ animation-timing-function: ease-in;
+ transform: translateY(-6px);
+ }
+
+ 93% {
+ animation-timing-function: ease-in;
+ transform: translateY(-4px);
+ }
+
+ 25%,55%,75%,87% {
+ animation-timing-function: ease-out;
+ transform: translateY(0px);
+ }
+
+ 100% {
+ animation-timing-function: ease-out;
+ opacity: 1;
+ transform: translateY(0px);
+ }
+ }
+
+ /* LOADING */
+ .lds-spinner {
+ margin: 40px auto;
+ width: 100px;
+ height: 100px;
+ }
+ .lds-spinner div {
+ transform-origin: 40px 40px;
+ animation: lds-spinner 1.2s linear infinite;
+ }
+ .lds-spinner div:after {
+ content: " ";
+ display: block;
+ position: absolute;
+ top: 3px;
+ left: 37px;
+ width: 6px;
+ height: 18px;
+ border-radius: 20%;
+ background: #fff;
+ }
+ .lds-spinner div:nth-child(1) {
+ transform: rotate(0deg);
+ animation-delay: -1.1s;
+ }
+ .lds-spinner div:nth-child(2) {
+ transform: rotate(30deg);
+ animation-delay: -1s;
+ }
+ .lds-spinner div:nth-child(3) {
+ transform: rotate(60deg);
+ animation-delay: -0.9s;
+ }
+ .lds-spinner div:nth-child(4) {
+ transform: rotate(90deg);
+ animation-delay: -0.8s;
+ }
+ .lds-spinner div:nth-child(5) {
+ transform: rotate(120deg);
+ animation-delay: -0.7s;
+ }
+ .lds-spinner div:nth-child(6) {
+ transform: rotate(150deg);
+ animation-delay: -0.6s;
+ }
+ .lds-spinner div:nth-child(7) {
+ transform: rotate(180deg);
+ animation-delay: -0.5s;
+ }
+ .lds-spinner div:nth-child(8) {
+ transform: rotate(210deg);
+ animation-delay: -0.4s;
+ }
+ .lds-spinner div:nth-child(9) {
+ transform: rotate(240deg);
+ animation-delay: -0.3s;
+ }
+ .lds-spinner div:nth-child(10) {
+ transform: rotate(270deg);
+ animation-delay: -0.2s;
+ }
+ .lds-spinner div:nth-child(11) {
+ transform: rotate(300deg);
+ animation-delay: -0.1s;
+ }
+ .lds-spinner div:nth-child(12) {
+ transform: rotate(330deg);
+ animation-delay: 0s;
+ }
+ @keyframes lds-spinner {
+ 0% {
+ opacity: 1;
+ }
+ 100% {
+ opacity: 0;
+ }
+ }
\ No newline at end of file
diff --git a/code/src/components/Background.js b/code/src/components/Background.js
new file mode 100644
index 000000000..f207435ba
--- /dev/null
+++ b/code/src/components/Background.js
@@ -0,0 +1,21 @@
+import React from 'react';
+import '../animations.css';
+
+const Background = () => {
+ return (
+
+ 😃
+ 😍
+ 😊
+ 🥳
+ 🤩
+ 😃
+ 😍
+ 😊
+ 🥳
+ 🤩
+
+ )
+};
+
+export default Background;
\ No newline at end of file
diff --git a/code/src/components/Feed.js b/code/src/components/Feed.js
new file mode 100644
index 000000000..ffc6fa599
--- /dev/null
+++ b/code/src/components/Feed.js
@@ -0,0 +1,59 @@
+/* eslint-disable no-underscore-dangle */
+import React, { useState, useEffect } from 'react';
+import ReactTimeAgo from 'react-time-ago';
+import NewPost from './NewPost.js';
+
+const API = 'https://happy-thoughts-ux7hkzgmwa-uc.a.run.app/thoughts'
+
+const Feed = () => {
+ const [thoughtsList, setThoughtsList] = useState([]);
+ const [loading, setLoading] = useState(false);
+
+ useEffect(() => {
+ setLoading(true);
+ fetch(`${API}`)
+ .then((response) => response.json())
+ .then((data) => setThoughtsList(data))
+ .catch((error) => console.log(error))
+ .finally(() => { setLoading(false) })
+ }, []);
+
+ const HandleLike = (thoughtId) => {
+ fetch(`${API}/${thoughtId}/like`, { method: 'POST' })
+ .then((response) => response.json())
+ .then((data) => {
+ const UpdateLikes = thoughtsList.map((like) => {
+ if (like._id === data._id) {
+ like.hearts += 1
+ return like
+ } else { return like }
+ })
+ setThoughtsList(UpdateLikes)
+ })
+ };
+
+ return (
+ <>
+
+
+ {!loading && thoughtsList.map((thought) => {
+ return (
+
+
{thought.message}
+
+
x {thought.hearts}
+
+
+ )
+ })}
+ {loading && ()}
+
+ >
+ )
+};
+
+export default Feed;
\ No newline at end of file
diff --git a/code/src/components/Footer.js b/code/src/components/Footer.js
new file mode 100644
index 000000000..4dc0c4e57
--- /dev/null
+++ b/code/src/components/Footer.js
@@ -0,0 +1,13 @@
+import React from 'react';
+
+const Footer = () => {
+ return (
+
+ )
+};
+
+export default Footer;
\ No newline at end of file
diff --git a/code/src/components/Header.js b/code/src/components/Header.js
new file mode 100644
index 000000000..f0a59c000
--- /dev/null
+++ b/code/src/components/Header.js
@@ -0,0 +1,12 @@
+import React from 'react';
+import '../animations.css';
+
+const Header = () => {
+ return (
+
+ )
+};
+
+export default Header;
\ No newline at end of file
diff --git a/code/src/components/NewPost.js b/code/src/components/NewPost.js
new file mode 100644
index 000000000..e3f3c3796
--- /dev/null
+++ b/code/src/components/NewPost.js
@@ -0,0 +1,59 @@
+import React, { useState } from 'react';
+import Confetti from 'react-confetti';
+
+const NewPost = () => {
+ const [newPost, setNewPost] = useState('');
+ const [confetti, setConfetti] = useState({ showConfetti: false })
+
+ const HandleFormSubmit = (event) => {
+ event.preventDefault();
+ if (newPost.length < 5) {
+ return alert('Oh no! Too short message, needs to be minimum 5 characters')
+ } else if (newPost.length > 140) {
+ return alert('Oh no! Too long message, keep it within 140 characters')
+ } else {
+ const Submit = {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ message: newPost })
+ };
+ fetch('https://happy-thoughts-ux7hkzgmwa-uc.a.run.app/thoughts', Submit)
+ .then((response) => response.json())
+ .then(() => {
+ setConfetti({ showConfetti: true })
+ setNewPost('');
+ setTimeout(() => window.location.reload(), 3000)
+ })
+ }
+ };
+
+ return (
+ <>
+ {confetti.showConfetti && }
+
+ >
+ )
+};
+
+export default NewPost;
\ No newline at end of file
diff --git a/code/src/index.css b/code/src/index.css
index 4a1df4db7..c236b5ff3 100644
--- a/code/src/index.css
+++ b/code/src/index.css
@@ -1,13 +1,222 @@
+@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@500&display=swap');
+
+* {
+ box-sizing: border-box;
+}
+
body {
- margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
+ background: rgb(127, 199, 235);
+ height: 100%;
+ overflow: hidden;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
monospace;
}
+
+body, h1, p, label, textarea, footer {
+ margin: 0;
+ padding: 0;
+ font-family: 'Nunito';
+}
+
+h1 {
+ font-family: 'Chewy';
+ font-size: 42px;
+ text-transform: uppercase;
+ background: url('https://blog.prepscholar.com/hs-fs/hubfs/feature_rainbow_seven_colors.png?width=500&name=feature_rainbow_seven_colors.png');
+ background-position: center;
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+}
+
+main {
+ margin: 0 auto;
+ padding: 0;
+ width: 90%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.feedWrapper, .newPostWrapper {
+ box-sizing: border-box;
+ background-color: white;
+ margin: 10px;
+ width: 320px;
+ border: 1px solid rgb(56, 56, 56);
+ border-radius: 25px;
+ box-shadow: 3x 3px 0px 1px rgba(56, 56, 56, 0.75);
+ -webkit-box-shadow: 3px 3px 0px 1px rgba(56, 56, 56, 0.75);
+ -moz-box-shadow: 3px 3px 0px 1px rgba(56, 56, 56, 0.75);
+}
+
+/* NEW POST */
+.newPostWrapper {
+ padding: 14px;
+}
+
+.newPostTitle {
+ font-size: 14px;
+ font-weight: 500;
+ line-height: 1.8;
+}
+
+#newPost {
+ width: 100%;
+}
+
+textarea {
+ padding: 5px;
+ max-width: 315px;
+ background-color: rgb(251, 241, 243);
+ border: none;
+ border-radius: 8px;
+ color: black;
+}
+
+textarea:focus {
+ outline: none;
+ background-color: white;
+ border: 2px solid pink;
+}
+
+.counter, .counterTooMany {
+ position: relative;
+ float: right;
+ font-size: 12px;
+}
+
+.counter {
+ color: grey;
+}
+
+.counterTooMany {
+ color: red;
+}
+
+.postBtn {
+ margin-top: 5px;
+ background-color: pink;
+ border-radius: 20px;
+ border: none;
+ padding: 6px 8px;
+ font-family: 'Nunito';
+ font-weight: 600;
+ color: white;
+}
+
+/* FEED */
+.feedWrapper {
+ opacity: 0.9;
+ padding: 12px;
+ margin: 10px auto;
+}
+
+.postText {
+ margin: 5px 5px 10px 5px;
+ max-width: 100%;
+ overflow-wrap: break-word;
+ height: auto;
+ font-size: 14px;
+}
+
+.heart {
+ font-size: 12px;
+}
+
+.likesBtn, .noLikesBtn {
+ border: none;
+ border-radius: 50%;
+ padding: 5px 6px;
+}
+
+.likesBtn {
+ background-color: pink;
+}
+
+.sumOfLikes, .dateOfPost {
+ font-size: 12px;
+ color: grey;
+}
+
+.sumOfLikes {
+ margin-left: 2px;
+}
+
+.dateOfPost {
+ float: right;
+ margin-top: 10px;
+}
+
+.feedContainer {
+ height: 57vh;
+ width: 100%;
+ overflow-y: scroll;
+ overflow-x: hidden;
+}
+
+/* Customized scroll (hide) */
+::-webkit-scrollbar {
+ width: 10px;
+}
+::-webkit-scrollbar-track {
+ background: transparent;
+}
+::-webkit-scrollbar-thumb {
+ background: transparent;
+}
+
+/* FOOTER */
+footer {
+ width: 100%;
+ position: absolute;
+ bottom: 0;
+ background-color: black;
+ opacity: 0.6;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.contact {
+ display:flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ margin: 0;
+ padding: 10px;
+ color: white;
+ text-align: center;
+ font-size: 12px;
+ font-weight: 600;
+}
+
+.contactMe {
+ margin: 0 0 0 20px;
+ border-radius: 15px;
+ background: transparent;
+ color: white;
+ border: 2px solid white;
+ padding: 10px;
+ font-size: 12px;
+ font-weight: 600;
+}
+
+.contactMe:hover {
+ background: white;
+ color: black;
+}
+
+/* RESPONSIVE DEISGN */
+@media (min-width: 667px){
+ h1 {
+ font-size: 62px;
+ }
+}
\ No newline at end of file
diff --git a/code/src/index.js b/code/src/index.js
index ec9ad93c9..827e18937 100644
--- a/code/src/index.js
+++ b/code/src/index.js
@@ -1,8 +1,12 @@
import React from 'react';
import { createRoot } from 'react-dom/client';
import './index.css';
+import TimeAgo from 'javascript-time-ago';
+import en from 'javascript-time-ago/locale/en.json'
import { App } from './App';
+TimeAgo.addDefaultLocale(en);
+
const container = document.getElementById('root');
const root = createRoot(container);
root.render();