├── Procfile ├── .gitignore ├── client ├── src │ ├── components │ │ ├── NavComps │ │ │ ├── NavOut │ │ │ │ ├── NavOut.module.css │ │ │ │ └── NavOut.tsx │ │ │ ├── NavLogged │ │ │ │ ├── NavLogged.module.css │ │ │ │ ├── NavLogged.const.ts │ │ │ │ └── NavLogged.tsx │ │ │ ├── Hamburger │ │ │ │ └── Hamburger.tsx │ │ │ ├── Nav │ │ │ │ └── Nav.tsx │ │ │ ├── ButtonBox │ │ │ │ └── ButtonBox.tsx │ │ │ └── NavMobile │ │ │ │ └── NavMobile.tsx │ │ ├── Modal │ │ │ ├── Modal.module.css │ │ │ └── Modal.tsx │ │ ├── Header │ │ │ └── Header.tsx │ │ ├── FooterComps │ │ │ ├── FooterNav │ │ │ │ └── FooterNav.tsx │ │ │ ├── Footer │ │ │ │ └── Footer.tsx │ │ │ └── FooterIcons │ │ │ │ └── FooterIcons.tsx │ │ ├── Who │ │ │ └── Who.tsx │ │ ├── Team │ │ │ └── Team.tsx │ │ ├── Why │ │ │ └── Why.tsx │ │ ├── Stats │ │ │ └── Stats.tsx │ │ ├── Hero │ │ │ └── Hero.tsx │ │ └── Auth │ │ │ └── Auth.tsx │ ├── Portal │ │ ├── Portal.module.css │ │ └── Portal.tsx │ ├── react-app-env.d.ts │ ├── index.css │ ├── models │ │ ├── TeamData.tsx │ │ └── TeamData.ts │ ├── pages │ │ ├── Home.tsx │ │ └── Portfolio.tsx │ ├── index.tsx │ ├── App.tsx │ └── features │ │ ├── auth-ctx.tsx │ │ └── ui-ctx.tsx ├── public │ ├── assets │ │ └── hero.jpg │ └── index.html ├── postcss.config.js ├── tailwind.config.js ├── .gitignore ├── tsconfig.json └── package.json ├── img1.png ├── server ├── app.js ├── test │ └── auth.rest └── index.js ├── package.json ├── LICENSE ├── ROSTER.md ├── ROADMAP.md ├── CONTRIBUTING.md └── README.md /Procfile: -------------------------------------------------------------------------------- 1 | web: node server/app.js -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | node_modules 3 | .DS_Store -------------------------------------------------------------------------------- /client/src/components/NavComps/NavOut/NavOut.module.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/src/Portal/Portal.module.css: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | z-index: 999; 3 | } 4 | -------------------------------------------------------------------------------- /client/src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// ; 2 | -------------------------------------------------------------------------------- /img1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Medic1111/FINALLY-SEEN/HEAD/img1.png -------------------------------------------------------------------------------- /client/public/assets/hero.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Medic1111/FINALLY-SEEN/HEAD/client/public/assets/hero.jpg -------------------------------------------------------------------------------- /client/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /client/src/index.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | html { 6 | scroll-behavior: smooth; 7 | } 8 | -------------------------------------------------------------------------------- /client/src/components/Modal/Modal.module.css: -------------------------------------------------------------------------------- 1 | .article { 2 | position: fixed; 3 | top: 0; 4 | left: 0; 5 | height: 100%; 6 | width: 100%; 7 | } 8 | -------------------------------------------------------------------------------- /server/app.js: -------------------------------------------------------------------------------- 1 | const app = require("./index"); 2 | 3 | app.listen(process.env.PORT || 3002, (err) => 4 | err ? console.log(err) : console.log("Server Spinning") 5 | ); 6 | -------------------------------------------------------------------------------- /client/src/models/TeamData.tsx: -------------------------------------------------------------------------------- 1 | export interface TeamData { 2 | collaborators: number; 3 | commits: number; 4 | prs: number; 5 | top: { 6 | avatar_url: string; 7 | login: string; 8 | html_url: string; 9 | }[]; 10 | } 11 | -------------------------------------------------------------------------------- /client/src/models/TeamData.ts: -------------------------------------------------------------------------------- 1 | export interface TeamData { 2 | collaborators: number; 3 | commits: number; 4 | prs: number; 5 | top: TopData[]; 6 | } 7 | 8 | interface TopData { 9 | avatar_url: string; 10 | login: string; 11 | html_url: string; 12 | } 13 | -------------------------------------------------------------------------------- /client/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: ["./src/**/*.{js,jsx,ts,tsx}"], 4 | theme: { 5 | backgroundImage: { 6 | "hero-img": "url('../public/assets/hero.jpg')", 7 | }, 8 | extend: {}, 9 | }, 10 | plugins: [], 11 | }; 12 | -------------------------------------------------------------------------------- /client/src/components/Modal/Modal.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Auth from "../Auth/Auth"; 3 | import classes from "./Modal.module.css"; 4 | 5 | const Modal: React.FC = () => { 6 | return ( 7 |
8 | 9 |
10 | ); 11 | }; 12 | 13 | export default Modal; 14 | -------------------------------------------------------------------------------- /client/src/components/NavComps/NavLogged/NavLogged.module.css: -------------------------------------------------------------------------------- 1 | .navLink { 2 | color: #6b7280; 3 | transition: 0.125s; 4 | } 5 | 6 | .navLink:hover { 7 | opacity: 0.8; 8 | } 9 | 10 | @media (max-width: 797px) { 11 | .text { 12 | display: none; 13 | } 14 | } 15 | 16 | @media (min-width: 798px) { 17 | .icon { 18 | display: none; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /client/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /client/src/pages/Home.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Header from "../components/Header/Header"; 3 | import Hero from "../components/Hero/Hero"; 4 | import Who from "../components/Who/Who"; 5 | import Why from "../components/Why/Why"; 6 | 7 | const Home: React.FC = () => { 8 | return ( 9 | <> 10 | 11 | 12 | 13 | 14 | ); 15 | }; 16 | 17 | export default Home; 18 | -------------------------------------------------------------------------------- /client/src/components/NavComps/NavLogged/NavLogged.const.ts: -------------------------------------------------------------------------------- 1 | export const NAV_ITEMS = [ 2 | { 3 | label: "Top", 4 | icon: "keyboard_double_arrow_up", 5 | url: "https://github.com/Medic1111/FINALLY-SEEN", 6 | }, 7 | { 8 | label: "Latest", 9 | icon: "fiber_new", 10 | url: "https://github.com/Medic1111/FINALLY-SEEN", 11 | }, 12 | { 13 | label: "Logout", 14 | icon: "logout", 15 | url: "https://github.com/Medic1111/FINALLY-SEEN", 16 | }, 17 | ]; 18 | -------------------------------------------------------------------------------- /client/src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom/client"; 3 | import "./index.css"; 4 | import App from "./App"; 5 | import AuthProvider from "./features/auth-ctx"; 6 | import UiProvider from "./features/ui-ctx"; 7 | 8 | const root = ReactDOM.createRoot( 9 | document.getElementById("root") as HTMLElement 10 | ); 11 | root.render( 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | ); 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "finally-seen", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node server/app.js", 8 | "build": "cd client && npm install && npm run build" 9 | }, 10 | "author": "Aryse ", 11 | "license": "MIT", 12 | "dependencies": { 13 | "bcrypt": "^5.1.0", 14 | "cors": "^2.8.5", 15 | "dotenv": "^16.0.3", 16 | "express": "^4.18.2", 17 | "jsonwebtoken": "^8.5.1", 18 | "mongoose": "^6.7.2", 19 | "morgan": "^1.10.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "esModuleInterop": true, 8 | "allowSyntheticDefaultImports": true, 9 | "strict": true, 10 | "forceConsistentCasingInFileNames": true, 11 | "noFallthroughCasesInSwitch": true, 12 | "module": "esnext", 13 | "moduleResolution": "node", 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "noEmit": true, 17 | "jsx": "react-jsx" 18 | }, 19 | "include": ["src"] 20 | } 21 | -------------------------------------------------------------------------------- /client/src/Portal/Portal.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import classes from "./Portal.module.css"; 3 | import ReactDOM from "react-dom"; 4 | const root = document.getElementById("portal") as HTMLElement; 5 | 6 | const Wrapper: React.FC<{ children: React.ReactNode }> = ({ children }) => { 7 | return
{children}
; 8 | }; 9 | 10 | const Portal: React.FC<{ children: React.ReactNode }> = ({ children }) => { 11 | return ( 12 | 13 | {ReactDOM.createPortal({children}, root)} 14 | 15 | ); 16 | }; 17 | 18 | export default Portal; 19 | -------------------------------------------------------------------------------- /client/src/components/Header/Header.tsx: -------------------------------------------------------------------------------- 1 | import { useState, useContext } from "react"; 2 | import Nav from "../NavComps/Nav/Nav"; 3 | import NavMobile from "../NavComps/NavMobile/NavMobile"; 4 | import { UiCtx } from "../../features/ui-ctx"; 5 | 6 | const Header: React.FC = () => { 7 | const uiMgr = useContext(UiCtx); 8 | 9 | return ( 10 |
11 |
12 |
13 |

FS

14 |
17 |
18 |
19 | ); 20 | }; 21 | 22 | export default Header; 23 | -------------------------------------------------------------------------------- /client/src/components/NavComps/NavLogged/NavLogged.tsx: -------------------------------------------------------------------------------- 1 | import { NAV_ITEMS } from "./NavLogged.const"; 2 | import classes from "./NavLogged.module.css"; 3 | 4 | const NavLogged: React.FC = () => { 5 | return ( 6 | 22 | ); 23 | }; 24 | 25 | export default NavLogged; 26 | -------------------------------------------------------------------------------- /server/test/auth.rest: -------------------------------------------------------------------------------- 1 | @base_url = http://localhost:3002/api/v1 2 | 3 | # LOGIN ROUTE CORRECT CREDENTIALS 4 | 5 | POST {{base_url}}/login HTTP/1.1 6 | Content-Type: application/json 7 | 8 | { 9 | "username": "Medic1111", 10 | "password": "111111" 11 | } 12 | 13 | ### 14 | 15 | # LOGIN ROUTE MISSING CREDENTIALS 16 | 17 | POST {{base_url}}/login HTTP/1.1 18 | Content-Type: application/json 19 | 20 | { 21 | "username": "dkpsakdspa", 22 | "password": "" 23 | } 24 | 25 | ### 26 | 27 | # LOGIN ROUTE NOT REGISTERED 28 | 29 | POST {{base_url}}/login HTTP/1.1 30 | Content-Type: application/json 31 | 32 | { 33 | "username": "medic111111", 34 | "password": "111" 35 | } 36 | 37 | 38 | ### 39 | 40 | # LOGIN ROUTE WRONG PASSWORD 41 | 42 | POST {{base_url}}/login HTTP/1.1 43 | Content-Type: application/json 44 | 45 | { 46 | "username": "medic1111", 47 | "password": "this_is_not_my_password" 48 | } 49 | -------------------------------------------------------------------------------- /client/src/components/NavComps/Hamburger/Hamburger.tsx: -------------------------------------------------------------------------------- 1 | import { useContext } from "react"; 2 | import { UiCtx } from "../../../features/ui-ctx"; 3 | 4 | const Hamburger: React.FC = () => { 5 | const uiMgr = useContext(UiCtx); 6 | 7 | return ( 8 |
9 | 30 |
31 | ); 32 | }; 33 | 34 | export default Hamburger; 35 | -------------------------------------------------------------------------------- /client/src/components/NavComps/Nav/Nav.tsx: -------------------------------------------------------------------------------- 1 | // ICONMONSTR 2 | import ButtonBox from "../ButtonBox/ButtonBox"; 3 | import Hamburger from "../Hamburger/Hamburger"; 4 | import { useContext } from "react"; 5 | import { UiCtx } from "../../../features/ui-ctx"; 6 | import { AuthCtx } from "../../../features/auth-ctx"; 7 | import NavLogged from "../NavLogged/NavLogged"; 8 | import NavOut from "../NavOut/NavOut"; 9 | 10 | const Nav: React.FC = () => { 11 | const uiMgr = useContext(UiCtx); 12 | const authMgr = useContext(AuthCtx); 13 | return ( 14 |
15 | 20 | 21 |
22 | {!uiMgr.showMobileNav && !authMgr.isAuth && } 23 | 24 |
25 |
26 | ); 27 | }; 28 | 29 | export default Nav; 30 | -------------------------------------------------------------------------------- /client/src/App.tsx: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import React, { useEffect, useContext } from "react"; 3 | import { AuthCtx } from "./features/auth-ctx"; 4 | import Footer from "./components/FooterComps/Footer/Footer"; 5 | import Home from "./pages/Home"; 6 | import Portfolio from "./pages/Portfolio"; 7 | import Modal from "./components/Modal/Modal"; 8 | import Header from "./components/Header/Header"; 9 | import { UiCtx } from "./features/ui-ctx"; 10 | 11 | function App() { 12 | const authMgr = useContext(AuthCtx); 13 | const uiMgr = useContext(UiCtx); 14 | 15 | const fetchTest = async () => { 16 | await axios 17 | .get("/api") 18 | .then((serverRes) => console.log(serverRes.data)) 19 | .catch((err) => console.log(err)); 20 | }; 21 | 22 | useEffect(() => { 23 | fetchTest(); 24 | }, []); 25 | 26 | return ( 27 |
28 |
29 | {authMgr.isAuth ? : } 30 | {uiMgr.showModal && } 31 |
32 |
33 | ); 34 | } 35 | 36 | export default App; 37 | -------------------------------------------------------------------------------- /client/src/components/NavComps/ButtonBox/ButtonBox.tsx: -------------------------------------------------------------------------------- 1 | import { useContext } from "react"; 2 | import { AuthCtx } from "../../../features/auth-ctx"; 3 | import { UiCtx } from "../../../features/ui-ctx"; 4 | 5 | const ButtonBox: React.FC = () => { 6 | const uiMgr = useContext(UiCtx); 7 | const authMgr = useContext(AuthCtx); 8 | 9 | return ( 10 |
11 |

{ 14 | uiMgr.setShowModal(true); 15 | authMgr.setIsLoggin(true); 16 | }} 17 | > 18 | Login 19 |

20 | 21 |
22 |

{ 25 | uiMgr.setShowModal(true); 26 | authMgr.setIsLoggin(false); 27 | }} 28 | > 29 | Register 30 |

31 |
32 |
33 | ); 34 | }; 35 | 36 | export default ButtonBox; 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Aryse Gabrielle Pagano 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ROSTER.md: -------------------------------------------------------------------------------- 1 | # WELCOME TO THE ROSTER 2 | 3 | > The perfect place for first time ever contributions 4 | 5 | ### This is the roster 6 | 7 | > Where collaborator's contact info can be found. Please skip a line, `---`, skip another line and add the template I have below (obviously with your information) 8 | 9 | ### COLLABORATORS: 10 | 11 | --- 12 | 13 | **:point_right: Aryse Tansy** 14 | :e-mail: paganowebdev@gmail.com 15 | :computer: [Portfolio](https://www.pagano.dev/) 16 | 17 | --- 18 | 19 | **:point_right: Cong Su Nguyen** 20 | :e-mail: sub1910692@student.ctu.edu.vn 21 | 22 | --- 23 | 24 | 25 | **:point_right: Priya Saraf** 26 | :e-mail: priyasaraf1011@gmail.com 27 | 28 | --- 29 | 30 | **:point_right: Aditya Narayan** 31 | :e-mail: 29adityanarayan2000@gmail.com 32 | 33 | --- 34 | 35 | **:point_right: Yahli Gitzi** 36 | :e-mail: yahligitzi2@gmail.com 37 | 38 | --- 39 | 40 | **:point_right: Wasiu Adelakun** 41 | :e-mail: adelakunwasiu1000@gmail.com 42 | :computer: [Portfolio](https://waslead.netlify.app/) 43 | 44 | --- 45 | 46 | **:point_right: Augustine Kirumba** 47 | :e-mail: kirumbaaugustinewambugu@gmail.com 48 | 49 | --- 50 | 51 | **:point_right: Matthew Mu** :e-mail: matty.mu96@gmail.com -------------------------------------------------------------------------------- /client/src/components/FooterComps/FooterNav/FooterNav.tsx: -------------------------------------------------------------------------------- 1 | const FooterNav: React.FC = () => { 2 | return ( 3 | 42 | ); 43 | }; 44 | 45 | export default FooterNav; 46 | -------------------------------------------------------------------------------- /client/src/components/NavComps/NavOut/NavOut.tsx: -------------------------------------------------------------------------------- 1 | import { useContext } from "react"; 2 | import { UiCtx } from "../../../features/ui-ctx"; 3 | import classes from "./NavOut.module.css"; 4 | 5 | const NavOut: React.FC = () => { 6 | const uiMgr = useContext(UiCtx); 7 | return ( 8 | <> 9 | {" "} 10 | 15 | {" "} 16 | Github{" "} 17 | 18 | uiMgr.setShowMobileNav(false)} 20 | href="#who" 21 | className="px-6 py-3" 22 | > 23 | {" "} 24 | Who{" "} 25 | 26 | uiMgr.setShowMobileNav(false)} 28 | href="#why" 29 | className="flex items-center justify-between px-6 py-3" 30 | > 31 | Why 32 | 33 | 37 | Collab 38 | 39 | 40 | ); 41 | }; 42 | 43 | export default NavOut; 44 | -------------------------------------------------------------------------------- /client/src/components/FooterComps/Footer/Footer.tsx: -------------------------------------------------------------------------------- 1 | import FooterIcons from "../FooterIcons/FooterIcons"; 2 | import FooterNav from "../FooterNav/FooterNav"; 3 | 4 | const Footer: React.FC = () => { 5 | return ( 6 |
7 |
8 |
9 |

{ 12 | window.scrollTo(0, 0); 13 | }} 14 | > 15 | FS 16 |

17 |
18 |

19 | This is an open-source project with a MIT license and its purpose is 20 | to promote contributions from developers at all levels. 21 |

22 | 23 |

24 | Medic1111 {new Date().getFullYear()} Copyrights 25 |

26 | 27 | 28 |
29 |
30 | ); 31 | }; 32 | 33 | export default Footer; 34 | -------------------------------------------------------------------------------- /client/src/features/auth-ctx.tsx: -------------------------------------------------------------------------------- 1 | import React, { createContext, useState } from "react"; 2 | 3 | interface AuthType { 4 | isLoggin: boolean; 5 | setIsLoggin: React.Dispatch>; 6 | isAuth: boolean; 7 | setIsAuth: React.Dispatch>; 8 | currentUser: {}; 9 | setCurrentUser: React.Dispatch>; 10 | } 11 | 12 | export const AuthCtx = createContext({ 13 | isLoggin: false, 14 | setIsLoggin: () => {}, 15 | isAuth: false, 16 | setIsAuth: () => {}, 17 | currentUser: {}, 18 | setCurrentUser: () => {}, 19 | }); 20 | 21 | const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ 22 | children, 23 | }) => { 24 | const [isLoggin, setIsLoggin] = useState(false); 25 | const [isAuth, setIsAuth] = useState(false); 26 | const [currentUser, setCurrentUser] = useState({}); 27 | 28 | return ( 29 | 39 | {children} 40 | 41 | ); 42 | }; 43 | 44 | export default AuthProvider; 45 | -------------------------------------------------------------------------------- /client/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | 14 | 18 | 22 | 23 | 24 | 28 | 29 | Finally-Seen 30 | 31 | 32 |
33 |
34 | 35 | 36 | -------------------------------------------------------------------------------- /client/src/features/ui-ctx.tsx: -------------------------------------------------------------------------------- 1 | import React, { createContext, useState } from "react"; 2 | 3 | interface UiType { 4 | showMobileNav: boolean; 5 | setShowMobileNav: React.Dispatch>; 6 | showHamburger: boolean; 7 | setShowHamburger: React.Dispatch>; 8 | showModal: boolean; 9 | setShowModal: React.Dispatch>; 10 | } 11 | 12 | export const UiCtx = createContext({ 13 | showMobileNav: false, 14 | setShowMobileNav: () => {}, 15 | showHamburger: false, 16 | setShowHamburger: () => {}, 17 | showModal: false, 18 | setShowModal: () => {}, 19 | }); 20 | 21 | const UiProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { 22 | const [showMobileNav, setShowMobileNav] = useState(false); 23 | const [showHamburger, setShowHamburger] = useState(false); 24 | const [showModal, setShowModal] = useState(false); 25 | 26 | return ( 27 | 37 | {children} 38 | 39 | ); 40 | }; 41 | 42 | export default UiProvider; 43 | -------------------------------------------------------------------------------- /client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "client", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.16.5", 7 | "@testing-library/react": "^13.4.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "@types/jest": "^27.5.2", 10 | "@types/node": "^16.18.3", 11 | "@types/react": "^18.0.25", 12 | "@types/react-dom": "^18.0.8", 13 | "axios": "^1.1.3", 14 | "react": "^18.2.0", 15 | "react-dom": "^18.2.0", 16 | "react-scripts": "5.0.1", 17 | "typescript": "^4.8.4", 18 | "web-vitals": "^2.1.4" 19 | }, 20 | "scripts": { 21 | "start": "react-scripts start", 22 | "build": "react-scripts build", 23 | "test": "react-scripts test", 24 | "eject": "react-scripts eject" 25 | }, 26 | "proxy": "http://localhost:3002", 27 | "eslintConfig": { 28 | "extends": [ 29 | "react-app", 30 | "react-app/jest" 31 | ] 32 | }, 33 | "browserslist": { 34 | "production": [ 35 | ">0.2%", 36 | "not dead", 37 | "not op_mini all" 38 | ], 39 | "development": [ 40 | "last 1 chrome version", 41 | "last 1 firefox version", 42 | "last 1 safari version" 43 | ] 44 | }, 45 | "devDependencies": { 46 | "autoprefixer": "^10.4.13", 47 | "postcss": "^8.4.19", 48 | "tailwindcss": "^3.2.4" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /client/src/components/Who/Who.tsx: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import { useEffect, useState } from "react"; 3 | import Team from "../Team/Team"; 4 | import { TeamData } from "../../models/TeamData"; 5 | import Stats from "../Stats/Stats"; 6 | 7 | const Who: React.FC = () => { 8 | const [data, setData] = useState({ 9 | collaborators: 0, 10 | commits: 0, 11 | prs: 0, 12 | top: [{ avatar_url: "", login: "", html_url: "" }], 13 | }); 14 | 15 | const fetchData = async () => { 16 | let count = 0; 17 | await axios 18 | .get("https://api.github.com/repos/Medic1111/FINALLY-SEEN/contributors") 19 | .then((serverRes) => { 20 | serverRes.data.forEach((obj: { contributions: 0 }) => { 21 | return (count += obj.contributions); 22 | }); 23 | 24 | setData({ 25 | collaborators: serverRes.data.length, 26 | commits: count, 27 | prs: 0, 28 | top: [...serverRes.data.slice(0, 8)], 29 | }); 30 | }) 31 | .catch((err) => { 32 | console.log(err); 33 | }); 34 | }; 35 | 36 | useEffect(() => { 37 | fetchData(); 38 | }, []); 39 | 40 | return ( 41 | <> 42 |
43 | 44 | 45 |
46 | 47 | ); 48 | }; 49 | 50 | export default Who; 51 | -------------------------------------------------------------------------------- /client/src/components/Team/Team.tsx: -------------------------------------------------------------------------------- 1 | import { TeamData } from "../../models/TeamData"; 2 | 3 | const Team: React.FC<{ data: TeamData }> = ({ data }) => { 4 | return ( 5 |
6 |

7 | Top Contributors 8 |

9 |
10 | {data.top.map((obj, index) => { 11 | return ( 12 | <> 13 |
14 | avatar 19 | 20 |
21 |

22 | {obj.login} 23 |

24 | 25 | 26 | Check Github 27 | 28 | 29 |
30 |
31 | 32 | ); 33 | })} 34 |
35 |
36 | ); 37 | }; 38 | 39 | export default Team; 40 | -------------------------------------------------------------------------------- /client/src/components/Why/Why.tsx: -------------------------------------------------------------------------------- 1 | const Why: React.FC = () => { 2 | return ( 3 |
4 |
5 |
6 |

7 | Why 8 |

9 |

10 | 11 | The question is "why not". The sense of community comes with kind 12 | gestures of offering what you can from a good place. You never know 13 | what treasure is coming with the next commit, but you know 14 | inherently to treasure each and every single one no matter the 15 | outcome. 16 | 17 |

18 |
19 | 20 | Aryse Pagano 21 | 22 | / 23 | Project Owner 24 |
25 |
26 |
27 |
28 | ); 29 | }; 30 | 31 | export default Why; 32 | -------------------------------------------------------------------------------- /server/index.js: -------------------------------------------------------------------------------- 1 | // GENERAL REQUIRES 2 | 3 | const express = require("express"); 4 | const morgan = require("morgan"); 5 | const cors = require("cors"); 6 | const bcrypt = require("bcrypt"); 7 | const jwt = require("jsonwebtoken"); 8 | const mongoose = require("mongoose"); 9 | const path = require("path"); 10 | require("dotenv").config(); 11 | const app = express(); 12 | 13 | // GENERAL MIDDLEWARES 14 | app.use(morgan("dev")); 15 | app.use(cors({ origin: "*" })); 16 | app.use(express.json()); 17 | app.use(express.static(path.resolve(__dirname, "../client/build"))); 18 | 19 | // DEV TESTING ROUTES HERE: 20 | 21 | app.post("/api/v1/login", (req, res) => { 22 | const { username, password } = req.body; 23 | const mockUsers = ["medic1111", "john", "brent", "lordson"]; 24 | const correctPass = "111111"; 25 | 26 | // THIS IS THE FIRST CHECK: 27 | 28 | if (!username || !password) { 29 | return res.status(422).json({ message: "All fields are required" }); 30 | } 31 | 32 | // HERE WE USE MOCK DATA, BUT IT WILL BE A SEARCH ON DB 33 | // IF SEARCH FAILS: 34 | 35 | if (!mockUsers.includes(username)) { 36 | return res.status(404).json({ message: "User not found" }); 37 | } 38 | 39 | // IF SEARCH DOESNT FAIL, WE BCRYPT COMPARE PASSWORD 40 | // IF COMPARISON FAILS: 41 | 42 | if (password !== correctPass) { 43 | return res.status(403).json({ message: "Wrong password" }); 44 | } 45 | 46 | // IF ALL CHECKS, USER CAN BE LOGGED IN: 47 | 48 | res.status(200).json({ message: "Logging user" }); 49 | 50 | // USE THE AUTH.REST FILE TO SEND REQUESTS AND OBSERVE 51 | // RESPONSE. THAT WILL BE THE FIRST LINE OF TESTING 52 | }); 53 | 54 | app.get("/api", (req, res) => 55 | res.status(200).json({ message: "Hello from server" }) 56 | ); 57 | 58 | // UNIVERSAL ROUTE 59 | 60 | app.get("*", (req, res) => { 61 | res.sendFile(path.resolve(__dirname, "../client/build", "index.html")); 62 | }); 63 | 64 | module.exports = app; 65 | -------------------------------------------------------------------------------- /ROADMAP.md: -------------------------------------------------------------------------------- 1 | # HELLO COLLABS! 2 | 3 | > Thanks for participating and I trully hope this project is adding to your contributions. 4 | 5 | --- 6 | 7 | ## THE GOAL: 8 | 9 | The objective of this project is to have it 100% build by cotribution. Some tasks may seen too small or simple. Trust me, I remember how it was to NOT know how to contribute and based on that, my intention is to welcome ALL levels of collaborators. 10 | 11 | The project is a MERN application which will render links to developers portfolio. It will also display a featured picture of such portfolio and give registered users the ability to vote up. 12 | 13 | ### Where are we? 14 | 15 | - Client: 16 | 17 | - [x] When I access the application URL I see the "home" page. 18 | - [x] The home page has a header 19 | - [ ] The header has a Logo, and a Nav bar with options to Login or Register 20 | - [ ] The Nav will display icons if viewport less than 798px 21 | - [x] The home page also has a footer 22 | - [ ] The home page has its main content wrapped in a Wrapper component 23 | - [ ] The "home" page seen at first by any user will display the top 10 portfolios based on upvotes. 24 | - [ ] When I click Login, a login form takes over the content inside the Wrapper 25 | - [ ] When I click Register, a Register form takes over the content inside the Wrapper 26 | - [ ] Initially, when I submit login/register, a simple state will change, which will display a nav with different content: Top, Latest, add(icon), Logout 27 | 28 | *** 29 | 30 | > Attention: This is the first plan and may change at any time. The intention is to give as many contribution opportunities as possible. As the project evolves, such features will become more advance and likely to change. 31 | 32 | *** 33 | 34 | ### SYSTEMATIC APPROACH 35 | 36 | - We only move forward as we accomplish the roadmap 37 | 38 | - We will work on a particular feature as an epic, and move forward when that Epic is completed to achieve MVP. 39 | 40 | - There's absolutely no rush, and mistakes are WELCOME as we all learn from them 41 | 42 | - HAVE FUN! 43 | -------------------------------------------------------------------------------- /client/src/components/Stats/Stats.tsx: -------------------------------------------------------------------------------- 1 | import { TeamData } from "../../models/TeamData"; 2 | 3 | const Stats: React.FC<{ data: TeamData }> = ({ data }) => { 4 | return ( 5 | <> 6 |
7 |
8 |

Who

9 | 10 |

11 | Dynamic team of developers at all levels, always evolving but most 12 | importantly always counting. 13 |

14 |
15 | 16 |
17 |
18 |
19 |
20 | Collaborators 21 |
22 | 23 |
24 | {data.collaborators} 25 |
26 |
27 | 28 |
29 |
30 | Commits 31 |
32 | 33 |
34 | {data.commits} 35 |
36 |
37 | 38 |
39 |
40 | Team {"=)"} 41 |
42 | 43 |
44 | 1 45 |
46 |
47 |
48 |
49 |
50 | 51 | ); 52 | }; 53 | 54 | export default Stats; 55 | -------------------------------------------------------------------------------- /client/src/components/NavComps/NavMobile/NavMobile.tsx: -------------------------------------------------------------------------------- 1 | import { useContext } from "react"; 2 | import { AuthCtx } from "../../../features/auth-ctx"; 3 | import { UiCtx } from "../../../features/ui-ctx"; 4 | import NavLogged from "../NavLogged/NavLogged"; 5 | import NavOut from "../NavOut/NavOut"; 6 | 7 | const NavMobile: React.FC = () => { 8 | const uiMgr = useContext(UiCtx); 9 | const authMgr = useContext(AuthCtx); 10 | 11 | return ( 12 |
13 |
14 |
15 |
16 |
17 | 18 | Menu 19 | 20 | 21 | 42 |
43 | 44 | 47 |
48 |
49 |
50 |
51 | ); 52 | }; 53 | 54 | export default NavMobile; 55 | -------------------------------------------------------------------------------- /client/src/components/Hero/Hero.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react"; 2 | import { AuthCtx } from "../../features/auth-ctx"; 3 | import { UiCtx } from "../../features/ui-ctx"; 4 | 5 | const Hero: React.FC = () => { 6 | const uiMgr = useContext(UiCtx); 7 | const authMgr = useContext(AuthCtx); 8 | 9 | return ( 10 |
11 |
12 |
13 |
14 |

15 | Where developers are 16 | 17 | Finally Seen 18 | 19 |

20 | 21 |

22 | A contribution initiative as open-source. 23 |

24 | 25 | 44 |
45 |
46 |
47 | ); 48 | }; 49 | 50 | export default Hero; 51 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## WELCOME AND THANKS FOR CONTRIBUTING 2 | 3 | ### First things first: 4 | 5 | - We do use Github API to pull some stats including your profile picture if you're on the list of top 8 contributors. IF YOU'RE NOT OKAY WITH THAT, Please do not contribute =) or don't be top 8. 6 | 7 | - Your initial contribution will be adding your contact to ROSTER.md 8 | 9 | - You will find the template and instructions (hint: click raw to view markdown and copy) 10 | 11 | - After forking, ensure to ALWAYS PULL DEVELOPMENT, which is the branch all collaboration work will be PRd to. 12 | 13 | - NEVER PR TO MAIN, it will not be merged. 14 | 15 | - Always work on your branch, naming it camelCase with your first and last name 16 | 17 | > Ex: arysePagano 18 | 19 | ### Issues 20 | 21 | - There will be PLENTY of issues for you to choose from. If you see one that fits you, comment on it to be assigned to it. 22 | 23 | - Please be aware that we will all be waiting on your piece of work. The easiest way to get CONFLICTS is by delivering outdated/late work. 24 | 25 | - Be respectful and deliver within 24 hrs. Those issues will be short enough for that to be accomplished very easily. 26 | 27 | - If you run into problems, DO comment on your task. Other people and myself will gladly give a hand. 28 | 29 | - I intend to open GITHUB PROJECTS for this app. To be announced in the near future. For now, well organized issues will do the job. 30 | 31 | ### Clone the repository 32 | 33 | - Fork the repository. 34 | 35 | - Clone the forked repository. 36 | 37 | ```bash 38 | $ git clone https://github.com/your_username/FINALLY-SEEN.git 39 | ``` 40 | 41 | - Clone all the branches from the parent repository, not only main branch. 42 | 43 | ### Creating a branch 44 | 45 | - When starting work on a new issue, branch off from the `development` branch. 46 | 47 | ```bash 48 | $ git checkout -b development 49 | ``` 50 | 51 | - Switched to a new branch "". 52 | 53 | - Contributors working on same issue but in different branches can do sub-team fetches in case required. 54 | 55 | - Commit the changes with some descriptive messgaes. 56 | 57 | ```bash 58 | $ git commit -m "" 59 | ``` 60 | 61 | - Once the issue is finished, the contributor shall push the changes to remote after commiting. 62 | ```bash 63 | $ git push origin 64 | ``` 65 | 66 | ### Raising a Pull request 67 | 68 | - Once the branch has been pushed, the contributor shall raise the PR against the `development`. 69 | 70 | - Contributor shall incorporate review comments and upon approval, the PR shall proceed for merge into `development`. 71 | 72 | - As you update your PR and apply changes, mark each conversation as resolved. 73 | -------------------------------------------------------------------------------- /client/src/components/Auth/Auth.tsx: -------------------------------------------------------------------------------- 1 | import { useState, useContext } from "react"; 2 | import { UiCtx } from "../../features/ui-ctx"; 3 | import { AuthCtx } from "../../features/auth-ctx"; 4 | 5 | const Auth: React.FC = () => { 6 | const uiMgr = useContext(UiCtx); 7 | const authMgr = useContext(AuthCtx); 8 | 9 | return ( 10 |
11 |
12 |

13 | {authMgr.isLoggin ? "Log In" : "Register"} 14 |

15 | {authMgr.isLoggin || ( 16 | 23 | )} 24 | 25 | 32 | 33 | 40 | 41 | 44 | 45 | {authMgr.isLoggin && ( 46 | 50 | FORGOT PASSWORD? 51 | 52 | )} 53 | 54 |

55 | {authMgr.isLoggin ? "No account? " : "Already registered? "} 56 | authMgr.setIsLoggin((prev) => !prev)} 60 | > 61 | {authMgr.isLoggin ? "Create One" : "Login"} 62 | 63 |

64 | 65 |

uiMgr.setShowModal(false)} 67 | className="cursor-pointer text-center text-2xl font-medium text-teal-600" 68 | > 69 | FS 70 |

71 |
72 |
73 | ); 74 | }; 75 | 76 | export default Auth; 77 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FINALLY-SEEN 2 | 3 | > A contribution initiative 4 | 5 | --- 6 | 7 | [LIVE DEV DEMO](https://finally-seen-oizk.onrender.com/) 8 | 9 | --- 10 | 11 | ![hero image](img1.png) 12 | 13 | ## STACK 14 | 15 | - Client: 16 | - React with CRA templated with TS 17 | - Server: 18 | - NodeJS and Express 19 | - DB: 20 | - MongoDB 21 | - Deployment: 22 | - Render.io 23 | 24 | --- 25 | 26 | ## The Project: 27 | 28 | Hello World! And welcome to FINALLY-SEEN, a soon to be a MERN stack application for which a user (a dev) will be able to post the URL of their portfolio and obtain some sort of feedback. 29 | 30 | The Project is still to be fully defined, I just wanted to get that out there as soon as possible to help those like me who chase "good first issue"s. 31 | 32 | The intention is to get everyone who wants to contribute, at least one task. I will personally try my best to adapt this project so anyone regardless of skills can hop in. 33 | 34 | > Ex: You know react but do not know TS...No problem. Ill take your JS (thanks for that) and give the convertion to someone else to collab on. 35 | 36 | --- 37 | 38 | ## Fearful? Don't be... 39 | 40 | While I intend to give devs a good amount of coding freedom, I will be very specific and even (if needed and requested), outline steps needed to be performed in order to achieve the task. IT'S OKAY TO MAKE MISTAKES. Fixing bugs always make great first issues. 41 | 42 | ## WHAT IS NOT OKAY? 43 | 44 | Leave your ego home. This industry is full of it and I'm sure you can find plenty of opportunities to take it "for a walk". This is not the place. 45 | 46 | --- 47 | 48 | ## HOW TO RUN? 49 | 50 | 1. Fork this repo: 51 | 52 | Step 1: Click the Fork button to the right of the repository. 53 | image 54 | Step 2: We will then be navigated to the create new a fork page and click the create fork button. 55 | image 56 | 57 | 2. Clone the project: 58 | 59 | Step 1: On your Visual Studio Code IDE (or any IDE), click terminal and click new terminal. 60 | image 61 | Step 2: On the terminal run `git clone https://github.com/Medic1111/FINALLY-SEEN` to clone the project. 62 | 63 | 3. Install dependencies client and run client: 64 | 65 | Step 1: On the terminal in your VScode IDE run `cd .\FINALLY-SEEN\` 66 | 67 | Step 2: Then run `cd .\client\` and run `npm install` to install dependencies client. 68 | 69 | Step 3: With all dependencies installed, while still on the client you can run `npm start` to start the client on localhost 3000 70 | 71 | 4. Install dependencies server and run server: 72 | 73 | Step 1: On the new terminal in your VScode IDE(while on the root of the project) run `cd .\server\` 74 | 75 | Step 2: Then run `npm install` to install dependencies server. 76 | 77 | Step 3: With all dependencies installed, while still on the server you can run `node app.js` to start the server. 78 | 79 | > I highly suggest using nodemon to run the server. It is not a dependency of this project but feel free to use your globally installed one. 80 | 81 | --- 82 | 83 | ### WHO AM I 84 | 85 | **:point_right: Aryse Tansy** 86 | :e-mail: paganowebdev@gmail.com 87 | :computer: [Portfolio](https://www.pagano.dev/) 88 | 89 | --- 90 | -------------------------------------------------------------------------------- /client/src/pages/Portfolio.tsx: -------------------------------------------------------------------------------- 1 | import Header from "../components/Header/Header"; 2 | 3 | const Portfolio: React.FC = () => { 4 | return ( 5 |
6 | {/*
*/} 7 |
8 |
9 |
10 | 11 |
12 |

13 | Meet the developer's
{" "} 14 | portfolios 15 |

16 | 17 |
18 | 23 | 24 |
25 |

26 | Developer Title{" "} 27 | (Ups: 480) 28 |

29 | 30 |

31 | “ A description of the developer and short journey brief ” 32 |

33 | 34 | 38 | DevName LastName(link to github) 39 | 40 | 41 | portfolio URL 42 | 43 |
44 |
45 | 46 |
47 | 63 | 64 | 80 |
81 |
82 |
83 |
84 | ); 85 | }; 86 | 87 | export default Portfolio; 88 | -------------------------------------------------------------------------------- /client/src/components/FooterComps/FooterIcons/FooterIcons.tsx: -------------------------------------------------------------------------------- 1 | const FooterIcons: React.FC = () => { 2 | return ( 3 | 69 | ); 70 | }; 71 | 72 | export default FooterIcons; 73 | --------------------------------------------------------------------------------