diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index 29b50a0..277cd7e 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -6,7 +6,7 @@ on: jobs: build-project: #First Job is to check the code formatting, linting and build the project. if: github.event.pull_request.draft == false - name: Run Prettier, Lint and Build Checks + name: Run Formatting Checks and Tests runs-on: ubuntu-latest steps: @@ -27,6 +27,9 @@ jobs: - name: Linting Check #Runs ESLint Script run: npm run lint + - name: Test #Runs Jest Script + run: npm run test + - name: Build #Build the project env: MONGODB_URI: ${{ secrets.MONGODB_URI }} diff --git a/.prettierignore b/.prettierignore index 3890519..91d7a13 100644 --- a/.prettierignore +++ b/.prettierignore @@ -6,4 +6,9 @@ package.json package-lock.json README.md -tailwind.config.js \ No newline at end of file +tailwind.config.js +jest.config.mjs +jest.setup.js +jsconfig.json +next.config.js +postcss.config.js diff --git a/.prettierrc.json b/.prettierrc.json index 043b0cd..8bab7bb 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -3,5 +3,6 @@ "trailingComma": "es5", "singleQuote": true, "tabWidth": 2, - "useTabs": false + "useTabs": false, + "printWidth": 150 } diff --git a/.vscode/settings.json b/.vscode/settings.json index c91ad1b..94550ba 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,6 @@ { "editor.codeActionsOnSave": { - "source.fixAll.eslint": true + "source.fixAll.eslint": "explicit" }, // Add those two lines: "editor.formatOnSave": true, // Tell VSCode to format files on save diff --git a/package-lock.json b/package-lock.json index bfeb17b..27e3d85 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "promises": "^0.2.5", "react": "18.2.0", "react-dom": "18.2.0", + "react-icons": "^4.11.0", "tailwindcss": "3.3.3" }, "devDependencies": { @@ -17456,6 +17457,14 @@ "integrity": "sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==", "dev": true }, + "node_modules/react-icons": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.11.0.tgz", + "integrity": "sha512-V+4khzYcE5EBk/BvcuYRq6V/osf11ODUM2J8hg2FDSswRrGvqiYUYPRy4OdrWaQOBj4NcpJfmHZLNaD+VH0TyA==", + "peerDependencies": { + "react": "*" + } + }, "node_modules/react-inspector": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/react-inspector/-/react-inspector-6.0.2.tgz", @@ -19709,9 +19718,9 @@ "dev": true }, "node_modules/typescript": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", "dev": true, "peer": true, "bin": { @@ -33332,6 +33341,12 @@ } } }, + "react-icons": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.11.0.tgz", + "integrity": "sha512-V+4khzYcE5EBk/BvcuYRq6V/osf11ODUM2J8hg2FDSswRrGvqiYUYPRy4OdrWaQOBj4NcpJfmHZLNaD+VH0TyA==", + "requires": {} + }, "react-inspector": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/react-inspector/-/react-inspector-6.0.2.tgz", @@ -35034,9 +35049,9 @@ "dev": true }, "typescript": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", "dev": true, "peer": true }, diff --git a/package.json b/package.json index cf5ed1b..feb2481 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "build": "next build", "start": "next start", "lint": "next lint", - "test": "jest --watch", + "test": "jest --maxWorkers=2", "storybook": "storybook dev -p 6006", "build-storybook": "storybook build", "prettier": "npx prettier . --check", @@ -25,6 +25,7 @@ "promises": "^0.2.5", "react": "18.2.0", "react-dom": "18.2.0", + "react-icons": "^4.11.0", "tailwindcss": "3.3.3" }, "devDependencies": { diff --git a/src/__tests__/home.test.js b/src/__tests__/home.test.js index 2dc6e4f..9826fa0 100644 --- a/src/__tests__/home.test.js +++ b/src/__tests__/home.test.js @@ -2,23 +2,11 @@ import { render, screen } from '@testing-library/react' import Home from '../app/page.js' import SearchBar from '@/components/SearchBar.js' import '@testing-library/jest-dom' - -describe('Home', () => { - it('renders a heading', () => { - render() - - const heading = screen.getByRole('heading', { - name: /BacPac/i, - }) - - expect(heading).toBeInTheDocument() - }) -}) it('renders a search box', () => { - const {getByPlaceholderText} = render() - - const subject = getByPlaceholderText('Search Colleges...') + const { getByPlaceholderText } = render() + + const subject = getByPlaceholderText('Search') expect(subject).toBeInTheDocument() -}) \ No newline at end of file +}) diff --git a/src/__tests__/searchBar.test.js b/src/__tests__/searchBar.test.js index 09406d9..618b5ee 100644 --- a/src/__tests__/searchBar.test.js +++ b/src/__tests__/searchBar.test.js @@ -1,42 +1,33 @@ -import { render, screen, fireEvent, getByTestId, waitFor } from '@testing-library/react' +import { render, fireEvent } from '@testing-library/react' import SearchBar from '@/components/SearchBar.js' import data from '../../data/university_data' import '@testing-library/jest-dom' -it('renders a search box', () => { - const {getByPlaceholderText} = render() - - const subject = getByPlaceholderText('Search Colleges...') - - expect(subject).toBeInTheDocument() -}) - it('display filtered data based on input', () => { - const {getByPlaceholderText, queryByText} = render() - const input = getByPlaceholderText('Search Colleges...') - + const { getByPlaceholderText, queryByText } = render() + const input = getByPlaceholderText('Search') + fireEvent.change(input, { target: { value: 'Bhubaneswar' } }) - // console.log(screen.debug()); //For Debugging: Print the rendered component to the console expect(queryByText('Indian Institute of Technology Bhubaneswar')).toBeInTheDocument() - expect(queryByText('Massachusetts Institute of Technology (MIT)')).toBeNull(); + expect(queryByText('Massachusetts Institute of Technology (MIT)')).toBeNull() }) it('handles case-insensitive filtering', () => { - const { getByPlaceholderText, queryByText } = render(); - const input = getByPlaceholderText('Search Colleges...'); + const { getByPlaceholderText, queryByText } = render() + const input = getByPlaceholderText('Search') - fireEvent.change(input, { target: { value: 'bhub' } }); + fireEvent.change(input, { target: { value: 'bhub' } }) expect(queryByText('Indian Institute of Technology Bhubaneswar')).toBeInTheDocument() - expect(queryByText('Massachusetts Institute of Technology (MIT)')).toBeNull(); -}); + expect(queryByText('Massachusetts Institute of Technology (MIT)')).toBeNull() +}) it('should display "No results found" if no matching results are found', () => { - const { getByPlaceholderText, queryByText } = render(); - const input = getByPlaceholderText('Search Colleges...'); + const { getByPlaceholderText, queryByText } = render() + const input = getByPlaceholderText('Search') + + fireEvent.change(input, { target: { value: 'qwertyuiop' } }) - fireEvent.change(input, { target: { value: 'qwertyuiop' } }); - - expect(queryByText('No results found')).toBeInTheDocument(); -}); \ No newline at end of file + expect(queryByText('No results found')).toBeInTheDocument() +}) diff --git a/src/app/aboutus/page.js b/src/app/aboutus/page.js new file mode 100644 index 0000000..6104118 --- /dev/null +++ b/src/app/aboutus/page.js @@ -0,0 +1,12 @@ +import Navbar from '../components/Navbar/Navbar' +import React from 'react' + +function AboutUs() { + return ( +
+ +
+ ) +} + +export default AboutUs diff --git a/src/app/api/graphql/route.js b/src/app/api/graphql/route.js index 20020e7..f238d7a 100644 --- a/src/app/api/graphql/route.js +++ b/src/app/api/graphql/route.js @@ -1,9 +1,6 @@ import { startServerAndCreateNextHandler } from '@as-integrations/next' import { ApolloServer } from '@apollo/server' -import { - ApolloServerPluginLandingPageLocalDefault, - ApolloServerPluginLandingPageProductionDefault, -} from '@apollo/server/plugin/landingPage/default' +import { ApolloServerPluginLandingPageLocalDefault, ApolloServerPluginLandingPageProductionDefault } from '@apollo/server/plugin/landingPage/default' import { gql } from 'graphql-tag' import { MongoClient } from 'mongodb' diff --git a/src/app/community/page.js b/src/app/community/page.js new file mode 100644 index 0000000..3e9b003 --- /dev/null +++ b/src/app/community/page.js @@ -0,0 +1,12 @@ +import Navbar from '../components/Navbar/Navbar' +import React from 'react' + +function Community() { + return ( +
+ +
+ ) +} + +export default Community diff --git a/src/app/components/CollegeResult.js b/src/app/components/CollegeResult.js index 33da95c..50fe620 100644 --- a/src/app/components/CollegeResult.js +++ b/src/app/components/CollegeResult.js @@ -2,19 +2,10 @@ import Link from 'next/link' function CollegeResult(props) { return (
- -
- {props.serialNo + 1} -
-
- {props.info.name} -
-
- {props.info.score} -
+ +
{props.serialNo + 1}
+
{props.info.name}
+
{props.info.score}
) diff --git a/src/app/components/Footer/Footer.css b/src/app/components/Footer/Footer.css new file mode 100644 index 0000000..aa4595d --- /dev/null +++ b/src/app/components/Footer/Footer.css @@ -0,0 +1,3 @@ +.footer { + height: 60px; +} diff --git a/src/app/components/Footer/Footer.js b/src/app/components/Footer/Footer.js new file mode 100644 index 0000000..a4d18da --- /dev/null +++ b/src/app/components/Footer/Footer.js @@ -0,0 +1,69 @@ +import './Footer.css' + +import { AiFillFacebook, AiFillInstagram, AiOutlineCopyrightCircle, AiOutlineTwitter } from 'react-icons/ai' + +import { BsDiscord } from 'react-icons/bs' +import Image from 'next/image' +import React from 'react' +import bacpacLogo from '../../../assets/bacpacLogo.png' +import bacpacTitle from '../../../assets/bacpacTitle.png' + +function Footer() { + const handleRedirect = (platform) => { + let url + const SocialNetwork = { + DISCORD: 1, + FACEBOOK: 2, + TWITTER: 3, + INSTAGRAM: 4, + } + switch (platform) { + case SocialNetwork.DISCORD: + url = '#' + break + case SocialNetwork.FACEBOOK: + url = '#' + break + case SocialNetwork.TWITTER: + url = '#' + break + case SocialNetwork.INSTAGRAM: + url = '#' + break + default: + return + } + window.open(url, '_blank') + } + return ( +
+
+
+ +
+
+ +
+
+
+ Copyright 2023 Bacpac Networks +
+
+
handleRedirect(4)}> + +
+
handleRedirect(2)}> + +
+
handleRedirect(3)}> + +
+
handleRedirect(1)}> + +
+
+
+ ) +} + +export default Footer diff --git a/src/app/components/Navbar/Navbar.css b/src/app/components/Navbar/Navbar.css new file mode 100644 index 0000000..1285321 --- /dev/null +++ b/src/app/components/Navbar/Navbar.css @@ -0,0 +1,50 @@ +.navbar { + box-shadow: 0 5px 15px 5px #ececec; + height: 60px; +} +.nav li:hover { + font-size: 16px; + font-weight: 500; + transition: all 0.3s ease-in; +} +.nav-link { + font-weight: bold; + font-size: 16px; + /* text-transform: uppercase; */ + transform: scale(1.2); + text-decoration: none; + color: #000; + padding: 20px 0px; + margin: 0px 20px; + display: inline-block; + position: relative; + opacity: 1; +} +.link { + font-size: 16px; + color: #000; + font-weight: 500; +} +.nav-link:hover { + opacity: 1; +} + +.nav-link::before { + transition: 300ms; + height: 2px; + content: ''; + position: absolute; + background-color: #000; + border-radius: 5px; + width: 50%; + /* opacity: 1; */ +} + +.nav-link-ltr::before { + width: 80%; + bottom: 20px; +} + +.nav-link-ltr:hover::before { + width: 100%; +} diff --git a/src/app/components/Navbar/Navbar.js b/src/app/components/Navbar/Navbar.js new file mode 100644 index 0000000..00ef989 --- /dev/null +++ b/src/app/components/Navbar/Navbar.js @@ -0,0 +1,59 @@ +'use client' + +import './Navbar.css' + +import Image from 'next/image' +import Link from 'next/link' +import React from 'react' +import bacpacLogo from '../../../assets/bacpacLogo.png' +import { usePathname } from 'next/navigation' + +function Navbar() { + const pathname = usePathname() + const menuContent = [ + { + name: 'Discover', + path: '/discover', + }, + { + name: 'About us', + path: '/aboutus', + }, + { + name: 'Site manual', + path: '/sitemanual', + }, + { + name: 'Community', + path: '/community', + }, + ] + return ( +
+
+
+ + BACPAC LOGO + +
+
+ {menuContent.map((item, index) => { + return ( +
  • + + {item.name} + +
  • + ) + })} +
    +
    +
    + + +
    +
    + ) +} + +export default Navbar diff --git a/src/app/components/originalComponents/ONavbar.js b/src/app/components/originalComponents/ONavbar.js new file mode 100644 index 0000000..b58aa9e --- /dev/null +++ b/src/app/components/originalComponents/ONavbar.js @@ -0,0 +1,34 @@ +import Image from 'next/image' +import Link from 'next/link' +import React from 'react' + +function Navbar() { + return ( +
    +
    +
    + + BACPAC LOGO + +
    +
    + {menuContent.map((item, index) => { + return ( +
  • + + {item.name} + +
  • + ) + })} +
    +
    +
    + + +
    +
    + ) +} + +export default Navbar diff --git a/src/app/discover/page.js b/src/app/discover/page.js new file mode 100644 index 0000000..5b86de9 --- /dev/null +++ b/src/app/discover/page.js @@ -0,0 +1,12 @@ +import Navbar from '../components/Navbar/Navbar' +import React from 'react' + +function Discover() { + return ( +
    + +
    + ) +} + +export default Discover diff --git a/src/app/globals.css b/src/app/globals.css index 3be321c..daa0569 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1,7 +1,7 @@ +@import url('https://fonts.googleapis.com/css2?family=Montserrat&family=Signika+Negative&display=swap'); @tailwind base; @tailwind components; @tailwind utilities; - :root { --foreground-rgb: 0, 0, 0; --background-start-rgb: 214, 219, 220; @@ -18,13 +18,33 @@ body { color: rgb(var(--foreground-rgb)); - background: linear-gradient( - to bottom, - transparent, - rgb(var(--background-end-rgb)) - ) - rgb(var(--background-start-rgb)); + background: linear-gradient(to bottom, transparent, rgb(var(--background-end-rgb))) rgb(var(--background-start-rgb)); + font-style: 'Montserrat', sans-serif; } .searchBox::-webkit-scrollbar { display: none; } +@layer components { + .btn { + @apply p-3 rounded-lg flex text-[#ffffff] items-center justify-center text-base; + } + .btn-primary { + @apply bg-[#BC9CFF]; + } + .btn-secondary { + @apply bg-[#6744FF]; + } + .center { + @apply flex items-center justify-center; + } + /* .center-v center's the element in vertical direction */ + .center-v { + @apply flex items-center; + } + .icons { + @apply w-8 h-10 cursor-pointer; + } + .icon { + @apply w-8 h-6 text-black; + } +} diff --git a/src/app/page.js b/src/app/page.js index 89a241d..f88ebc5 100644 --- a/src/app/page.js +++ b/src/app/page.js @@ -1,16 +1,25 @@ 'use client' -import { useEffect, useState } from 'react' - +import { AiOutlineSearch } from 'react-icons/ai' +import { BsStars } from 'react-icons/bs' import CollegeResult from './components/CollegeResult' -import jsonData from '../../data/university_data' +import Footer from './components/Footer/Footer' +import Image from 'next/image' +import Link from 'next/link' +import Navbar from './components/Navbar/Navbar' +import bacpacTitle from '../assets/bacpacTitle.png' +import bookImgLogo from '../assets/bookimg.png' +import discord from '../assets/discordLog.png' +import universityData from '../../data/university_data' +import { useState } from 'react' +import SearchBar from '../components/SearchBar' export default function Home() { const [open, setOpen] = useState(false) const [searchData, setSearchData] = useState([]) function handleSearch(e) { let input = e.target.value.toLowerCase() - const filterData = jsonData + const filterData = universityData .filter((item) => { let collegeName = item.name.toLowerCase() let collegeAddress = item.address.toLowerCase() @@ -21,25 +30,76 @@ export default function Home() { setSearchData(filterData) } return ( -
    -

    BacPac

    -
    - - {open && ( -
    - {searchData.map((item, index) => ( - - ))} +
    + +
    +
    + BACPAC +
    + +
    +
    + +

    Already part of your university community?

    +
    +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    +

    +

    First time user?

    +
    +

    Get familiar with the


    site first!

    +

    +
    +
    +
      +
    • + + Click here to learn about BACPAC + +
    • +
    • + + Click here to learn how to use BACPAC + +
    • +
    +
    +
    +
    + BACPAC +
    +
    +
    +
    +
    +

    Still have questions?

    +
    +
    + Our discord community is ready and eager to help you with
    + anything BACPAC related. Make friends along the way! +
    +
    +
    + BACPAC + +
    +
    Interested in managing our server? Leave a message!
    - )} -
    -
    +
    +
    +