diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000..e009d3b
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,20 @@
+{
+ "arrowParens": "always",
+ "bracketSpacing": true,
+ "endOfLine": "lf",
+ "htmlWhitespaceSensitivity": "css",
+ "insertPragma": false,
+ "jsxBracketSameLine": false,
+ "jsxSingleQuote": false,
+ "printWidth": 80,
+ "proseWrap": "preserve",
+ "quoteProps": "as-needed",
+ "requirePragma": false,
+ "semi": true,
+ "singleQuote": false,
+ "tabWidth": 4,
+ "trailingComma": "es5",
+ "useTabs": false,
+ "vueIndentScriptAndStyle": false,
+ "parser": "babel"
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index d0fe510..320ecca 100644
--- a/package.json
+++ b/package.json
@@ -1,34 +1,35 @@
{
- "name": "school_documents_front",
- "version": "0.1.0",
- "private": true,
- "dependencies": {
- "@testing-library/jest-dom": "^4.2.4",
- "@testing-library/react": "^9.3.2",
- "@testing-library/user-event": "^7.1.2",
- "react": "^16.13.1",
- "react-dom": "^16.13.1",
- "react-scripts": "3.4.3"
- },
- "scripts": {
- "start": "react-scripts start",
- "build": "react-scripts build",
- "test": "react-scripts test",
- "eject": "react-scripts eject"
- },
- "eslintConfig": {
- "extends": "react-app"
- },
- "browserslist": {
- "production": [
- ">0.2%",
- "not dead",
- "not op_mini all"
- ],
- "development": [
- "last 1 chrome version",
- "last 1 firefox version",
- "last 1 safari version"
- ]
- }
+ "name": "school_documents_front",
+ "version": "0.1.0",
+ "private": true,
+ "dependencies": {
+ "@testing-library/jest-dom": "^4.2.4",
+ "@testing-library/react": "^9.3.2",
+ "@testing-library/user-event": "^7.1.2",
+ "framer-motion": "2.3.0",
+ "react": "^16.13.1",
+ "react-dom": "^16.13.1",
+ "react-scripts": "3.4.3"
+ },
+ "scripts": {
+ "start": "react-scripts start",
+ "build": "react-scripts build",
+ "test": "react-scripts test",
+ "eject": "react-scripts eject"
+ },
+ "eslintConfig": {
+ "extends": "react-app"
+ },
+ "browserslist": {
+ "production": [
+ ">0.2%",
+ "not dead",
+ "not op_mini all"
+ ],
+ "development": [
+ "last 1 chrome version",
+ "last 1 firefox version",
+ "last 1 safari version"
+ ]
+ }
}
diff --git a/src/App.css b/src/App.css
index 74b5e05..fd36153 100644
--- a/src/App.css
+++ b/src/App.css
@@ -1,38 +1,4 @@
-.App {
- text-align: center;
-}
-
-.App-logo {
- height: 40vmin;
- pointer-events: none;
-}
-
-@media (prefers-reduced-motion: no-preference) {
- .App-logo {
- animation: App-logo-spin infinite 20s linear;
- }
-}
-
-.App-header {
- background-color: #282c34;
- min-height: 100vh;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- font-size: calc(10px + 2vmin);
- color: white;
-}
-
-.App-link {
- color: #61dafb;
-}
-
-@keyframes App-logo-spin {
- from {
- transform: rotate(0deg);
- }
- to {
- transform: rotate(360deg);
- }
-}
+body {
+ min-height: 100vh;
+ box-sizing: border-box;
+}
\ No newline at end of file
diff --git a/src/App.js b/src/App.js
deleted file mode 100644
index ce9cbd2..0000000
--- a/src/App.js
+++ /dev/null
@@ -1,26 +0,0 @@
-import React from 'react';
-import logo from './logo.svg';
-import './App.css';
-
-function App() {
- return (
-
- );
-}
-
-export default App;
diff --git a/src/App.jsx b/src/App.jsx
new file mode 100644
index 0000000..aa6d39f
--- /dev/null
+++ b/src/App.jsx
@@ -0,0 +1,13 @@
+import React from "react";
+import "./App.css";
+import Navbar from "./Navbar";
+
+function App() {
+ return (
+
+
+
+ );
+}
+
+export default App;
diff --git a/src/App.test.js b/src/App.test.js
deleted file mode 100644
index 4db7ebc..0000000
--- a/src/App.test.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import React from 'react';
-import { render } from '@testing-library/react';
-import App from './App';
-
-test('renders learn react link', () => {
- const { getByText } = render();
- const linkElement = getByText(/learn react/i);
- expect(linkElement).toBeInTheDocument();
-});
diff --git a/src/Navbar/filter.svg b/src/Navbar/filter.svg
new file mode 100644
index 0000000..844908c
--- /dev/null
+++ b/src/Navbar/filter.svg
@@ -0,0 +1,44 @@
+
+
+
diff --git a/src/Navbar/index.jsx b/src/Navbar/index.jsx
new file mode 100644
index 0000000..b74d739
--- /dev/null
+++ b/src/Navbar/index.jsx
@@ -0,0 +1,169 @@
+import React, { useState } from "react";
+
+import { motion } from "framer-motion";
+
+import "./main.css";
+
+import LogoImage from "./logo.png";
+import FilterIcon from "./filter.svg";
+import SearchIcon from "./search.svg";
+
+const Navbar = (props) => {
+ const [searchCollapsed, setSearchCollapsed] = useState(true);
+ const [filtersCollapsed, setFiltersCollapsed] = useState(true);
+
+ const searchVariants = {
+ open: {
+ width: "calc(100vw - 5vh)",
+ display: "block",
+ },
+ closed: {
+ width: "7vh",
+ transitionEnd: {
+ display: "none",
+ },
+ },
+ };
+
+ const navVariants = {
+ open: {
+ height: "100vh",
+ borderTopLeftRadius: 0,
+ borderTopRightRadius: 0,
+ },
+ closed: {
+ height: "12vh",
+ borderTopLeftRadius: "20px",
+ borderTopRightRadius: "20px",
+ },
+ };
+
+ const filtersVariants = {
+ open: {
+ height: "100vh",
+ padding: "2.5vh",
+ },
+ closed: {
+ height: 0,
+ padding: 0,
+ },
+ };
+
+ const transition = {
+ ease: "easeIn",
+ duration: 0.5,
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default Navbar;
diff --git a/src/Navbar/logo.png b/src/Navbar/logo.png
new file mode 100644
index 0000000..08ef74d
Binary files /dev/null and b/src/Navbar/logo.png differ
diff --git a/src/logo.svg b/src/Navbar/logo.svg
similarity index 100%
rename from src/logo.svg
rename to src/Navbar/logo.svg
diff --git a/src/Navbar/main.css b/src/Navbar/main.css
new file mode 100644
index 0000000..5298622
--- /dev/null
+++ b/src/Navbar/main.css
@@ -0,0 +1,101 @@
+#navbar {
+ position: fixed;
+ bottom: 0;
+ height: 12vh;
+ background-color: rgb(54, 54, 69);
+ width: 100%;
+ border-radius: 20px 20px 0 0;
+ padding: 2.5vh;
+ box-sizing: border-box;
+ color: #ffffff;
+}
+
+#navbar nav {
+ background-color: rgb(54, 54, 69);
+ display: flex;
+ gap: 1.5vh;
+ height: 7vh;
+ position: relative;
+ z-index: 1000;
+}
+
+#logo {
+ height: 7vh;
+ width: 7vh;
+ background-color: white;
+ border-radius: 100%;
+ padding: 1vh;
+ box-sizing: border-box;
+}
+
+#spacing {
+ flex-grow: 1;
+}
+
+.navButton {
+ background-color: rgb(255, 109, 109);
+ height: 7vh;
+ width: 7vh;
+ padding: 1.5vh;
+ border-radius: 100%;
+ border: none;
+ cursor: pointer;
+}
+
+#search {
+ z-index: 1000;
+}
+
+.navButton img {
+ height: 4vh;
+ width: 4vh;
+}
+
+#searchInput {
+ position: fixed;
+ width: 7vh;
+ bottom: 2.5vh;
+ right: 2.5vh;
+ height: 7vh;
+ border: none;
+ border-radius: 100vh;
+ box-sizing: border-box;
+ z-index: 500;
+}
+
+#filters {
+ position: fixed;
+ bottom: 0;
+ height: 0;
+ left: 0;
+ width: 100vw;
+ box-sizing: border-box;
+ padding: 2.5vh;
+ display: flex;
+ align-items: center;
+ flex-direction: column;
+ justify-content: center;
+ gap: 5vh;
+ padding-top: -12vh;
+ overflow: hidden;
+ z-index: 1;
+}
+
+#filters label h2 {
+ margin: 1.5vh 0;
+ text-align: center;
+}
+
+#filters select {
+ background-color: rgb(255, 109, 109);
+ border: none;
+ appearance: none;
+ padding: 1.5vh;
+ height: 7vh;
+ border-radius: 100vh;
+ width: 75vw;
+}
+
+body {
+ padding-bottom: 12vh;
+}
\ No newline at end of file
diff --git a/src/Navbar/search.svg b/src/Navbar/search.svg
new file mode 100644
index 0000000..0e64311
--- /dev/null
+++ b/src/Navbar/search.svg
@@ -0,0 +1,43 @@
+
+
+
diff --git a/src/index.js b/src/index.js
deleted file mode 100644
index f5185c1..0000000
--- a/src/index.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import React from 'react';
-import ReactDOM from 'react-dom';
-import './index.css';
-import App from './App';
-import * as serviceWorker from './serviceWorker';
-
-ReactDOM.render(
-
-
- ,
- document.getElementById('root')
-);
-
-// If you want your app to work offline and load faster, you can change
-// unregister() to register() below. Note this comes with some pitfalls.
-// Learn more about service workers: https://bit.ly/CRA-PWA
-serviceWorker.unregister();
diff --git a/src/index.jsx b/src/index.jsx
new file mode 100644
index 0000000..4a1582e
--- /dev/null
+++ b/src/index.jsx
@@ -0,0 +1,11 @@
+import React from "react";
+import ReactDOM from "react-dom";
+import "./index.css";
+import App from "./App";
+
+ReactDOM.render(
+
+
+ ,
+ document.getElementById("root")
+);
diff --git a/src/serviceWorker.js b/src/serviceWorker.js
deleted file mode 100644
index b04b771..0000000
--- a/src/serviceWorker.js
+++ /dev/null
@@ -1,141 +0,0 @@
-// This optional code is used to register a service worker.
-// register() is not called by default.
-
-// This lets the app load faster on subsequent visits in production, and gives
-// it offline capabilities. However, it also means that developers (and users)
-// will only see deployed updates on subsequent visits to a page, after all the
-// existing tabs open on the page have been closed, since previously cached
-// resources are updated in the background.
-
-// To learn more about the benefits of this model and instructions on how to
-// opt-in, read https://bit.ly/CRA-PWA
-
-const isLocalhost = Boolean(
- window.location.hostname === 'localhost' ||
- // [::1] is the IPv6 localhost address.
- window.location.hostname === '[::1]' ||
- // 127.0.0.0/8 are considered localhost for IPv4.
- window.location.hostname.match(
- /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
- )
-);
-
-export function register(config) {
- if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
- // The URL constructor is available in all browsers that support SW.
- const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
- if (publicUrl.origin !== window.location.origin) {
- // Our service worker won't work if PUBLIC_URL is on a different origin
- // from what our page is served on. This might happen if a CDN is used to
- // serve assets; see https://github.com/facebook/create-react-app/issues/2374
- return;
- }
-
- window.addEventListener('load', () => {
- const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
-
- if (isLocalhost) {
- // This is running on localhost. Let's check if a service worker still exists or not.
- checkValidServiceWorker(swUrl, config);
-
- // Add some additional logging to localhost, pointing developers to the
- // service worker/PWA documentation.
- navigator.serviceWorker.ready.then(() => {
- console.log(
- 'This web app is being served cache-first by a service ' +
- 'worker. To learn more, visit https://bit.ly/CRA-PWA'
- );
- });
- } else {
- // Is not localhost. Just register service worker
- registerValidSW(swUrl, config);
- }
- });
- }
-}
-
-function registerValidSW(swUrl, config) {
- navigator.serviceWorker
- .register(swUrl)
- .then(registration => {
- registration.onupdatefound = () => {
- const installingWorker = registration.installing;
- if (installingWorker == null) {
- return;
- }
- installingWorker.onstatechange = () => {
- if (installingWorker.state === 'installed') {
- if (navigator.serviceWorker.controller) {
- // At this point, the updated precached content has been fetched,
- // but the previous service worker will still serve the older
- // content until all client tabs are closed.
- console.log(
- 'New content is available and will be used when all ' +
- 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
- );
-
- // Execute callback
- if (config && config.onUpdate) {
- config.onUpdate(registration);
- }
- } else {
- // At this point, everything has been precached.
- // It's the perfect time to display a
- // "Content is cached for offline use." message.
- console.log('Content is cached for offline use.');
-
- // Execute callback
- if (config && config.onSuccess) {
- config.onSuccess(registration);
- }
- }
- }
- };
- };
- })
- .catch(error => {
- console.error('Error during service worker registration:', error);
- });
-}
-
-function checkValidServiceWorker(swUrl, config) {
- // Check if the service worker can be found. If it can't reload the page.
- fetch(swUrl, {
- headers: { 'Service-Worker': 'script' },
- })
- .then(response => {
- // Ensure service worker exists, and that we really are getting a JS file.
- const contentType = response.headers.get('content-type');
- if (
- response.status === 404 ||
- (contentType != null && contentType.indexOf('javascript') === -1)
- ) {
- // No service worker found. Probably a different app. Reload the page.
- navigator.serviceWorker.ready.then(registration => {
- registration.unregister().then(() => {
- window.location.reload();
- });
- });
- } else {
- // Service worker found. Proceed as normal.
- registerValidSW(swUrl, config);
- }
- })
- .catch(() => {
- console.log(
- 'No internet connection found. App is running in offline mode.'
- );
- });
-}
-
-export function unregister() {
- if ('serviceWorker' in navigator) {
- navigator.serviceWorker.ready
- .then(registration => {
- registration.unregister();
- })
- .catch(error => {
- console.error(error.message);
- });
- }
-}
diff --git a/src/setupTests.js b/src/setupTests.js
deleted file mode 100644
index 74b1a27..0000000
--- a/src/setupTests.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// jest-dom adds custom jest matchers for asserting on DOM nodes.
-// allows you to do things like:
-// expect(element).toHaveTextContent(/react/i)
-// learn more: https://github.com/testing-library/jest-dom
-import '@testing-library/jest-dom/extend-expect';
diff --git a/yarn.lock b/yarn.lock
index feea970..8e8eaf0 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1095,6 +1095,18 @@
resolved "https://registry.yarnpkg.com/@csstools/normalize.css/-/normalize.css-10.1.0.tgz#f0950bba18819512d42f7197e56c518aa491cf18"
integrity sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg==
+"@emotion/is-prop-valid@^0.8.2":
+ version "0.8.8"
+ resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a"
+ integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==
+ dependencies:
+ "@emotion/memoize" "0.7.4"
+
+"@emotion/memoize@0.7.4":
+ version "0.7.4"
+ resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb"
+ integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==
+
"@hapi/address@2.x.x":
version "2.1.4"
resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5"
@@ -1309,6 +1321,22 @@
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b"
integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==
+"@popmotion/easing@^1.0.1", "@popmotion/easing@^1.0.2":
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/@popmotion/easing/-/easing-1.0.2.tgz#17d925c45b4bf44189e5a38038d149df42d8c0b4"
+ integrity sha512-IkdW0TNmRnWTeWI7aGQIVDbKXPWHVEYdGgd5ZR4SH/Ty/61p63jCjrPxX1XrR7IGkl08bjhJROStD7j+RKgoIw==
+
+"@popmotion/popcorn@^0.4.2":
+ version "0.4.4"
+ resolved "https://registry.yarnpkg.com/@popmotion/popcorn/-/popcorn-0.4.4.tgz#a5f906fccdff84526e3fcb892712d7d8a98d6adc"
+ integrity sha512-jYO/8319fKoNLMlY4ZJPiPu8Ea8occYwRZhxpaNn/kZsK4QG2E7XFlXZMJBsTWDw7I1i0uaqyC4zn1nwEezLzg==
+ dependencies:
+ "@popmotion/easing" "^1.0.1"
+ framesync "^4.0.1"
+ hey-listen "^1.0.8"
+ style-value-types "^3.1.7"
+ tslib "^1.10.0"
+
"@sheerun/mutationobserver-shim@^0.3.2":
version "0.3.3"
resolved "https://registry.yarnpkg.com/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.3.tgz#5405ee8e444ed212db44e79351f0c70a582aae25"
@@ -4685,6 +4713,28 @@ fragment-cache@^0.2.1:
dependencies:
map-cache "^0.2.2"
+framer-motion@2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-2.3.0.tgz#700c3d6a554c86bfa6a2d96e25f25829667cd0b4"
+ integrity sha512-zX6V5vz3joMzacqV7UpiHKUtqLMmU/YsVM6KpeRCi65KjUiymUX5O2jkpR3cCdlr1DkJ1yWUjBWY7xyiO834VA==
+ dependencies:
+ "@popmotion/easing" "^1.0.2"
+ "@popmotion/popcorn" "^0.4.2"
+ framesync "^4.0.4"
+ hey-listen "^1.0.8"
+ popmotion "9.0.0-beta-8"
+ style-value-types "^3.1.9"
+ tslib "^1.10.0"
+ optionalDependencies:
+ "@emotion/is-prop-valid" "^0.8.2"
+
+framesync@^4.0.1, framesync@^4.0.4:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/framesync/-/framesync-4.1.0.tgz#69a8db3ca432dc70d6a76ba882684a1497ef068a"
+ integrity sha512-MmgZ4wCoeVxNbx2xp5hN/zPDCbLSKiDt4BbbslK7j/pM2lg5S0vhTNv1v8BCVb99JPIo6hXBFdwzU7Q4qcAaoQ==
+ dependencies:
+ hey-listen "^1.0.5"
+
fresh@0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
@@ -5015,6 +5065,11 @@ hex-color-regex@^1.1.0:
resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e"
integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==
+hey-listen@^1.0.5, hey-listen@^1.0.8:
+ version "1.0.8"
+ resolved "https://registry.yarnpkg.com/hey-listen/-/hey-listen-1.0.8.tgz#8e59561ff724908de1aa924ed6ecc84a56a9aa68"
+ integrity sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==
+
hmac-drbg@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
@@ -7624,6 +7679,18 @@ pnp-webpack-plugin@1.6.4:
dependencies:
ts-pnp "^1.1.6"
+popmotion@9.0.0-beta-8:
+ version "9.0.0-beta-8"
+ resolved "https://registry.yarnpkg.com/popmotion/-/popmotion-9.0.0-beta-8.tgz#f5a709f11737734e84f2a6b73f9bcf25ee30c388"
+ integrity sha512-6eQzqursPvnP7ePvdfPeY4wFHmS3OLzNP8rJRvmfFfEIfpFqrQgLsM50Gd9AOvGKJtYJOFknNG+dsnzCpgIdAA==
+ dependencies:
+ "@popmotion/easing" "^1.0.1"
+ "@popmotion/popcorn" "^0.4.2"
+ framesync "^4.0.4"
+ hey-listen "^1.0.8"
+ style-value-types "^3.1.6"
+ tslib "^1.10.0"
+
portfinder@^1.0.26:
version "1.0.28"
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778"
@@ -9812,6 +9879,14 @@ style-loader@0.23.1:
loader-utils "^1.1.0"
schema-utils "^1.0.0"
+style-value-types@^3.1.6, style-value-types@^3.1.7, style-value-types@^3.1.9:
+ version "3.1.9"
+ resolved "https://registry.yarnpkg.com/style-value-types/-/style-value-types-3.1.9.tgz#faf7da660d3f284ed695cff61ea197d85b9122cc"
+ integrity sha512-050uqgB7WdvtgacoQKm+4EgKzJExVq0sieKBQQtJiU3Muh6MYcCp4T3M8+dfl6VOF2LR0NNwXBP1QYEed8DfIw==
+ dependencies:
+ hey-listen "^1.0.8"
+ tslib "^1.10.0"
+
stylehacks@^4.0.0:
version "4.0.3"
resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-4.0.3.tgz#6718fcaf4d1e07d8a1318690881e8d96726a71d5"