diff --git a/assets/index/images/Icon.jpg b/assets/index/images/Icon.jpg deleted file mode 100644 index 98b3ae17..00000000 Binary files a/assets/index/images/Icon.jpg and /dev/null differ diff --git a/assets/index/images/MeraPro-V4Oex.otf b/assets/index/images/MeraPro-V4Oex.otf deleted file mode 100644 index 48dee011..00000000 Binary files a/assets/index/images/MeraPro-V4Oex.otf and /dev/null differ diff --git a/assets/index/images/Picture_1.jpg b/assets/index/images/Picture_1.jpg new file mode 100644 index 00000000..5a952b17 Binary files /dev/null and b/assets/index/images/Picture_1.jpg differ diff --git a/assets/index/images/Picture_2.jpg b/assets/index/images/Picture_2.jpg new file mode 100644 index 00000000..56b1cd70 Binary files /dev/null and b/assets/index/images/Picture_2.jpg differ diff --git a/assets/index/images/Screenshot 2024-12-11 194353.png b/assets/index/images/Screenshot 2024-12-11 194353.png deleted file mode 100644 index 38072c5d..00000000 Binary files a/assets/index/images/Screenshot 2024-12-11 194353.png and /dev/null differ diff --git a/assets/index/images/favicon.ico b/assets/index/images/favicon.ico deleted file mode 100644 index 97e88ea8..00000000 Binary files a/assets/index/images/favicon.ico and /dev/null differ diff --git a/assets/index/images/hero.svg b/assets/index/images/hero.svg deleted file mode 100644 index e55d8b1a..00000000 --- a/assets/index/images/hero.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/index/images/icons8-magnifying-glass.svg b/assets/index/images/icons8-magnifying-glass.svg deleted file mode 100644 index 7f1664f3..00000000 --- a/assets/index/images/icons8-magnifying-glass.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/index/images/notepad.png b/assets/index/images/notepad.png deleted file mode 100644 index f7d80b4d..00000000 Binary files a/assets/index/images/notepad.png and /dev/null differ diff --git a/aurora.css b/aurora.css deleted file mode 100644 index 38978cde..00000000 --- a/aurora.css +++ /dev/null @@ -1,60 +0,0 @@ -/* Aurora Background Effect */ -@keyframes aurora { - from { - background-position: 50% 50%, 50% 50%; - } - to { - background-position: 350% 50%, 350% 50%; - } -} - -.aurora-background { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: -1; - overflow: hidden; - pointer-events: none; -} - -.aurora-inner { - position: absolute; - inset: -10px; - background-image: - repeating-linear-gradient(100deg, #fff 0%, #fff 7%, transparent 10%, transparent 12%, #fff 16%), - repeating-linear-gradient(100deg, #3b82f6 10%, #a5b4fc 15%, #93c5fd 20%, #ddd6fe 25%, #60a5fa 30%); - background-size: 300%, 200%; - background-position: 50% 50%, 50% 50%; - opacity: 0.5; - filter: blur(10px); - animation: aurora 60s linear infinite; -} - -.dark .aurora-inner { - background-image: - repeating-linear-gradient(100deg, #000 0%, #000 7%, transparent 10%, transparent 12%, #000 16%), - repeating-linear-gradient(100deg, #3b82f6 10%, #a5b4fc 15%, #93c5fd 20%, #ddd6fe 25%, #60a5fa 30%); - filter: blur(10px) invert(0); -} - -/* Radial mask for aurora effect */ -.aurora-inner::after { - content: ""; - position: absolute; - inset: 0; - background-image: - repeating-linear-gradient(100deg, #fff 0%, #fff 7%, transparent 10%, transparent 12%, #fff 16%), - repeating-linear-gradient(100deg, #3b82f6 10%, #a5b4fc 15%, #93c5fd 20%, #ddd6fe 25%, #60a5fa 30%); - background-size: 200%, 100%; - background-attachment: fixed; - mix-blend-mode: difference; - mask-image: radial-gradient(ellipse at 100% 0%, black 10%, transparent 70%); -} - -.dark .aurora-inner::after { - background-image: - repeating-linear-gradient(100deg, #000 0%, #000 7%, transparent 10%, transparent 12%, #000 16%), - repeating-linear-gradient(100deg, #3b82f6 10%, #a5b4fc 15%, #93c5fd 20%, #ddd6fe 25%, #60a5fa 30%); -} \ No newline at end of file diff --git a/components/footer.html b/components/footer.html new file mode 100644 index 00000000..4d32a99e --- /dev/null +++ b/components/footer.html @@ -0,0 +1,171 @@ + + + + + + + + + NotesVault - Footer + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/header.css b/components/header.css deleted file mode 100644 index 3d828603..00000000 --- a/components/header.css +++ /dev/null @@ -1,176 +0,0 @@ -@import url("https://fonts.googleapis.com/css2?family=Open+Sans:wght@600&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900"); - -#header { - top: 0; - left: 0; - width: 79vw; - z-index: 1000; - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: center; - padding: 15px 10vw; - margin: 0; - } - - .navbar { - display: flex; - justify-content: space-between; - align-items: center; - padding: 24px 0px; - max-width: 80vw; - margin: 0 auto; - background-color: white; - width: 100%; - position: relative; -} - -/* Logo styling */ -.navbar-left .logo { - font-family: "Poppins", sans-serif; - font-weight: 500; - font-style: normal; - font-size: calc(12px + 1vw); -} - - /* Flex box for left/right header items */ - #header div { - display: flex; - } - - /* Ensures text/icons inside header are centered vertically */ - #header div p { - display: flex; - align-items: center; - } - - /* Left section spacing */ -#header #header-title-box { - margin-left: 5vw; -} - -#header-title-box { - display: flex; - align-items: center; -} - -/* Title style */ -#header #header-title-box #header-title { - font-weight: 500; - font-style: normal; - font-size: calc(12px + 1vw); -} - -#header #header-navigation { - width: 40vw; - display: flex; - justify-content: space-between; - align-items: center; -} - -#header #header-navigation p { - font-family: "Poppins", sans-serif; - font-weight: 300; - font-style: normal; - font-size: calc(9px + 0.4vw); - transition: font-weight 0.1s, text-decoration 0.1s; - cursor: pointer; -} - -.nav-menu { - display: flex; - gap: 20px; -} - -.nav-menu a { - text-decoration: none; - overflow: hidden; - position: relative; - display: inline-block; - color: #000000; - font-weight: 700; - font-style: normal; - font-family: "Poppins", sans-serif; -} - -.nav-menu a::before, -.nav-menu a::after { - content: ""; - position: absolute; - left: 0; - width: 100%; -} - -.nav-menu a::before { - background-color: #347034; - height: 2px; - bottom: 0; - transform: scaleX(0); - transform-origin: 100% 50%; - transition: transform 0.3s cubic-bezier(0.76, 0, 0.24, 1); -} - -.nav-menu a::after { - content: attr(data-replace); - height: 100%; - top: 0; - transform: translate3d(200%, 0, 0); - transform-origin: 100% 50%; - transition: transform 0.3s cubic-bezier(0.76, 0, 0.24, 1); - color: #017c01; - position: absolute; -} - -.nav-menu a span { - display: inline-block; - transition: transform 0.3s cubic-bezier(0.76, 0, 0.24, 1); -} - - -.nav-menu a:hover span { - transform: translate3d(-200%, 0, 0); -} - -.nav-menu a:hover::before { - transform-origin: 0% 50%; - transform: scaleX(1); -} - -.nav-menu a:hover::after { - transform: translate3d(0, 0, 0); -} - -#header #header-navigation p:hover { - font-weight: 400; - text-decoration: underline; -} - -#header #header-signup-box { - cursor: pointer; - display: flex; - align-items: center; - gap: 4px; -} - -#header #header-signup-box p { - display: inline-flex; - font-family: "Poppins", sans-serif; - font-weight: 300; - font-style: normal; - font-size: calc(9px + 0.4vw); - background-color: #163d3b; - padding: 15px 30px; - color: #dff8f8; - border-radius: 30px; - vertical-align: middle; - align-items: center; - max-height: 50px; - transition: all 0.3s ease; -} - -#header #header-signup-box p:hover { - background-color: #1f5c59; - color: #ffffff; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); - transform: translateY(-1px); -} \ No newline at end of file diff --git a/components/header.html b/components/header.html index fdf184c8..80d91b6b 100644 --- a/components/header.html +++ b/components/header.html @@ -1,17 +1,209 @@ - + + + + + + + + + NotesVault - Header + + + + + + + + + + + + + + + + + + + + + diff --git a/components/header.js b/components/header.js deleted file mode 100644 index 5e518146..00000000 --- a/components/header.js +++ /dev/null @@ -1,7 +0,0 @@ -document.addEventListener('DOMContentLoaded', () => { - fetch('../components/header.html') - .then(res => res.text()) - .then(data => { - document.getElementById('header-holder').innerHTML = data; - }); - }); diff --git a/data/notes.json b/data/notes.json index 7901d7a5..3741d68f 100644 --- a/data/notes.json +++ b/data/notes.json @@ -1,86 +1,52 @@ [ { - "title": "Mathematics I", - "branch": "CSE", - "semester": "1", - "subject": "Maths", - "link": "https://example.com/notes/maths1.pdf" - }, - { - "title": "Operating System Notes", - "branch": "CSE", - "semester": "2", - "subject": "OS", - "link": "https://example.com/notes/os.pdf" - }, - { - "title": "DBMS Concepts", - "branch": "CSE", - "semester": "2", - "subject": "DBMS", - "link": "https://example.com/notes/dbms.pdf" - }, - { - "title": "Intro to AI", - "branch": "CSE AIML", - "semester": "1", - "subject": "AI", - "link": "https://example.com/notes/ai.pdf" - }, - { - "title": "Machine Learning Basics", - "branch": "CSE AIML", - "semester": "2", - "subject": "ML", - "link": "https://example.com/notes/ml.pdf" - }, - { - "title": "Python for AIML", - "branch": "CSE AIML", - "semester": "2", - "subject": "Python", - "link": "https://example.com/notes/python_aiml.pdf" - }, - { - "title": "IoT Fundamentals", - "branch": "CSE IOT", - "semester": "1", - "subject": "IoT Fundamentals", - "link": "https://example.com/notes/iot_fundamentals.pdf" - }, - { - "title": "Sensor Technologies", - "branch": "CSE IOT", - "semester": "2", - "subject": "Sensors", - "link": "https://example.com/notes/sensors.pdf" - }, - { - "title": "Microcontroller Guide", - "branch": "CSE IOT", - "semester": "2", - "subject": "Microcontrollers", - "link": "https://example.com/notes/microcontrollers.pdf" - }, - { - "title": "Data Science Intro", - "branch": "CSE DS", - "semester": "1", - "subject": "Data Science Basics", - "link": "https://example.com/notes/ds_basics.pdf" - }, - { - "title": "Statistics Notes", - "branch": "CSE DS", - "semester": "2", - "subject": "Statistics", - "link": "https://example.com/notes/statistics.pdf" - }, - { - "title": "Python for Data Science", - "branch": "CSE DS", - "semester": "2", - "subject": "Python for DS", - "link": "https://example.com/notes/python_ds.pdf" + "_id": "note1", + "title": "Data Structures & Algorithms Basics", + "branch": "Computer Science", + "semester": "3rd", + "description": "Comprehensive notes on fundamental data structures (arrays, linked lists, trees, graphs) and common algorithms (sorting, searching).", + "uploader": "Alice Smith", + "uploadDate": "2023-03-15", + "filePath": "http://example.com/notes/dsa_basics.pdf" + }, + { + "_id": "note2", + "title": "Digital Electronics Principles", + "branch": "Electronics Engineering", + "semester": "4th", + "description": "Detailed notes covering logic gates, Boolean algebra, combinational and sequential circuits.", + "uploader": "Bob Johnson", + "uploadDate": "2023-04-20", + "filePath": "http://example.com/notes/digital_electronics.pdf" + }, + { + "_id": "note3", + "title": "Thermodynamics for Mechanical Engineers", + "branch": "Mechanical Engineering", + "semester": "5th", + "description": "Concepts of thermodynamics, laws, cycles, and their applications in various systems.", + "uploader": "Charlie Brown", + "uploadDate": "2023-05-10", + "filePath": "http://example.com/notes/thermodynamics.pdf" + }, + { + "_id": "note4", + "title": "Object-Oriented Programming with Java", + "branch": "Information Technology", + "semester": "3rd", + "description": "Introduction to OOP principles using Java: classes, objects, inheritance, polymorphism, abstraction, and encapsulation.", + "uploader": "Alice Smith", + "uploadDate": "2023-06-01", + "filePath": "http://example.com/notes/oop_java.pdf" + }, + { + "_id": "note5", + "title": "Calculus I - Differentiation", + "branch": "Mathematics", + "semester": "1st", + "description": "Basic concepts of differentiation, limits, continuity, and applications.", + "uploader": "David Lee", + "uploadDate": "2023-07-10", + "filePath": "http://example.com/notes/calculus1.pdf" } ] diff --git a/data/parameters.json b/data/parameters.json new file mode 100644 index 00000000..3a9c2c4b --- /dev/null +++ b/data/parameters.json @@ -0,0 +1,104 @@ +{ + "branches": [ + { + "name": "CSE", + "semesters": [ + { + "semester": 1, + "subjects": [ + {"BT101": "Engineering Chemistry"}, + {"BT102": "Mathematics-I"}, + {"BT103": "English for Communication"}, + {"BT104": "Basic Electrical & Electronics Engineering"}, + {"BT105": "Engineering Graphics"} + ] + }, + { + "semester": 2, + "subjects": [ + {"BT201": "Engineering Physics"}, + {"BT202": "Mathematics-II"}, + {"BT203": "Basic Mechanical Engineering"}, + {"BT204": "Basic Civil Engineering & Mechanics"}, + {"BT205": "Basic Computer Engineering"} + ] + } + ] + }, + { + "name": "CSE-AIML", + "semesters": [ + { + "semester": 1, + "subjects": [ + {"BT101": "Engineering Chemistry"}, + {"BT102": "Mathematics-I"}, + {"BT103": "English for Communication"}, + {"BT104": "Basic Electrical & Electronics Engineering"}, + {"BT105": "Engineering Graphics"} + ] + }, + { + "semester": 2, + "subjects": [ + {"BT201": "Engineering Physics"}, + {"BT202": "Mathematics-II"}, + {"BT203": "Basic Mechanical Engineering"}, + {"BT204": "Basic Civil Engineering & Mechanics"}, + {"BT205": "Basic Computer Engineering"} + ] + } + ] + }, + { + "name": "CSE-IOT", + "semesters": [ + { + "semester": 1, + "subjects": [ + {"BT101": "Engineering Chemistry"}, + {"BT102": "Mathematics-I"}, + {"BT103": "English for Communication"}, + {"BT104": "Basic Electrical & Electronics Engineering"}, + {"BT105": "Engineering Graphics"} + ] + }, + { + "semester": 2, + "subjects": [ + {"BT201": "Engineering Physics"}, + {"BT202": "Mathematics-II"}, + {"BT203": "Basic Mechanical Engineering"}, + {"BT204": "Basic Civil Engineering & Mechanics"}, + {"BT205": "Basic Computer Engineering"} + ] + } + ] + }, + { + "name": "CSE-DS", + "semesters": [ + { + "semester": 1, + "subjects": [ + {"BT101": "Engineering Chemistry"}, + {"BT102": "Mathematics-I"}, + {"BT103": "English for Communication"}, + {"BT104": "Basic Electrical & Electronics Engineering"}, + {"BT105": "Engineering Graphics"} + ] + }, + { + "semester": 2, + "subjects": [ + {"BT201": "Engineering Physics"}, + {"BT202": "Mathematics-II"}, + {"BT203": "Basic Mechanical Engineering"}, + {"BT204": "Basic Civil Engineering & Mechanics"}, + {"BT205": "Basic Computer Engineering"} + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/data/search_parameters/parameters.json b/data/search_parameters/parameters.json deleted file mode 100644 index 1c58fa75..00000000 --- a/data/search_parameters/parameters.json +++ /dev/null @@ -1,103 +0,0 @@ -{ - "branches": [ - { - "name": "CSE", - "semesters": [ - { - "semester": 1, - "subjects": [ - {"BT101": "Engineering Chemistry"}, - {"BT102": "Mathematics-I"}, - {"BT103": "English for Communication"}, - {"BT104": "Basic Electrical & Electronics Engineering"}, - {"BT105": "Engineering Graphics"} - ] - }, - { - "semester": 2, - "subjects": [ - {"BT201": "Engineering Physics"}, - {"BT202": "Mathematics-II"}, - {"BT203": "Basic Mechanical Engineering"}, - {"BT204": "Basic Civil Engineering & Mechanics"}, - {"BT205": "Basic Computer Engineering"} - ] - } - ] - }, - { - "name": "CSE-AIML", - "semesters": [ - { - "semester": 1, - "subjects": [ - {"BT201": "Engineering Physics"}, - {"BT102": "Mathematics-I"}, - {"BT203": "Basic Mechanical Engineering"}, - {"BT204": "Basic Civil Engineering & Mechanics"}, - {"BT205": "Basic Computer Engineering"} - ] - }, - { - "semester": 2, - "subjects": [ - {"BT101": "Engineering Chemistry"}, - {"BT202": "Mathematics-II"}, - {"BT103": "English for Communication"}, - {"BT104": "Basic Electrical & Electronics Engineering"}, - {"BT105": "Engineering Graphics"} - ] - } - ] - }, - { - "name": "CSE-IOT", - "semesters": [ - { - "semester": 1, - "subjects": [ - {"BT201": "Engineering Physics"}, - {"BT102": "Mathematics-I"}, - {"BT203": "Basic Mechanical Engineering"}, - {"BT204": "Basic Civil Engineering & Mechanics"}, - {"BT205": "Basic Computer Engineering"} - ] - }, - { - "semester": 2, - "subjects": [ - {"BT101": "Engineering Chemistry"}, - {"BT202": "Mathematics-II"}, - {"BT103": "English for Communication"}, - {"BT104": "Basic Electrical & Electronics Engineering"}, - {"BT105": "Engineering Graphics"} - ] - } - ] - }, - { - "name": "CSE-DS", - "semesters": [ - { - "semester": 1, - "subjects": [ - {"BT201": "Engineering Physics"}, - {"BT102": "Mathematics-I"}, - {"BT203": "Basic Mechanical Engineering"}, - {"BT204": "Basic Civil Engineering & Mechanics"}, - {"BT205": "Basic Computer Engineering"} - ] - }, - { - "semester": 2, - "subjects": [ - {"BT101": "Engineering Chemistry"}, - {"BT202": "Mathematics-II"}, - {"BT103": "English for Communication"}, - {"BT104": "Basic Electrical & Electronics Engineering"}, - {"BT105": "Engineering Graphics"} - ] - } - ] - }, "CSBS", "EX", "EE", "EC", "AIR", "ME", "CE"] -} \ No newline at end of file diff --git a/features.html b/features.html deleted file mode 100644 index 2fd9a070..00000000 --- a/features.html +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - NotesVault - Features - - - - - -
-

✨ Key Features of NotesVault

-

Empowering your study experience with simplicity and speed.

- -
-
-

📚 Organized by Branch & Semester

-

Sort your notes smartly by branch and semester, making it easier to browse content.

-
-
-

🔍 Smart Search

-

Search notes by subject, semester, or custom tags with instant results.

-
-
-

📝 Jotpad

-

Take quick notes or summaries anytime without switching tabs.

-
-
-

📤 Easy Upload

-

Upload your notes with a clean form or drag & drop interface.

-
-
-

🌙 Light/Dark Mode

-

Switch themes for your comfort and improved readability anytime.

-
-
-

🧾 License-Friendly

-

Open-source and transparent — explore the GitHub repo and contribute easily.

-
-
-
- - - - - diff --git a/glassy-ui.css b/glassy-ui.css deleted file mode 100644 index 2cabbc96..00000000 --- a/glassy-ui.css +++ /dev/null @@ -1,432 +0,0 @@ -/* Glassy UI Styles */ - -/* Glassy Button Base */ -.glassy-button { - background: rgba(255, 255, 255, 0.15); - -webkit-backdrop-filter: blur(10px); - backdrop-filter: blur(10px); - border: 1px solid rgba(255, 255, 255, 0.2); - border-radius: 15px; - box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); - transition: all 0.3s ease; - position: relative; - overflow: hidden; -} - -.glassy-button::before { - content: ''; - position: absolute; - top: 0; - left: -100%; - width: 100%; - height: 100%; - background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); - transition: left 0.5s; -} - -.glassy-button:hover::before { - left: 100%; -} - -.glassy-button:hover { - background: rgba(255, 255, 255, 0.25); - border: 1px solid rgba(255, 255, 255, 0.3); - transform: translateY(-2px); - box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15); -} - -/* Main Action Buttons */ -.try-box { - background: rgba(255, 255, 255, 0.15) !important; - -webkit-backdrop-filter: blur(10px) !important; - backdrop-filter: blur(10px) !important; - border: 1px solid rgba(255, 255, 255, 0.2) !important; - border-radius: 15px !important; - padding: 12px 24px !important; - color: #333 !important; - text-decoration: none !important; - font-weight: 500 !important; - box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1) !important; - transition: all 0.3s ease !important; - position: relative !important; - overflow: hidden !important; - cursor: pointer !important; -} - -.try-box::before { - content: ''; - position: absolute; - top: 0; - left: -100%; - width: 100%; - height: 100%; - background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent); - transition: left 0.5s; -} - -.try-box:hover::before { - left: 100%; -} - -.try-box:hover { - background: rgba(255, 255, 255, 0.25) !important; - border: 1px solid rgba(255, 255, 255, 0.3) !important; - transform: translateY(-2px) !important; - box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15) !important; -} - -/* Feature Cards */ -.feature-card { - background: rgba(255, 255, 255, 0.1) !important; - -webkit-backdrop-filter: blur(15px) !important; - backdrop-filter: blur(15px) !important; - border: 1px solid rgba(255, 255, 255, 0.2) !important; - border-radius: 20px !important; - padding: 30px 20px !important; - box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1) !important; - transition: all 0.3s ease !important; - position: relative !important; - overflow: hidden !important; - margin: 15px !important; -} - -.feature-card::before { - content: ''; - position: absolute; - top: 0; - left: -100%; - width: 100%; - height: 100%; - background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent); - transition: left 0.6s; -} - -.feature-card:hover::before { - left: 100%; -} - -.feature-card:hover { - background: rgba(255, 255, 255, 0.2) !important; - border: 1px solid rgba(255, 255, 255, 0.3) !important; - transform: translateY(-5px) scale(1.02) !important; - box-shadow: 0 15px 50px rgba(0, 0, 0, 0.2) !important; -} - -.feature-card svg { - margin-bottom: 15px !important; - filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.1)) !important; -} - -.feature-title { - font-weight: 600 !important; - margin-bottom: 10px !important; - color: #333 !important; -} - -.feature-desc, .card-text { - color: #555 !important; - line-height: 1.5 !important; -} - -/* Card class for existing cards */ -.card { - background: rgba(255, 255, 255, 0.1) !important; - -webkit-backdrop-filter: blur(15px) !important; - backdrop-filter: blur(15px) !important; - border: 1px solid rgba(255, 255, 255, 0.2) !important; - border-radius: 20px !important; - padding: 30px 20px !important; - box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1) !important; - transition: all 0.3s ease !important; - position: relative !important; - overflow: hidden !important; - margin: 15px !important; -} - -.card::before { - content: ''; - position: absolute; - top: 0; - left: -100%; - width: 100%; - height: 100%; - background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent); - transition: left 0.6s; -} - -.card:hover::before { - left: 100%; -} - -.card:hover { - background: rgba(255, 255, 255, 0.2) !important; - border: 1px solid rgba(255, 255, 255, 0.3) !important; - transform: translateY(-5px) scale(1.02) !important; - box-shadow: 0 15px 50px rgba(0, 0, 0, 0.2) !important; -} - -/* Header Sign Up Button */ -#header-signup-box a { - background: rgba(255, 255, 255, 0.15) !important; - -webkit-backdrop-filter: blur(10px) !important; - backdrop-filter: blur(10px) !important; - border: 1px solid rgba(255, 255, 255, 0.2) !important; - border-radius: 12px !important; - padding: 8px 16px !important; - transition: all 0.3s ease !important; - position: relative !important; - overflow: hidden !important; - text-decoration: none !important; -} - -#header-signup-box a::before { - content: ''; - position: absolute; - top: 0; - left: -100%; - width: 100%; - height: 100%; - background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); - transition: left 0.5s; -} - -#header-signup-box a:hover::before { - left: 100%; -} - -#header-signup-box a:hover { - background: rgba(255, 255, 255, 0.25) !important; - border: 1px solid rgba(255, 255, 255, 0.3) !important; - transform: translateY(-1px) !important; - box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1) !important; -} - -/* Search Box */ -.main-right-search-form-input { - background: rgba(255, 255, 255, 0.15) !important; - -webkit-backdrop-filter: blur(10px) !important; - backdrop-filter: blur(10px) !important; - border: 1px solid rgba(255, 255, 255, 0.2) !important; - border-radius: 25px !important; - padding: 12px 20px !important; - color: #333 !important; - transition: all 0.3s ease !important; -} - -.main-right-search-form-input:focus { - background: rgba(255, 255, 255, 0.25) !important; - border: 1px solid rgba(255, 255, 255, 0.3) !important; - outline: none !important; - box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1) !important; -} - -.main-right-search-form-input::placeholder { - color: rgba(51, 51, 51, 0.7) !important; -} - -/* Search Box Container */ -.Search-box { - background: rgba(0, 0, 0, 0.1) !important; - -webkit-backdrop-filter: blur(15px) !important; - backdrop-filter: blur(15px) !important; - border-bottom: 1px solid rgba(255, 255, 255, 0.1) !important; -} - -/* Main Right Box */ -.main-right-box { - background: rgba(255, 255, 255, 0.1) !important; - -webkit-backdrop-filter: blur(15px) !important; - backdrop-filter: blur(15px) !important; - border: 1px solid rgba(255, 255, 255, 0.2) !important; - border-radius: 20px !important; - padding: 30px !important; - box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1) !important; - transition: all 0.3s ease !important; -} - -.main-right-box:hover { - background: rgba(255, 255, 255, 0.15) !important; - border: 1px solid rgba(255, 255, 255, 0.3) !important; - box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15) !important; -} - -/* About Section */ -.About { - background: rgba(255, 255, 255, 0.1) !important; - -webkit-backdrop-filter: blur(15px) !important; - backdrop-filter: blur(15px) !important; - border: 1px solid rgba(255, 255, 255, 0.2) !important; - border-radius: 20px !important; - padding: 30px !important; - margin: 30px 0 !important; - box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1) !important; - transition: all 0.3s ease !important; -} - -.About:hover { - background: rgba(255, 255, 255, 0.15) !important; - border: 1px solid rgba(255, 255, 255, 0.3) !important; - box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15) !important; -} - -.About-left-link { - background: rgba(255, 255, 255, 0.15) !important; - -webkit-backdrop-filter: blur(10px) !important; - backdrop-filter: blur(10px) !important; - border: 1px solid rgba(255, 255, 255, 0.2) !important; - border-radius: 12px !important; - padding: 10px 20px !important; - display: inline-block !important; - color: #333 !important; - text-decoration: none !important; - font-weight: 500 !important; - transition: all 0.3s ease !important; - cursor: pointer !important; - position: relative !important; - overflow: hidden !important; -} - -.About-left-link::before { - content: ''; - position: absolute; - top: 0; - left: -100%; - width: 100%; - height: 100%; - background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); - transition: left 0.5s; -} - -.About-left-link:hover::before { - left: 100%; -} - -.About-left-link:hover { - background: rgba(255, 255, 255, 0.25) !important; - border: 1px solid rgba(255, 255, 255, 0.3) !important; - transform: translateY(-2px) !important; - box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1) !important; -} - -/* Footer Glassy Effect */ -.custom-footer { - background: rgba(255, 255, 255, 0.05) !important; - -webkit-backdrop-filter: blur(20px) !important; - backdrop-filter: blur(20px) !important; - border-top: 1px solid rgba(255, 255, 255, 0.1) !important; -} - -/* Footer Links */ -.footer-learn-link { - background: rgba(255, 255, 255, 0.1) !important; - -webkit-backdrop-filter: blur(10px) !important; - backdrop-filter: blur(10px) !important; - border: 1px solid rgba(255, 255, 255, 0.2) !important; - border-radius: 8px !important; - padding: 6px 12px !important; - display: inline-block !important; - transition: all 0.3s ease !important; - text-decoration: none !important; - position: relative !important; - overflow: hidden !important; -} - -.footer-learn-link::before { - content: ''; - position: absolute; - top: 0; - left: -100%; - width: 100%; - height: 100%; - background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent); - transition: left 0.5s; -} - -.footer-learn-link:hover::before { - left: 100%; -} - -.footer-learn-link:hover { - background: rgba(255, 255, 255, 0.2) !important; - border: 1px solid rgba(255, 255, 255, 0.3) !important; - transform: translateY(-1px) !important; - box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1) !important; -} - -/* Scroll to Top Button */ -#scrollToTopBtn { - background: rgba(255, 255, 255, 0.15) !important; - -webkit-backdrop-filter: blur(10px) !important; - backdrop-filter: blur(10px) !important; - border: 1px solid rgba(255, 255, 255, 0.2) !important; - border-radius: 50% !important; - width: 50px !important; - height: 50px !important; - color: #333 !important; - transition: all 0.3s ease !important; - position: relative !important; - overflow: hidden !important; -} - -#scrollToTopBtn::before { - content: ''; - position: absolute; - top: 0; - left: -100%; - width: 100%; - height: 100%; - background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); - transition: left 0.5s; -} - -#scrollToTopBtn:hover::before { - left: 100%; -} - -#scrollToTopBtn:hover { - background: rgba(255, 255, 255, 0.25) !important; - border: 1px solid rgba(255, 255, 255, 0.3) !important; - transform: translateY(-2px) scale(1.1) !important; - box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15) !important; -} - -/* Card Container */ -.card-container { - display: flex !important; - justify-content: center !important; - align-items: center !important; - flex-wrap: wrap !important; - gap: 20px !important; - padding: 40px 20px !important; -} - -/* Card Links */ -.card-container a { - text-decoration: none !important; - color: inherit !important; -} - -.card-container a:hover { - text-decoration: none !important; -} - -/* Features Section */ -.features-section { - background: rgba(255, 255, 255, 0.02) !important; - -webkit-backdrop-filter: blur(5px) !important; - backdrop-filter: blur(5px) !important; - padding: 60px 0 !important; -} - -/* Responsive Design */ -@media (max-width: 768px) { - .feature-card, .card { - width: 90% !important; - margin: 10px auto !important; - } - - .card-container { - flex-direction: column !important; - align-items: center !important; - } -} \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 00000000..8da3a00e --- /dev/null +++ b/index.html @@ -0,0 +1,148 @@ + + + + + + + + + NotesVault - Your Organized Learning Companion + + + + + + + + + + + + + + + +
+ + +
+
+
+
+

Welcome Back

+

Your Organized Learning Companion...

+

+ Keep your study notes and PYQs organized, easy to find, and always + just a click away with NotesVault! +

+ +
+
+
+

Notes Organized by Subject

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

Key Features

+

+ Powerful tools to organize your academic journey! +

+ +
+ +
+
+ +
+

Easy Upload

+

+ Add your notes quickly and effortlessly with drag & drop + functionality +

+
+
+ + +
+
+ +
+

Sort The Chaos

+

Neatly arrange all your notes with smart categorization

+
+
+ + +
+
+ +
+

Search By Tags

+

Find notes instantly using subject tags and keywords

+
+
+ + +
+
+ +
+

Cross-Device Sync

+

Access your notes from any device, anywhere

+
+
+
+
+
+
+ + + + + + + + diff --git a/pages/BrowseNotes.html b/pages/BrowseNotes.html deleted file mode 100644 index b5778427..00000000 --- a/pages/BrowseNotes.html +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - Browse Notes - NotesVault - - - - - - - - - -
- -
- - -
-

Browse All Notes

- -
-
Loading notes...
- -
-
- - - - - - - diff --git a/pages/Footer.html b/pages/Footer.html deleted file mode 100644 index c8d62d40..00000000 --- a/pages/Footer.html +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - NotesVault Footer - - - - - - - - - -
- -
- - - - - \ No newline at end of file diff --git a/pages/about.html b/pages/about.html index f99faaee..634b84ae 100644 --- a/pages/about.html +++ b/pages/about.html @@ -1,452 +1,347 @@ + + - - - - About - NotesVault + NotesVault - About + + + + + + - - + + + + + + -
+
-
- -
+
-
-
-

About NotesVault

-

Empowering Students Through Collaborative Learning

-
-
- 500+ - Notes Shared -
-
- 100+ - Contributors -
-
- 24/7 - Available +
+
+
+

About NotesVault

+

+ Empowering Students Through Collaborative Learning +

+ +
+
+ 0 + Notes Shared +
+
+ 0 + Contributors +
+
+ 24/7 + Availability +
-
+ -
-
-
-

What is NotesVault?

-

- NotesVault is a revolutionary, open-source platform designed specifically for students who believe in the power of collaborative learning. We've created a centralized hub where academic notes, Previous Year Questions (PYQs), and study materials are organized, accessible, and community-driven. -

-

- Born from the frustration of scattered resources across WhatsApp groups, Google Drives, and countless broken links, NotesVault brings order to the chaos of student life. Our platform doesn't just store your notes—it builds bridges between learners, fostering a supportive ecosystem where knowledge flows freely. -

-
-
-
-
- - Collaborative +
+
+
+
+

What is NotesVault?

+

+ NotesVault is a revolutionary platform designed for students who + believe in collaborative learning. We provide a centralized hub + where academic notes, Previous Year Questions (PYQs), and study + materials are organized and accessible. +

+

+ Born from the frustration of scattered resources across WhatsApp + groups and Google Drives, NotesVault brings order to student + life by building bridges between learners and fostering a + supportive knowledge-sharing ecosystem. +

+
+ +
+
+ + Community-Driven
-
- - Searchable +
+ + Smart Search
-
- - Responsive +
+ + Mobile-Friendly
-
- +
+ Open Source
-
+
-
- -
-
- -

Our Mission & Vision

-
-
-
-
- -

Mission

+ +
+
+
+

Our Mission & Vision

+

The driving force behind NotesVault

+
+ +
+
+
+
+

Mission

- To democratize academic access by providing a centralized, open-source platform where students can seamlessly share, browse, and store academic resources like notes and PYQs, breaking down barriers to quality education. + To democratize academic access by providing a centralized + platform where students can seamlessly share, browse, and store + academic resources, breaking down barriers to quality education.

-
-
-
- -

Vision

+ + +
+
+
+

Vision

- To create a world where learning is truly collaborative, efficient, and accessible for every student—regardless of their background, college, or resources—by eliminating knowledge silos and fostering a supportive global learning community. + To create a world where learning is collaborative and accessible + for every student by eliminating knowledge silos and fostering a + global learning community.

-
+
+
- -
-
- -

Transforming Student Life

-
- -
-
-

The Problem We Solve

-
- - "Students were drowning in scattered notes across WhatsApp groups, broken Google Drive links, and disorganized folders. We knew there had to be a better way." - -
-
- -
-
-
- -
-

Unified Resource Hub

-

No more digging through endless chat threads or broken drives. Everything you need is organized in one accessible location.

+ +
+
+
+

The Problem We Solve

+

+ Transforming student learning experiences +

+
+ +
+

+ "Students were drowning in scattered notes across WhatsApp groups, + broken Google Drive links, and disorganized folders. We knew there + had to be a better way." +

+
- Student Feedback
+
+ +
+
+
+
- -
-
- -
-

Smart Search & Filtering

-

Find exactly what you need with intelligent subject tags, semester filters, and advanced search capabilities.

+

Unified Resource Hub

+

+ No more digging through endless chat threads. Everything you + need is organized in one accessible location. +

+
+ +
+
+
- -
-
- -
-

Community-Driven

-

Every student can contribute, creating a thriving ecosystem of shared knowledge and collaborative learning.

+

Smart Search

+

+ Find exactly what you need with intelligent subject tags, + semester filters, and advanced search capabilities. +

+
+ +
+
+
- -
-
- -
-

24/7 Availability

-

Access your study materials anytime, anywhere. No more last-minute panic before exams.

+

Community-Driven

+

+ Every student can contribute, creating a thriving ecosystem of + shared knowledge. +

+
+ +
+
+
-
+

24/7 Availability

+

+ Access your study materials anytime, anywhere. No more + last-minute panic before exams. +

+
+ - -
-
- -

Built with Modern Technology

-
- -
+ +
+
+
+

Our Technology

+

+ Built with modern, reliable technologies +

+
+ +
-
- -

Frontend

- Current -
-
-
- +

+ Frontend +

+
    +
  • + HTML5 - Semantic markup for accessibility -
-
- + Semantic Markup + +
  • + CSS3 - Modern styling with flexbox & grid -
  • -
    - + Modern Styling + +
  • + JavaScript - Interactive user experience -
  • -
    + Interactive UX + +
    - +
    -
    - -

    Backend

    - Planned -
    -
    -
    - +

    + Backend + (Planned) +

    +
      +
    • + Node.js - Server-side JavaScript runtime -
    -
    - - Express.js - Fast web application framework -
    -
    - + JavaScript Runtime + +
  • + + Express + Web Framework +
  • +
  • + Firebase - Authentication & real-time database -
  • -
    -
    - -
    -
    - -

    DevOps & Tools

    - Planned -
    -
    -
    - - GitHub Actions - Continuous integration & deployment -
    -
    - - MongoDB - Document-based database -
    -
    - - Tailwind CSS - Utility-first CSS framework -
    -
    + Database & Auth + +
    +
    - -
    -
    - -

    Open Source & Community Driven

    -
    - -
    -
    -
    - - Made with Love by the Community -
    - -

    - NotesVault is proudly open-source and welcomes contributors of all skill levels! Whether you're a beginner looking to make your first contribution or an experienced developer wanting to add advanced features, there's a place for you in our community. + +

    +
    +
    +
    +

    Join Our Open Source Community

    +

    + NotesVault is built by students, for students. We welcome + contributors of all skill levels!

    - -
    -
    - - Star Us on GitHub -
    -
    - - Fork & Contribute -
    -
    - - Report Issues -
    -
    -
    - -
    -

    How to Get Started

    -
    -
    -
    1
    -
    -

    Explore the Codebase

    -

    Visit our GitHub repository and familiarize yourself with the project structure

    -
    -
    -
    -
    2
    -
    -

    Find Good First Issues

    -

    Look for issues labeled "good first issue" - perfect for newcomers

    -
    -
    -
    -
    3
    -
    -

    Join the Community

    -

    Connect with other contributors and get help when you need it

    -
    -
    -
    - - -
    -
    -
    + - -
    -
    - -

    Join Our Growing Community

    -
    - -
    -
    -

    NotesVault isn't just a platform—it's a movement. We're building a community of learners, creators, and innovators who believe that education should be accessible to everyone.

    -
    - -
    -
    -
    - -
    -
    - 100+ - Active Contributors +
    +
    + 1 +
    +

    Explore the Codebase

    +

    + Visit our GitHub repository to understand the project + structure +

    -
    -
    -
    - -
    -
    - 500+ - Notes Shared -
    -
    -
    -
    - + + +
    + 2 +
    +

    Find First Issues

    +

    + Look for issues labeled "good first issue" - perfect for + newcomers +

    -
    - 50+ - Universities +
    + +
    + 3 +
    +

    Join the Community

    +

    + Connect with other contributors and get help when you need + it +

    -
    +
    -
    -
    -
    -
    -
    - -
    - + + + diff --git a/pages/dashboard.html b/pages/dashboard.html new file mode 100644 index 00000000..6db220e7 --- /dev/null +++ b/pages/dashboard.html @@ -0,0 +1,229 @@ + + + + + + + + NotesVault - Student Dashboard + + + + + + + + + + + + + + +
    + + +
    +
    + + +
    +
    +
    +
    +

    Pranav K

    + +

    University of Mumbai

    +
    +
    +
    +
    Branch

    Computer Science

    +
    Year

    2nd Year

    +
    Student ID

    CS2024-049

    +
    + +
    + + +
    +

    Your Stats

    +
    +
    0
    Notes
    +
    0
    PYQs
    +
    0
    Subjects
    +
    0%
    Completion
    +
    +
    + + +
    +
    +

    Your Notes

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

    DBMS - Normalization

    +

    Computer Science • 2.4 MB

    +

    Complete notes on database normalization forms with examples.

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

    OS - Deadlock

    +

    Operating Systems • 5.1 MB

    +

    Presentation on deadlock conditions and prevention algorithms.

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

    Previous Year Questions

    +
    + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    SubjectExamYearFile TypeActions
    Computer NetworksMidterm2022PDF + + +
    Data StructuresFinal2021DOC + + +
    AlgorithmsQuiz2023PDF + + +
    +
    +
    + +
    +
    + + + + + + + + + + + + diff --git a/pages/features.html b/pages/features.html index ef843b35..0d3473de 100644 --- a/pages/features.html +++ b/pages/features.html @@ -1,165 +1,148 @@ + + - - - - Features - NotesVault - - - - - - - - -
    - -
    - -
    -
    -

    📂 Organized by Semester & Subject

    -

    Effortlessly browse notes and PYQs sorted by semester and subjects. Stay organized throughout your academic journey.

    -
    - - - -
    -

    📌 Pin Important Notes

    -

    Mark your most important notes and PYQs with a pin so they stay at the top for easy access.

    -
    - -
    -

    📥 Download Notes

    -

    Save your notes as text files and access them offline anytime.

    -
    - -
    -

    🌗 Dark Mode

    -

    Switch between light and dark themes with a single click for comfortable reading at night.

    -
    - - -
    -

    💬 Upload PYQs or Past year question papers

    -

    Add past year questions and papers so that preparation can be easier for other students.

    -
    -
    - - - - - + + + + NotesVault - Features + + + + + + + + + + + + + + + + +
    + +
    +
    +
    +

    Powerful Features

    +

    + Everything you need to organize your academic life! +

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

    Upload Notes

    +

    + Share your study materials with the community in just a few + clicks. Supports multiple file formats. +

    + + Try It Now   + +
    +
    + + +
    +
    + +
    +
    +

    Browse Notes

    +

    + Find exactly what you need with our powerful search and + filtering system. Organized by subject and semester. +

    + + Browse Notes   + +
    +
    + + +
    +
    + +
    +
    +

    Jotpad

    +

    + Quickly jot down ideas, formulas, or reminders without leaving + the app. Auto-saves your work. +

    + + Start Writing   + +
    +
    + + +
    +
    + +
    +
    +

    To-Do List

    +

    + Organize your study schedule, assignment deadlines, revision + plans, and daily academic tasks all in one place. +

    + + Get Organized   + +
    +
    +
    +
    +
    +
    + + + + + + + diff --git a/pages/jotpad.html b/pages/jotpad.html index 282c3d2c..116ed094 100644 --- a/pages/jotpad.html +++ b/pages/jotpad.html @@ -1,80 +1,85 @@ + + - - - - - NotesVault | JotPad - - - - - - - - - - -
    - -
    - -
    JotPad - A Clean, Real Time Note Taking Editor
    - -
    -
    -
    + + + + NotesVault - JotPad + + + + + + + + + + + + + + + +
    + + +
    +
    +

    JotPad

    +

    A Clean, Real Time Note Taking Editor!

    - -
    - - +
    + +
    +
    +
    + + +
    + +
    +
    + +
    + +
    + + + + +
    -
    -
    - - - - - + + - \ No newline at end of file + + + + + + diff --git a/pages/login.html b/pages/login.html index cfcb45b8..5080b53b 100644 --- a/pages/login.html +++ b/pages/login.html @@ -1,119 +1,106 @@ + + - - - - Login - NotesVault - - - - - - - - - -
    - -
    - -
    - - -
    -

    Welcome Back!

    -

    Sign in to your NotesVault account

    + +
    -
    -
    - - + + + - -
    -
    + + + +
    +
    +

    Ready to Organize Your Learning?

    +

    + Join thousands of students who are studying smarter with NotesVault +

    + +
    +
    + + + + - - - + + + diff --git a/pages/search.html b/pages/search.html deleted file mode 100644 index ac0d192e..00000000 --- a/pages/search.html +++ /dev/null @@ -1,243 +0,0 @@ - - - - - - - Browse Notes - NotesVault - - - - - - - - - - -
    - -
    - - -
    -

    Browse Notes

    - -
    - - - - - -
    - - -
    -
    -

    Mathematics I

    -

    Branch: CSE

    -

    Semester: 1

    -

    Subject: Maths

    - Download - -
    ★★★★★
    -
    - -
    -

    Operating System Notes

    -

    Branch: CSE

    -

    Semester: 2

    -

    Subject: OS

    - Download - -
    ★★★★★
    -
    - -
    -

    DBMS Concepts

    -

    Branch: CSE

    -

    Semester: 2

    -

    Subject: DBMS

    - Download - -
    ★★★★☆
    -
    - -
    -

    Engineering Physics

    -

    Branch: CSE

    -

    Semester: 1

    -

    Subject: Physics

    - Download - -
    ★★★★☆
    -
    -
    -
    - - -
    -

    © 2025 NotesVault - GSSoC Contribution

    -
    - - - - - \ No newline at end of file diff --git a/pages/signup.html b/pages/signup.html index 660dc478..85f61cf8 100644 --- a/pages/signup.html +++ b/pages/signup.html @@ -1,128 +1,123 @@ + + - - - - Sign Up - NotesVault - - - - - - - - - - - -
    - -
    - -
    - - - -
    -

    Create Your Account

    -

    Join NotesVault today!

    - -
    -
    - - -
    -
    - - + +
    + + + - + - -
    - - - + + + + diff --git a/pages/studentAccount.html b/pages/studentAccount.html deleted file mode 100644 index 650e5836..00000000 --- a/pages/studentAccount.html +++ /dev/null @@ -1,90 +0,0 @@ - - - - - - Student Account - NotesVault - - - - - - - - - - - - - - -
    - -
    - - - -
    -
    -
    -
    -

    👨‍🎓 Student Dashboard - NotesVault

    -
    -

    👋 Hey John! Ready to Learn Today?

    - -
    - -

    👤 Student Details

    -
    -
    -

    Name: John Doe

    -

    Email: johndoe@example.com

    -

    College: ABC Institute of Technology

    -

    Branch: Computer Science

    -

    Year: 3rd Year

    -
    - - -

    💾 Saved Notes

    -
    -
    -

    Lecture Notes

    -
      -
    • DBMS - Normalization.pdf
    • -
    • Operating Systems - Deadlock.ppt
    • -
    - -
    - -
    -

    Previous Year Questions (PYQs)

    -
      -
    • CS201 - Midterm 2022.pdf
    • -
    • CS303 - Final 2021.docx
    • -
    - -
    -
    - -
    - -
    -
    -
    - - - - - diff --git a/pages/todolist.html b/pages/todolist.html index 5f0c63f3..8dd6bdbb 100644 --- a/pages/todolist.html +++ b/pages/todolist.html @@ -1,154 +1,106 @@ + + + + + + NotesVault - To-Do List - - - - Todo List - NotesVault - - - - - - - - + + - - -
    + + -
    + + + + + - -
    -
    -
    -

    - - Todo List -

    -

    Manage your tasks efficiently and stay organized

    -
    + + +
    - -
    -
    -
    - - -
    -
    + +
    +
    +

    To-Do List

    +

    + Manage your tasks efficiently & stay organized! +

    +
    - -
    -
    - 0 tasks - 0 completed -
    -
    - - + +
    +
    + +
    +
    +
    + + +
    +
    -
    - -
    -
      - -
    - - -
    - -

    No tasks yet

    -

    Add your first task to get started!

    + +
    +
    + 0 Tasks + 0 Completed +
    +
    + + +
    -
    -
    -
    - - - - - - +
    - - + + - \ No newline at end of file + + + + + diff --git a/pages/upload.html b/pages/upload.html index 095909ad..19e492f3 100644 --- a/pages/upload.html +++ b/pages/upload.html @@ -1,191 +1,163 @@ + + - - - - - Upload Notes - - - - - - - - - - - - - - - - - -
    - -
    - - -
    -

    Upload Notes

    -
    - -
    - - + + + + NotesVault - Upload Notes + + + + + + + + + + + + + + + +
    + + +
    +
    +

    Upload Notes

    +

    + Upload & contribute to the growing knowledge base! +

    - -
    - - +
    + + +
    +
    + + +
    + + + +
    + + +
    + + + +
    + + +
    + + + +
    + + +
    + + +
    + + +
    + +
    +

    Click or drag file here

    +
    + +
    +
    + + + + +
    +
    -
    - - -
    - -
    - - -
    - -
    - - - -
    -

    Click or drag file here

    -
    - - - - - -
    -
    - - - - - - -
    -
    - -
    © 2025 NotesVault
    - - - - - - - + + + + + + diff --git a/script.js b/script.js deleted file mode 100644 index 861bc09e..00000000 --- a/script.js +++ /dev/null @@ -1,260 +0,0 @@ -document.addEventListener("DOMContentLoaded", function () { - let allData = {}; - const searchBranchContainer = document.getElementById("search-parameters-branch"); - const searchSemesterContainer = document.getElementById("search-parameters-semester"); - const searchSubjectContainer = document.getElementById("search-parameters-subject"); - const branchFilter = document.getElementById("branch-filter"); - const semesterFilter = document.getElementById("semester-filter"); - const subjectFilter = document.getElementById("subject-filter"); - const notesContainer = document.getElementById("notes-container"); - const themeToggleButton = document.getElementById('themeToggle'); - const hamburger = document.getElementById("hamburger"); - const navMenu = document.querySelector(".navbar-center"); - const signUp = document.querySelector(".signup-btn"); - - const subjectMap = { - "CSE": ["Maths", "DBMS", "OS", "DSA"], - "CSE AIML": ["AI", "ML", "Python"], - "CSE IOT": ["IoT Fundamentals", "Sensors", "Microcontrollers"], - "CSE DS": ["Data Science Basics", "Statistics", "Python for DS"] - }; - - let notesData = []; - - function createDropdown(container, id, defaultText, options) { - container.innerHTML = ''; - const select = document.createElement("select"); - select.id = id; - select.className = "search-parameters-select"; - const defaultOption = document.createElement("option"); - defaultOption.disabled = true; - defaultOption.selected = true; - defaultOption.innerHTML = defaultText; - select.appendChild(defaultOption); - options.forEach(opt => { - const option = document.createElement("option"); - option.value = opt; - option.innerHTML = opt; - select.appendChild(option); - }); - container.appendChild(select); - return select; - } - - function updateSemesters() { - const selectedBranch = document.getElementById("selectBranch").value; - let semesterNames = []; - searchSemesterContainer.innerHTML = ''; - searchSubjectContainer.innerHTML = ''; - const branchData = allData.branches.find(b => b.name === selectedBranch); - if (branchData && branchData.semesters) { - semesterNames = branchData.semesters.map(sem => sem.semester); - } - const semesterSelect = createDropdown(searchSemesterContainer, "selectSemester", "Select Semester", semesterNames); - semesterSelect.addEventListener("change", updateSubjects); - } - - function updateSubjects() { - const selectedBranch = document.getElementById("selectBranch").value; - const selectedSemester = document.getElementById("selectSemester").value; - let subjectNames = []; - searchSubjectContainer.innerHTML = ''; - const branchData = allData.branches.find(b => b.name === selectedBranch); - if (branchData && branchData.semesters) { - const semesterData = branchData.semesters.find(sem => sem.semester == selectedSemester); - if (semesterData && semesterData.subjects) { - subjectNames = semesterData.subjects.map(sub => Object.values(sub)[0]).sort((a, b) => a.localeCompare(b)); - } - } - createDropdown(searchSubjectContainer, "selectSubject", "Select Subject", subjectNames); - } - - fetch("data/search_parameters/parameters.json") - .then(res => res.json()) - .then(data => { - allData = data; - const branchNames = allData.branches.map(b => b.name); - const branchSelect = createDropdown(searchBranchContainer, "selectBranch", "Select Branch", branchNames); - branchSelect.addEventListener("change", updateSemesters); - }) - .catch(error => console.error("Error fetching parameters:", error)); - - // Typewriter Effect - const words = ["Branch", "Semester", "Subject", "Year"]; - let currentWordIndex = 0; - let charIndex = 0; - let isDeleting = false; - function typeWriterEffect() { - const currentWord = words[currentWordIndex]; - const typewriterElement = document.getElementById('typeWriterText'); - if (!typewriterElement) return; - if (isDeleting) { - typewriterElement.textContent = currentWord.substring(0, charIndex - 1); - charIndex--; - } else { - typewriterElement.textContent = currentWord.substring(0, charIndex + 1); - charIndex++; - } - let typeSpeed = isDeleting ? 75 : 150; - if (!isDeleting && charIndex === currentWord.length) { - typeSpeed = 2000; - isDeleting = true; - } else if (isDeleting && charIndex === 0) { - isDeleting = false; - currentWordIndex = (currentWordIndex + 1) % words.length; - typeSpeed = 500; - } - setTimeout(typeWriterEffect, typeSpeed); - } - typeWriterEffect(); - - // Theme Toggle - if (themeToggleButton) { - themeToggleButton.addEventListener('click', () => { - const html = document.documentElement; - const currentTheme = html.getAttribute('data-theme') || 'light'; - const newTheme = currentTheme === 'dark' ? 'light' : 'dark'; - html.setAttribute('data-theme', newTheme); - localStorage.setItem('theme', newTheme); - }); - } - (function initTheme() { - const savedTheme = localStorage.getItem('theme'); - const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches; - document.documentElement.setAttribute('data-theme', savedTheme || (prefersDark ? 'dark' : 'light')); - })(); - - if (hamburger && navMenu) { - hamburger.addEventListener("click", () => { - navMenu.classList.toggle("show"); - signUp.classList.toggle("show"); - }); - document.addEventListener('click', function (event) { - if (!navMenu.contains(event.target) && !hamburger.contains(event.target)) { - navMenu.classList.remove('show'); - signUp.classList.remove('show'); - } - }); - } - - fetch("data/notes.json") - .then(res => res.json()) - .then(data => { - notesData = data; - updateFilterSubjects(""); - displayNotes(notesData); - runQuerySearch(); - }); - - function updateFilterSubjects(branch) { - subjectFilter.innerHTML = ''; - const subjects = subjectMap[branch] || [].concat(...Object.values(subjectMap)); - [...new Set(subjects)].sort((a, b) => a.localeCompare(b)).forEach(sub => { - const opt = document.createElement("option"); - opt.value = sub; - opt.textContent = sub; - subjectFilter.appendChild(opt); - }); - } - - function displayNotes(notes) { - notesContainer.innerHTML = notes.length === 0 ? "

    No notes found.

    " : ""; - const bookmarked = JSON.parse(localStorage.getItem("bookmarkedNotes") || "[]"); - notes.sort((a, b) => a.title.toLowerCase().localeCompare(b.title.toLowerCase())).forEach(note => { - const card = document.createElement("div"); - card.className = "note-card"; - const isBookmarked = bookmarked.includes(note.title); - card.innerHTML = ` -
    -

    ${note.title}

    -

    Branch: ${note.branch}

    -

    Semester: ${note.semester}

    -

    Subject: ${note.subject}

    -
    - ${[1, 2, 3, 4, 5].map(i => ``).join('')} -
    -
    -
    - Download - -
    - `; - notesContainer.appendChild(card); - }); - - document.querySelectorAll(".bookmark-btn").forEach(btn => { - btn.addEventListener("click", () => { - const id = btn.getAttribute("data-id"); - let bookmarks = JSON.parse(localStorage.getItem("bookmarkedNotes") || "[]"); - if (bookmarks.includes(id)) { - bookmarks = bookmarks.filter(b => b !== id); - btn.textContent = "☆ Bookmark"; - btn.classList.remove("bookmarked"); - } else { - bookmarks.push(id); - btn.textContent = "★ Bookmarked"; - btn.classList.add("bookmarked"); - } - localStorage.setItem("bookmarkedNotes", JSON.stringify(bookmarks)); - }); - }); - - document.querySelectorAll(".rating").forEach(rating => { - const noteId = rating.dataset.id; - const saved = localStorage.getItem(`rating_${noteId}`); - if (saved) highlightStars(rating, saved); - rating.querySelectorAll(".star").forEach(star => { - star.addEventListener("click", () => { - const value = star.dataset.value; - localStorage.setItem(`rating_${noteId}`, value); - highlightStars(rating, value); - }); - }); - }); - - function highlightStars(container, rating) { - const stars = container.querySelectorAll(".star"); - stars.forEach(star => { - star.classList.toggle("filled", star.dataset.value <= rating); - }); - } - } - - [branchFilter, semesterFilter, subjectFilter].forEach(filter => { - filter.addEventListener("change", () => { - const branchVal = branchFilter.value; - if (filter === branchFilter) updateFilterSubjects(branchVal); - const filtered = notesData.filter(note => - (branchVal === "" || note.branch === branchVal) && - (semesterFilter.value === "" || note.semester === semesterFilter.value) && - (subjectFilter.value === "" || note.subject === subjectFilter.value) - ); - displayNotes(filtered); - }); - }); - - function runQuerySearch() { - const urlParams = new URLSearchParams(window.location.search); - const query = urlParams.get("query")?.trim().toLowerCase(); - if (query) { - const notes = document.querySelectorAll(".note-card"); - let matchFound = false; - notes.forEach(note => { - const content = note.textContent.toLowerCase(); - const show = content.includes(query); - note.style.display = show ? "block" : "none"; - if (show) matchFound = true; - }); - if (!matchFound) { - const msg = document.createElement("p"); - msg.textContent = `No notes found for "${query}"`; - msg.style.color = "red"; - msg.style.fontWeight = "bold"; - msg.style.marginTop = "20px"; - document.getElementById("notes-container").appendChild(msg); - } - } - } -}); \ No newline at end of file diff --git a/scripts/browseNotes.js b/scripts/browseNotes.js deleted file mode 100644 index 74c73651..00000000 --- a/scripts/browseNotes.js +++ /dev/null @@ -1,146 +0,0 @@ -document.addEventListener('DOMContentLoaded', () => { - const notesGrid = document.getElementById('notesGrid'); - const loadingMessage = document.getElementById('loadingMessage'); - const noNotesMessage = document.getElementById('noNotesMessage'); - const noteDetailModal = document.getElementById('noteDetailModal'); - const closeModalButton = noteDetailModal.querySelector('.close-button'); - const modalNoteTitle = document.getElementById('modalNoteTitle'); - const modalNoteBranch = document.getElementById('modalNoteBranch'); - const modalNoteSemester = document.getElementById('modalNoteSemester'); - const modalNoteDescription = document.getElementById('modalNoteDescription'); - const modalNoteUploader = document.getElementById('modalNoteUploader'); - const modalNoteUploadDate = document.getElementById('modalNoteUploadDate'); - const modalDownloadButton = document.getElementById('modalDownloadButton'); - const searchInput = document.getElementById('searchInput'); - - - const dummyNotes = [ - { - _id: 'note1', - title: 'Data Structures & Algorithms Basics', - branch: 'Computer Science', - semester: '3rd', - description: 'Comprehensive notes on fundamental data structures (arrays, linked lists, trees, graphs) and common algorithms (sorting, searching).', - uploader: 'Alice Smith', - uploadDate: '2023-03-15', - filePath: 'http://example.com/notes/dsa_basics.pdf' - }, - { - _id: 'note2', - title: 'Digital Electronics Principles', - branch: 'Electronics Engineering', - semester: '4th', - description: 'Detailed notes covering logic gates, Boolean algebra, combinational and sequential circuits.', - uploader: 'Bob Johnson', - uploadDate: '2023-04-20', - filePath: 'http://example.com/notes/digital_electronics.pdf' - }, - { - _id: 'note3', - title: 'Thermodynamics for Mechanical Engineers', - branch: 'Mechanical Engineering', - semester: '5th', - description: 'Concepts of thermodynamics, laws, cycles, and their applications in various systems.', - uploader: 'Charlie Brown', - uploadDate: '2023-05-10', - filePath: 'http://example.com/notes/thermodynamics.pdf' - }, - { - _id: 'note4', - title: 'Object-Oriented Programming with Java', - branch: 'Information Technology', - semester: '3rd', - description: 'Introduction to OOP principles using Java: classes, objects, inheritance, polymorphism, abstraction, and encapsulation.', - uploader: 'Alice Smith', - uploadDate: '2023-06-01', - filePath: 'http://example.com/notes/oop_java.pdf' - }, - { - _id: 'note5', - title: 'Calculus I - Differentiation', - branch: 'Mathematics', - semester: '1st', - description: 'Basic concepts of differentiation, limits, continuity, and applications.', - uploader: 'David Lee', - uploadDate: '2023-07-10', - filePath: 'http://example.com/notes/calculus1.pdf' - } - ]; - let allNotes = [...dummyNotes]; - - - function createNoteCard(note) { - const card = document.createElement('div'); - card.className = 'note-card'; - card.setAttribute('tabindex', '0'); - card.innerHTML = ` -

    ${note.title}

    -

    Branch: ${note.branch}

    -

    Semester: ${note.semester}

    -

    Uploaded By: ${note.uploader}

    -
    - - - Download - -
    - `; - card.querySelector('.view-button').onclick = () => openNoteDetailModal(note); - - card.onkeypress = e => { if (e.key === "Enter") openNoteDetailModal(note);}; - return card; - } - - function displayNotes(noteArr, initial = false) { - notesGrid.innerHTML = ''; - if (!noteArr || noteArr.length === 0) { - noNotesMessage.style.display = 'block'; - return; - } - noNotesMessage.style.display = 'none'; - let toDisplay = initial ? noteArr.slice(0, 3) : noteArr; - toDisplay.forEach(note => notesGrid.appendChild(createNoteCard(note))); - } - - async function fetchNotes() { - loadingMessage.style.display = 'block'; - notesGrid.innerHTML = ''; - try { - await new Promise(res => setTimeout(res, 500)); - displayNotes(allNotes, true); - } catch { - notesGrid.innerHTML = `

    Failed to load notes. Please try again later.

    `; - } finally { - loadingMessage.style.display = 'none'; - } - } - - - searchInput.addEventListener('input', () => { - const q = searchInput.value.toLowerCase().trim(); - const filtered = allNotes.filter(note => - note.title.toLowerCase().includes(q) || - note.branch.toLowerCase().includes(q) || - note.semester.toLowerCase().includes(q) - ); - displayNotes(filtered); - }); - - - function openNoteDetailModal(note) { - modalNoteTitle.textContent = note.title; - modalNoteBranch.textContent = note.branch; - modalNoteSemester.textContent = note.semester; - modalNoteDescription.textContent = note.description; - modalNoteUploader.textContent = note.uploader; - modalNoteUploadDate.textContent = new Date(note.uploadDate).toLocaleDateString(); - modalDownloadButton.href = note.filePath; - modalDownloadButton.setAttribute('download', `${note.title.replace(/\s/g, '_')}.pdf`); - noteDetailModal.style.display = 'flex'; - } - function closeNoteDetailModal() { noteDetailModal.style.display = 'none'; } - closeModalButton.onclick = closeNoteDetailModal; - window.onclick = (event) => { if (event.target === noteDetailModal) closeNoteDetailModal(); }; - - fetchNotes(); -}); \ No newline at end of file diff --git a/scripts/dashboard.js b/scripts/dashboard.js new file mode 100644 index 00000000..afc243d5 --- /dev/null +++ b/scripts/dashboard.js @@ -0,0 +1 @@ +// Student Dashboard (JavaScript) \ No newline at end of file diff --git a/scripts/features.js b/scripts/features.js deleted file mode 100644 index ecc913e2..00000000 --- a/scripts/features.js +++ /dev/null @@ -1,13 +0,0 @@ -document.addEventListener("DOMContentLoaded", () => { - const cards = document.querySelectorAll(".feature-card"); - - cards.forEach((card) => { - card.addEventListener("mouseenter", () => { - card.classList.add("active-feature"); - }); - - card.addEventListener("mouseleave", () => { - card.classList.remove("active-feature"); - }); - }); -}); diff --git a/scripts/jotpad.js b/scripts/jotpad.js new file mode 100644 index 00000000..cfb2d08b --- /dev/null +++ b/scripts/jotpad.js @@ -0,0 +1,264 @@ +// JotPad (JavaScript) + +ocument.addEventListener('DOMContentLoaded', function () { + const noteArea = document.getElementById('noteArea') + noteArea.innerHTML = localStorage.getItem('noteContent') || '' + + // Initialize Canvas + const canvas = document.getElementById('drawingCanvas') + const ctx = canvas.getContext('2d') + let isDrawing = false + let lastX = 0 + let lastY = 0 + + // Canvas Size + function resizeCanvas() { + const noteBox = document.querySelector('.note-box') + canvas.width = noteBox.offsetWidth + canvas.height = noteBox.offsetHeight + + // Redraw Existing Content + const canvasData = localStorage.getItem('canvasData') + if (canvasData) { + const img = new Image() + img.onload = function () { + ctx.drawImage(img, 0, 0) + } + img.src = canvasData + } + } + + resizeCanvas() + window.addEventListener('resize', resizeCanvas) + + // Drawing Functions + function startDrawing(e) { + isDrawing = true + const rect = canvas.getBoundingClientRect() + lastX = e.clientX - rect.left + lastY = e.clientY - rect.top + } + + function draw(e) { + if (!isDrawing) return + + const rect = canvas.getBoundingClientRect() + const currentX = e.clientX - rect.left + const currentY = e.clientY - rect.top + + const theme = document.documentElement.getAttribute('data-theme') + + ctx.strokeStyle = theme === 'dark' ? '#ffffff' : '#000000' + ctx.lineWidth = 2 + ctx.lineJoin = 'round' + ctx.lineCap = 'round' + + ctx.beginPath() + ctx.moveTo(lastX, lastY) + ctx.lineTo(currentX, currentY) + ctx.stroke() + + lastX = currentX + lastY = currentY + } + + function stopDrawing() { + isDrawing = false + // Save Canvas + localStorage.setItem('canvasData', canvas.toDataURL()) + } + + // Switch Mode (Text <--> Draw) + const textModeBtn = document.getElementById('textModeBtn') + const drawModeBtn = document.getElementById('drawModeBtn') + const saveDrawingBtn = document.getElementById('saveDrawingBtn') + const clearDrawingBtn = document.getElementById('clearDrawingBtn') + + function activateTextMode() { + textModeBtn.classList.add('active') + drawModeBtn.classList.remove('active') + noteArea.contentEditable = 'true' + canvas.style.pointerEvents = 'none' + saveDrawingBtn.style.display = 'none' + clearDrawingBtn.style.display = 'none' + noteArea.focus() + } + + function activateDrawMode() { + textModeBtn.classList.remove('active') + drawModeBtn.classList.add('active') + noteArea.contentEditable = 'false' + canvas.style.pointerEvents = 'auto' + saveDrawingBtn.style.display = 'inline-block' + clearDrawingBtn.style.display = 'inline-block' + } + + textModeBtn.addEventListener('click', activateTextMode) + drawModeBtn.addEventListener('click', activateDrawMode) + + // Set Initial Mode + activateTextMode() + + // Canvas Event Listeners + canvas.addEventListener('mousedown', startDrawing) + canvas.addEventListener('mousemove', draw) + canvas.addEventListener('mouseup', stopDrawing) + canvas.addEventListener('mouseout', stopDrawing) + + // Touch Functionality (Draw Mode) + canvas.addEventListener('touchstart', (e) => { + e.preventDefault() + const touch = e.touches[0] + const mouseEvent = new MouseEvent('mousedown', { + clientX: touch.clientX, + clientY: touch.clientY, + }) + canvas.dispatchEvent(mouseEvent) + }) + + canvas.addEventListener('touchmove', (e) => { + e.preventDefault() + const touch = e.touches[0] + const mouseEvent = new MouseEvent('mousemove', { + clientX: touch.clientX, + clientY: touch.clientY, + }) + canvas.dispatchEvent(mouseEvent) + }) + + canvas.addEventListener('touchend', (e) => { + e.preventDefault() + const mouseEvent = new MouseEvent('mouseup', {}) + canvas.dispatchEvent(mouseEvent) + }) + + // Clear Drawing Button + clearDrawingBtn.addEventListener('click', () => { + ctx.clearRect(0, 0, canvas.width, canvas.height) + localStorage.removeItem('canvasData') + }) + + // Save Drawing Button + saveDrawingBtn.addEventListener('click', () => { + const imageData = canvas.toDataURL('image/png') + const img = document.createElement('img') + img.src = imageData + img.style.maxWidth = '100%' + + activateTextMode() + noteArea.focus() + + // Insert At Cursor Position + const selection = window.getSelection() + if (selection.rangeCount > 0) { + const range = selection.getRangeAt(0) + range.insertNode(img) + } else { + noteArea.appendChild(img) + } + + ctx.clearRect(0, 0, canvas.width, canvas.height) + localStorage.removeItem('canvasData') + saveNoteContent() + }) + + // Handle Note Content + function togglePlaceholder() { + if (noteArea.innerText.trim() === '') { + noteArea.classList.add('empty') + } else { + noteArea.classList.remove('empty') + } + saveNoteContent() + } + + function saveNoteContent() { + localStorage.setItem('noteContent', noteArea.innerHTML) + } + + noteArea.addEventListener('input', togglePlaceholder) + noteArea.addEventListener('blur', togglePlaceholder) + noteArea.addEventListener('focus', function () { + if (noteArea.innerText.trim() === '') { + noteArea.classList.add('empty') + } + }) + + togglePlaceholder() +}) + +// Download PDF +async function downloadPDF() { + const { jsPDF } = window.jspdf + const content = document.getElementById('noteArea').innerHTML + const doc = new jsPDF() + doc.setFont('helvetica', 'normal') + doc.setFontSize(14) + + const tempDiv = document.createElement('div') + tempDiv.innerHTML = content + + let textContent = '' + const walker = document.createTreeWalker( + tempDiv, + NodeFilter.SHOW_TEXT, + null, + false + ) + let node + while ((node = walker.nextNode())) { + textContent += node.nodeValue + '\n' + } + + const images = tempDiv.getElementsByTagName('img') + let yPosition = 20 + const textLines = doc.splitTextToSize(textContent, 180) + doc.text(textLines, 10, yPosition) + yPosition += textLines.length * 7 + + for (let i = 0; i < images.length; i++) { + if (yPosition > 250) { + doc.addPage() + yPosition = 20 + } + + try { + const imgData = await getImageData(images[i].src) + const imgProps = doc.getImageProperties(imgData) + const width = 180 + const height = (imgProps.height * width) / imgProps.width + doc.addImage(imgData, 'PNG', 10, yPosition, width, height) + yPosition += height + 10 + } catch (error) { + console.error('Error adding image to PDF:', error) + } + } + + doc.save('My_Notes.pdf') +} + +function getImageData(url) { + return new Promise((resolve, reject) => { + const img = new Image() + img.crossOrigin = 'Anonymous' + img.onload = () => resolve(img) + img.onerror = reject + img.src = url + }) +} + +function deleteAll() { + if (confirm('Are you sure you want to delete all notes?')) { + const noteArea = document.getElementById('noteArea') + const canvas = document.getElementById('drawingCanvas') + const ctx = canvas.getContext('2d') + + noteArea.innerHTML = '' + ctx.clearRect(0, 0, canvas.width, canvas.height) + + localStorage.removeItem('noteContent') + localStorage.removeItem('canvasData') + + noteArea.classList.add('empty') + } +} diff --git a/scripts/login.js b/scripts/login.js new file mode 100644 index 00000000..2dac40fa --- /dev/null +++ b/scripts/login.js @@ -0,0 +1,170 @@ +// Login (JavaScript) + +document.addEventListener('DOMContentLoaded', function () { + // DOM Elements + const loginForm = document.getElementById('loginForm') + const messageBox = document.getElementById('messageBox') + const emailInput = document.getElementById('email') + const passwordInput = document.getElementById('password') + const passwordToggle = document.querySelector('.password-toggle') + const passwordIcon = passwordToggle.querySelector('i') + const rememberMe = document.getElementById('remember-me') + const loginBtn = document.getElementById('loginBtn') + const spinner = document.getElementById('spinner') + const btnText = document.getElementById('btnText') + + // Constants + const MIN_PASSWORD_LENGTH = 6 + const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/ + + // Initialize Form + function initForm() { + // Check For Remembered Email + const rememberedEmail = localStorage.getItem('rememberEmail') + if (rememberedEmail) { + emailInput.value = rememberedEmail + rememberMe.checked = true + emailInput.parentNode.classList.add('focused') + } + + // Setup Floating Labels + initFloatingLabels() + + // Setup Password Toggle + initPasswordToggle() + } + + // Initialize Floating Labels + function initFloatingLabels() { + document.querySelectorAll('.floating-input input').forEach((input) => { + input.addEventListener('focus', () => { + input.parentNode.classList.add('focused') + }) + + input.addEventListener('blur', () => { + if (!input.value) { + input.parentNode.classList.remove('focused') + } + }) + + if (input.value) { + input.parentNode.classList.add('focused') + } + }) + } + + // Initialize Password Toggle + function initPasswordToggle() { + passwordToggle.addEventListener('click', togglePasswordVisibility) + updatePasswordToggle() + } + + // Toggle Password Visibility + function togglePasswordVisibility() { + const isPassword = passwordInput.type === 'password' + passwordInput.type = isPassword ? 'text' : 'password' + updatePasswordToggle(isPassword) + } + + // Update Password Toggle State + function updatePasswordToggle(isPassword) { + passwordIcon.className = isPassword ? 'far fa-eye-slash' : 'far fa-eye' + passwordToggle.setAttribute( + 'aria-label', + isPassword ? 'Hide password' : 'Show password' + ) + } + + // Message Function + function showMessage(message, type = 'success') { + messageBox.textContent = message + messageBox.className = `message-box ${type} show` + + // Auto-Hide Message After Timeout + setTimeout(() => { + messageBox.classList.remove('show') + }, 3000) + } + + // Validate Form Inputs + function validateForm(email, password) { + if (!email || !password) { + showMessage('Please Fill In All Fields', 'error') + return false + } + + if (!EMAIL_REGEX.test(email)) { + showMessage('Please Enter a Valid Email Address', 'error') + return false + } + + if (password.length < MIN_PASSWORD_LENGTH) { + showMessage( + `Password Must Be At Least ${MIN_PASSWORD_LENGTH} Characters`, + 'error' + ) + return false + } + + return true + } + + // Set Loading State + function setLoadingState(isLoading) { + if (isLoading) { + spinner.classList.remove('hidden') + btnText.textContent = 'Signing in...' + loginBtn.disabled = true + } else { + spinner.classList.add('hidden') + btnText.textContent = 'Sign in' + loginBtn.disabled = false + } + } + + // Handle Form Submission + async function handleLogin(e) { + e.preventDefault() + + const email = emailInput.value.trim() + const password = passwordInput.value + const shouldRemember = rememberMe.checked + + // Validate Form + if (!validateForm(email, password)) return + + // Set Loading State + setLoadingState(true) + + try { + // Simulate API Call - Replace With Actual Fetch In Production + await new Promise((resolve) => setTimeout(resolve, 1000)) + + // Store Remember Me Preference + if (shouldRemember) { + localStorage.setItem('rememberEmail', email) + } else { + localStorage.removeItem('rememberEmail') + } + + // Show Success Message + showMessage('Login Successful! Redirecting...', 'success') + + // Redirect After Delay + setTimeout(() => { + window.location.href = '../index.html' + }, 1500) + } catch (error) { + console.error('Login error:', error) + showMessage('Login Failed. Please Try Again...', 'error') + } finally { + setLoadingState(false) + } + } + + // Event Listeners + loginForm.addEventListener('submit', handleLogin) + + // Initialize The Form + initForm() +}) diff --git a/scripts/overview_darktheme.js b/scripts/overview_darktheme.js deleted file mode 100644 index bdfab0c8..00000000 --- a/scripts/overview_darktheme.js +++ /dev/null @@ -1,24 +0,0 @@ - -document.addEventListener('DOMContentLoaded', () => { - function toggleTheme() { - const html = document.documentElement; - const currentTheme = html.getAttribute('data-theme') || 'light'; - const newTheme = currentTheme === 'dark' ? 'light' : 'dark'; - html.setAttribute('data-theme', newTheme); - localStorage.setItem('theme', newTheme); - } - - function initTheme() { - const savedTheme = localStorage.getItem('theme'); - const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches; - document.documentElement.setAttribute('data-theme', savedTheme || (prefersDark ? 'dark' : 'light')); - } - - const themeToggleButton = document.getElementById('themeToggle'); - if (themeToggleButton) { - themeToggleButton.addEventListener('click', toggleTheme); - } - - initTheme(); -}); - diff --git a/scripts/script.js b/scripts/script.js index b227df4f..c65b90a0 100644 --- a/scripts/script.js +++ b/scripts/script.js @@ -1,151 +1,269 @@ -document.addEventListener("DOMContentLoaded", function () { - let allData = {}; - - const searchBranchContainer = document.getElementById("search-parameters-branch"); - const searchSemesterContainer = document.getElementById("search-parameters-semester"); - const searchSubjectContainer = document.getElementById("search-parameters-subject"); - - function createDropdown(container, id, defaultText, options) { - container.innerHTML = ''; - const select = document.createElement("select"); - select.id = id; - select.className = "search-parameters-select"; - const defaultOption = document.createElement("option"); - defaultOption.disabled = true; - defaultOption.selected = true; - defaultOption.innerHTML = defaultText; - select.appendChild(defaultOption); - options.forEach(opt => { - const option = document.createElement("option"); - option.value = opt; - option.innerHTML = opt; - select.appendChild(option); - }); - container.appendChild(select); - return select; +// Main (JavaScript) + +document.addEventListener('DOMContentLoaded', () => { + // Global DOM Elements + const DOM = { + searchBranchContainer: document.getElementById('search-parameters-branch'), + searchSemesterContainer: document.getElementById( + 'search-parameters-semester' + ), + searchSubjectContainer: document.getElementById( + 'search-parameters-subject' + ), + typewriterElement: document.getElementById('typewriter'), + searchForm: document.querySelector('.search-form'), + yearElement: document.getElementById('year'), + backToTop: document.querySelector('.back-to-top'), } - function updateSemesters() { - const selectedBranch = document.getElementById("selectBranch").value; - searchSemesterContainer.innerHTML = ''; - searchSubjectContainer.innerHTML = ''; - const branchData = allData.branches.find(b => b.name === selectedBranch); - const semesterNames = branchData?.semesters?.map(sem => sem.semester) || []; - const semesterSelect = createDropdown(searchSemesterContainer, "selectSemester", "Select Semester", semesterNames); - semesterSelect.addEventListener("change", updateSubjects); + const TYPEWRITER_WORDS = ['Branch', 'Semester', 'Subject', 'Year'] + let allData = { branches: [] } + + // Helper Functions // + const createDropdown = (container, id, placeholder, options) => { + if (!container) return null + + container.innerHTML = ` + + ` + + return container.firstElementChild } - function updateSubjects() { - const selectedBranch = document.getElementById("selectBranch").value; - const selectedSemester = document.getElementById("selectSemester").value; - searchSubjectContainer.innerHTML = ''; - const branchData = allData.branches.find(b => b.name === selectedBranch); - const semesterData = branchData?.semesters?.find(sem => sem.semester == selectedSemester); - const subjectNames = semesterData?.subjects?.map(sub => Object.values(sub)[0]) || []; - createDropdown(searchSubjectContainer, "selectSubject", "Select Subject", subjectNames); + // Search Function // + const updateSemesters = () => { + const branchSelect = document.getElementById('selectBranch') + if (!branchSelect?.value) return + + DOM.searchSemesterContainer.innerHTML = '' + DOM.searchSubjectContainer.innerHTML = '' + + const branchData = allData.branches.find( + (b) => b.name === branchSelect.value + ) + if (!branchData?.semesters) return + + const semesterSelect = createDropdown( + DOM.searchSemesterContainer, + 'selectSemester', + 'Select Semester', + branchData.semesters.map((sem) => sem.semester) + ) + + semesterSelect?.addEventListener('change', updateSubjects) } - fetch("../data/search_parameters/parameters.json") - .then(res => res.json()) - .then(data => { - allData = data; - const branchNames = allData.branches.filter(b => b.name && b.name.trim() !== "").map(b => b.name); - const branchSelect = createDropdown(searchBranchContainer, "selectBranch", "Select Branch", branchNames); - branchSelect.addEventListener("change", updateSemesters); - }) - .catch(error => console.error("Error fetching parameters:", error)); - - const words = ["Branch", "Semester", "Subject", "Year"]; - let currentWordIndex = 0; - let charIndex = 0; - let isDeleting = false; - - function typeWriterEffect() { - const currentWord = words[currentWordIndex]; - const typewriterElement = document.getElementById('typeWriterText'); - if (!typewriterElement) return; - if (isDeleting) { - typewriterElement.textContent = currentWord.substring(0, charIndex - 1); - charIndex--; - } else { - typewriterElement.textContent = currentWord.substring(0, charIndex + 1); - charIndex++; + const updateSubjects = () => { + const branchSelect = document.getElementById('selectBranch') + const semesterSelect = document.getElementById('selectSemester') + if (!branchSelect?.value || !semesterSelect?.value) return + + DOM.searchSubjectContainer.innerHTML = '' + + const branchData = allData.branches.find( + (b) => b.name === branchSelect.value + ) + const semesterData = branchData?.semesters?.find( + (sem) => sem.semester === semesterSelect.value + ) + + if (semesterData?.subjects) { + createDropdown( + DOM.searchSubjectContainer, + 'selectSubject', + 'Select Subject', + semesterData.subjects.map((sub) => Object.values(sub)[0]) + ) } - let typeSpeed = isDeleting ? 75 : 150; - if (!isDeleting && charIndex === currentWord.length) { - typeSpeed = 2000; - isDeleting = true; + } + + const handleSearch = (e) => { + e.preventDefault() + const searchInput = DOM.searchForm?.querySelector("input[type='text']") + if (searchInput?.value) { + window.location.href = `pages/notes.html?query=${encodeURIComponent( + searchInput.value + )}` + } + } + + // Typewriter Effect // + const typeWriter = (wordIndex = 0, charIndex = 0, isDeleting = false) => { + if (!DOM.typewriterElement) return + + const word = TYPEWRITER_WORDS[wordIndex % TYPEWRITER_WORDS.length] + DOM.typewriterElement.textContent = word.substring( + 0, + isDeleting ? charIndex - 1 : charIndex + 1 + ) + + let delay + if (!isDeleting && charIndex === word.length) { + delay = 2000 + isDeleting = true } else if (isDeleting && charIndex === 0) { - isDeleting = false; - currentWordIndex = (currentWordIndex + 1) % words.length; - typeSpeed = 500; + delay = 500 + isDeleting = false + wordIndex++ + } else { + delay = isDeleting ? 75 : 150 } - setTimeout(typeWriterEffect, typeSpeed); + + setTimeout( + () => + typeWriter( + wordIndex, + isDeleting ? charIndex - 1 : charIndex + 1, + isDeleting + ), + delay + ) } - typeWriterEffect(); - - const nav = document.getElementById('header-navigation'); - const hamburger = document.getElementById('hamburger'); - if (hamburger) { - hamburger.addEventListener('click', () => { - nav.classList.toggle('show'); - hamburger.classList.toggle('active'); - }); + + // Theme Toggle // + const getPreferredTheme = () => { + const stored = localStorage.getItem('theme') + return ( + stored || + (window.matchMedia('(prefers-color-scheme: dark)').matches + ? 'dark' + : 'light') + ) } - document.addEventListener('click', function (event) { - if (nav && hamburger && !nav.contains(event.target) && !hamburger.contains(event.target)) { - nav.classList.remove('show'); - hamburger.classList.remove('active'); - } - }); - - function toggleTheme() { - const html = document.documentElement; - const currentTheme = html.getAttribute('data-theme') || 'light'; - const newTheme = currentTheme === 'dark' ? 'light' : 'dark'; - html.setAttribute('data-theme', newTheme); - localStorage.setItem('theme', newTheme); + + const setTheme = (theme) => { + document.documentElement.setAttribute('data-theme', theme) + localStorage.setItem('theme', theme) } - const themeToggleButton = document.getElementById('themeToggle'); - if (themeToggleButton) { - themeToggleButton.addEventListener('click', toggleTheme); + const setupThemeToggle = () => { + setTheme(getPreferredTheme()) + document + .querySelectorAll('.theme-toggle, .mobile-theme-toggle') + .forEach((toggle) => { + toggle.addEventListener('click', () => { + const current = + document.documentElement.getAttribute('data-theme') || 'light' + setTheme(current === 'dark' ? 'light' : 'dark') + }) + }) } - (function initTheme() { - const savedTheme = localStorage.getItem('theme'); - const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches; - document.documentElement.setAttribute('data-theme', savedTheme || (prefersDark ? 'dark' : 'light')); - })(); - - document.querySelectorAll(".upload-btn").forEach(btn => { - btn.addEventListener("click", () => { - window.location.href = "upload.html"; - }); - }); - - function runQuerySearch() { - const urlParams = new URLSearchParams(window.location.search); - const query = urlParams.get("query")?.trim().toLowerCase(); - if (query) { - const notes = document.querySelectorAll(".note-card"); - let matchFound = false; - notes.forEach((note) => { - const content = note.textContent.toLowerCase(); - const show = content.includes(query); - note.style.display = show ? "block" : "none"; - if (show) matchFound = true; - }); - if (!matchFound) { - const msg = document.createElement("p"); - msg.textContent = `No notes found for "${query}"`; - msg.style.color = "red"; - msg.style.fontWeight = "bold"; - msg.style.marginTop = "20px"; - document.getElementById("notes-container").appendChild(msg); - } + // Mobile Menu Navigation // + const toggleMobileMenu = () => { + const menuToggle = document.querySelector('.menu-toggle') + const mobileNav = document.querySelector('.mobile-nav') + const overlay = document.querySelector('.overlay') + + menuToggle?.classList.toggle('active') + mobileNav?.classList.toggle('active') + overlay?.classList.toggle('active') + document.body.style.overflow = mobileNav?.classList.contains('active') + ? 'hidden' + : '' + } + + const setupMobileMenu = () => { + const menuToggle = document.querySelector('.menu-toggle') + const mobileNavLinks = document.querySelectorAll('.mobile-nav-link') + const overlay = document.querySelector('.overlay') + + menuToggle?.addEventListener('click', toggleMobileMenu) + overlay?.addEventListener('click', toggleMobileMenu) + mobileNavLinks.forEach((link) => + link.addEventListener('click', toggleMobileMenu) + ) + } + + // Back to Top Button // + const setupBackToTop = () => { + if (!DOM.backToTop) return + window.addEventListener('scroll', () => { + DOM.backToTop.classList.toggle('visible', window.scrollY > 300) + }) + + DOM.backToTop.addEventListener('click', () => { + window.scrollTo({ top: 0, behavior: 'smooth' }) + }) + } + + // Load Components (Header & Footer) // + const loadComponents = async () => { + try { + const [header, footer] = await Promise.all([ + fetch('/components/header.html').then((res) => res.text()), + fetch('/components/footer.html').then((res) => res.text()), + ]) + + document.getElementById('header-placeholder').innerHTML = header + document.getElementById('footer-placeholder').innerHTML = footer + + // Re-initialize Header-Based Features + setupThemeToggle() + setupMobileMenu() + + // Set Active Nav Link // + const currentPath = window.location.pathname.split('/').pop() + + document + .querySelectorAll('.nav-link, .mobile-nav-link') + .forEach((link) => { + const linkPath = link.getAttribute('href')?.split('/').pop() + if (linkPath === currentPath) { + link.classList.add('active') + } + }) + + // Set Active Footer Link // + document.querySelectorAll('.footer-link').forEach((link) => { + const linkPath = link.getAttribute('href')?.split('/').pop() + if (linkPath === currentPath) { + link.classList.add('active') + } + }) + } catch (error) { + console.error('Error loading header/footer:', error) + } + } + + // Init // + const init = async () => { + if (DOM.typewriterElement) typeWriter() + if (DOM.searchForm) DOM.searchForm.addEventListener('submit', handleSearch) + + if (DOM.yearElement) DOM.yearElement.textContent = new Date().getFullYear() + + // Load Search Data + try { + const response = await fetch('data/search_parameters/parameters.json') + allData.branches = (await response.json()).branches.filter((b) => + b.name?.trim() + ) + + const branchSelect = createDropdown( + DOM.searchBranchContainer, + 'selectBranch', + 'Select Branch', + allData.branches.map((b) => b.name) + ) + + branchSelect?.addEventListener('change', updateSemesters) + } catch (error) { + console.error('Error loading search parameters:', error) } + + // Load Header & Footer + await loadComponents() + + // Load Back To Top Button + DOM.backToTop = document.querySelector('.back-to-top') + setupBackToTop() } - runQuerySearch(); -}); + init() +}) diff --git a/scripts/signup.js b/scripts/signup.js new file mode 100644 index 00000000..6b56a7ac --- /dev/null +++ b/scripts/signup.js @@ -0,0 +1,139 @@ +// Sign Up (JavaScript) + +document.addEventListener('DOMContentLoaded', function () { + // DOM Elements + const signupForm = document.getElementById('signupForm') + const messageBox = document.getElementById('messageBox') + const passwordInput = document.getElementById('password') + const confirmPasswordInput = document.getElementById('confirm-password') + const passwordToggle = document.querySelector('.password-toggle') + const passwordIcon = passwordToggle.querySelector('i') + const signupBtn = document.getElementById('signupBtn') + const spinner = document.getElementById('spinner') + const btnText = document.getElementById('btnText') + + // Constants + const MIN_PASSWORD_LENGTH = 6 + const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/ + + // Toggle Password Visibility + passwordToggle.addEventListener('click', function () { + const isPassword = passwordInput.type === 'password' + passwordInput.type = isPassword ? 'text' : 'password' + passwordIcon.className = isPassword ? 'far fa-eye-slash' : 'far fa-eye' + passwordToggle.setAttribute( + 'aria-label', + isPassword ? 'Hide password' : 'Show password' + ) + }) + + // Floating Label Effect + document.querySelectorAll('.floating-input input').forEach((input) => { + input.addEventListener('focus', () => { + input.parentNode.classList.add('focused') + }) + + input.addEventListener('blur', () => { + if (!input.value) { + input.parentNode.classList.remove('focused') + } + }) + }) + + // Password Strength Validation + passwordInput.addEventListener('input', function () { + validatePasswordStrength() + }) + + function validatePasswordStrength() { + // Add Password Strength Validation Logic While Implemneting User Authentication + } + + // Show Message + function showMessage(text, type) { + messageBox.textContent = text + messageBox.className = `message-box ${type} show` + + setTimeout(() => { + messageBox.classList.remove('show') + }, 3000) + } + + // Set Loading State + function setLoadingState(isLoading) { + if (isLoading) { + spinner.classList.remove('hidden') + btnText.textContent = 'Signing up...' + signupBtn.disabled = true + } else { + spinner.classList.add('hidden') + btnText.textContent = 'Sign up' + signupBtn.disabled = false + } + } + + // Form Validation + function validateForm(name, email, password, confirmPassword) { + if (!name || !email || !password || !confirmPassword) { + showMessage('Please Fill In All Fields', 'error') + return false + } + + if (!EMAIL_REGEX.test(email)) { + showMessage('Please Enter a Valid Email Address', 'error') + return false + } + + if (password.length < MIN_PASSWORD_LENGTH) { + showMessage( + `Password Must Be At Least ${MIN_PASSWORD_LENGTH} Characters`, + 'error' + ) + return false + } + + if (password !== confirmPassword) { + showMessage('Passwords Do Not Match', 'error') + return false + } + + return true + } + + // Form Submission + signupForm.addEventListener('submit', async function (e) { + e.preventDefault() + + const name = document.getElementById('name').value.trim() + const email = document.getElementById('email').value.trim() + const password = document.getElementById('password').value + const confirmPassword = document.getElementById('confirm-password').value + + // Validate Form + if (!validateForm(name, email, password, confirmPassword)) return + + // Set Loading State + setLoadingState(true) + + try { + // Simulate API Call - Replace With Actual Fetch In Production + await new Promise((resolve) => setTimeout(resolve, 1500)) + + // Show Success Message + showMessage( + 'Account Created Successfully! Redirecting To Login...', + 'success' + ) + + // Redirect After Delay + setTimeout(() => { + window.location.href = 'login.html' + }, 2000) + } catch (error) { + console.error('Signup error:', error) + showMessage('Signup Failed. Please Try Again...', 'error') + } finally { + setLoadingState(false) + } + }) +}) diff --git a/scripts/studentAccount.js b/scripts/studentAccount.js deleted file mode 100644 index 6820ecbd..00000000 --- a/scripts/studentAccount.js +++ /dev/null @@ -1,41 +0,0 @@ -document.addEventListener("DOMContentLoaded", function () { - // Mock data — Replace with actual API call or localStorage - const studentData = { - name: "John Doe", - email: "johndoe@example.com", - college: "ABC Institute of Technology", - branch: "Computer Science", - year: "3rd Year", - notes: { - lectures: ["DBMS - Normalization.pdf", "Operating Systems - Deadlock.ppt"], - pyqs: ["CS201 - Midterm 2022.pdf", "CS303 - Final 2021.docx"] - } - }; - - // Populate student details - const profileSection = document.querySelector(".profile"); - profileSection.innerHTML = ` -

    👤 Student Details

    -

    Name: ${studentData.name}

    -

    Email: ${studentData.email}

    -

    College: ${studentData.college}

    -

    Branch: ${studentData.branch}

    -

    Year: ${studentData.year}

    - `; - - // Populate saved notes - const notesSection = document.querySelector(".notes-section"); - notesSection.innerHTML = ` -

    💾 Saved Notes

    -
    -

    Lecture Notes

    -
      ${studentData.notes.lectures.map(note => `
    • ${note}
    • `).join("")}
    - -
    -
    -

    Previous Year Questions (PYQs)

    -
      ${studentData.notes.pyqs.map(note => `
    • ${note}
    • `).join("")}
    - -
    - `; -}); diff --git a/scripts/todolist.js b/scripts/todolist.js index 60c2c09b..40fa081b 100644 --- a/scripts/todolist.js +++ b/scripts/todolist.js @@ -1,230 +1,255 @@ -// Todo List JavaScript - NotesVault +// To-Do List (JavaScript) class TodoList { - constructor() { - this.todos = JSON.parse(localStorage.getItem('notesvault-todos')) || []; - this.currentEditId = null; - this.init(); + constructor() { + this.todos = JSON.parse(localStorage.getItem('notesvault-todos')) || [] + this.currentEditId = null + this.init() + } + + init() { + this.bindEvents() + this.render() + this.updateStats() + } + + bindEvents() { + // Form Submission + const form = document.getElementById('todoForm') + form.addEventListener('submit', (e) => this.handleSubmit(e)) + + // Clear Buttons + document + .getElementById('clearCompleted') + .addEventListener('click', () => this.clearCompleted()) + document + .getElementById('clearAll') + .addEventListener('click', () => this.clearAll()) + + // Task Input Focus + const taskInput = document.getElementById('taskInput') + taskInput.addEventListener('keydown', (e) => { + if (e.key === 'Escape' && this.currentEditId) { + this.cancelEdit() + } + }) + } + + handleSubmit(e) { + e.preventDefault() + const taskInput = document.getElementById('taskInput') + const taskText = taskInput.value.trim() + + if (!taskText) return + + if (this.currentEditId) { + this.updateTask(this.currentEditId, taskText) + } else { + this.addTask(taskText) } - init() { - this.bindEvents(); - this.render(); - this.updateStats(); + taskInput.value = '' + this.currentEditId = null + this.updateAddButton() + } + + addTask(text) { + const task = { + id: Date.now(), + text: text, + completed: false, + createdAt: new Date().toISOString(), } - bindEvents() { - // Form submission - const form = document.getElementById('todoForm'); - form.addEventListener('submit', (e) => this.handleSubmit(e)); - - // Clear buttons - document.getElementById('clearCompleted').addEventListener('click', () => this.clearCompleted()); - document.getElementById('clearAll').addEventListener('click', () => this.clearAll()); - - // Task input focus - const taskInput = document.getElementById('taskInput'); - taskInput.addEventListener('keydown', (e) => { - if (e.key === 'Escape' && this.currentEditId) { - this.cancelEdit(); - } - }); + this.todos.unshift(task) + this.saveToStorage() + this.render() + this.updateStats() + this.showNotification('Task Added Successfully!', 'success') + } + + updateTask(id, text) { + const taskIndex = this.todos.findIndex((todo) => todo.id === id) + if (taskIndex !== -1) { + this.todos[taskIndex].text = text + this.todos[taskIndex].updatedAt = new Date().toISOString() + this.saveToStorage() + this.render() + this.updateStats() + this.showNotification('Task Updated Successfully!', 'success') } - - handleSubmit(e) { - e.preventDefault(); - const taskInput = document.getElementById('taskInput'); - const taskText = taskInput.value.trim(); - - if (!taskText) return; - - if (this.currentEditId) { - this.updateTask(this.currentEditId, taskText); - } else { - this.addTask(taskText); - } - - taskInput.value = ''; - this.currentEditId = null; - this.updateAddButton(); + } + + toggleTask(id) { + const task = this.todos.find((todo) => todo.id === id) + if (task) { + task.completed = !task.completed + this.saveToStorage() + this.render() + this.updateStats() } - - addTask(text) { - const task = { - id: Date.now(), - text: text, - completed: false, - createdAt: new Date().toISOString() - }; - - this.todos.unshift(task); - this.saveToStorage(); - this.render(); - this.updateStats(); - this.showNotification('Task added successfully!', 'success'); + } + + deleteTask(id) { + if (confirm('Are you sure you want to delete this task?')) { + this.todos = this.todos.filter((todo) => todo.id !== id) + this.saveToStorage() + this.render() + this.updateStats() + this.showNotification('Task Deleted Successfully!', 'info') } - - updateTask(id, text) { - const taskIndex = this.todos.findIndex(todo => todo.id === id); - if (taskIndex !== -1) { - this.todos[taskIndex].text = text; - this.todos[taskIndex].updatedAt = new Date().toISOString(); - this.saveToStorage(); - this.render(); - this.updateStats(); - this.showNotification('Task updated successfully!', 'success'); - } + } + + editTask(id) { + const task = this.todos.find((todo) => todo.id === id) + if (task) { + this.currentEditId = id + const taskInput = document.getElementById('taskInput') + taskInput.value = task.text + taskInput.focus() + taskInput.select() + this.updateAddButton() } - - toggleTask(id) { - const task = this.todos.find(todo => todo.id === id); - if (task) { - task.completed = !task.completed; - this.saveToStorage(); - this.render(); - this.updateStats(); - } + } + + cancelEdit() { + this.currentEditId = null + const taskInput = document.getElementById('taskInput') + taskInput.value = '' + this.updateAddButton() + } + + clearCompleted() { + const completedCount = this.todos.filter((todo) => todo.completed).length + if (completedCount === 0) { + this.showNotification('No Completed Tasks To Clear!', 'warning') + return } - deleteTask(id) { - if (confirm('Are you sure you want to delete this task?')) { - this.todos = this.todos.filter(todo => todo.id !== id); - this.saveToStorage(); - this.render(); - this.updateStats(); - this.showNotification('Task deleted successfully!', 'info'); - } + if ( + confirm( + `Are you sure you want to delete ${completedCount} completed task(s)?` + ) + ) { + this.todos = this.todos.filter((todo) => !todo.completed) + this.saveToStorage() + this.render() + this.updateStats() + this.showNotification( + `${completedCount} completed task(s) cleared!`, + 'success' + ) } + } - editTask(id) { - const task = this.todos.find(todo => todo.id === id); - if (task) { - this.currentEditId = id; - const taskInput = document.getElementById('taskInput'); - taskInput.value = task.text; - taskInput.focus(); - taskInput.select(); - this.updateAddButton(); - } - } - - cancelEdit() { - this.currentEditId = null; - const taskInput = document.getElementById('taskInput'); - taskInput.value = ''; - this.updateAddButton(); + clearAll() { + if (this.todos.length === 0) { + this.showNotification('No Tasks To Clear!', 'warning') + return } - clearCompleted() { - const completedCount = this.todos.filter(todo => todo.completed).length; - if (completedCount === 0) { - this.showNotification('No completed tasks to clear!', 'warning'); - return; - } - - if (confirm(`Are you sure you want to delete ${completedCount} completed task(s)?`)) { - this.todos = this.todos.filter(todo => !todo.completed); - this.saveToStorage(); - this.render(); - this.updateStats(); - this.showNotification(`${completedCount} completed task(s) cleared!`, 'success'); - } + if ( + confirm( + `Are you sure you want to delete all ${this.todos.length} task(s)?` + ) + ) { + this.todos = [] + this.saveToStorage() + this.render() + this.updateStats() + this.showNotification('All Tasks Cleared!', 'success') } + } - clearAll() { - if (this.todos.length === 0) { - this.showNotification('No tasks to clear!', 'warning'); - return; - } + render() { + const todoList = document.getElementById('todoList') + const emptyState = document.getElementById('emptyState') - if (confirm(`Are you sure you want to delete all ${this.todos.length} task(s)?`)) { - this.todos = []; - this.saveToStorage(); - this.render(); - this.updateStats(); - this.showNotification('All tasks cleared!', 'success'); - } + if (this.todos.length === 0) { + todoList.innerHTML = '' + emptyState.classList.add('show') + return } - render() { - const todoList = document.getElementById('todoList'); - const emptyState = document.getElementById('emptyState'); + emptyState.classList.remove('show') + todoList.innerHTML = this.todos + .map((todo) => this.createTaskElement(todo)) + .join('') + } - if (this.todos.length === 0) { - todoList.innerHTML = ''; - emptyState.classList.add('show'); - return; - } + createTaskElement(todo) { + const completedClass = todo.completed ? 'completed' : '' + const checked = todo.completed ? 'checked' : '' - emptyState.classList.remove('show'); - todoList.innerHTML = this.todos.map(todo => this.createTaskElement(todo)).join(''); - } - - createTaskElement(todo) { - const completedClass = todo.completed ? 'completed' : ''; - const checked = todo.completed ? 'checked' : ''; - - return ` + return `
  • ${this.escapeHtml(todo.text)}
    - -
  • - `; - } - - updateStats() { - const totalTasks = this.todos.length; - const completedTasks = this.todos.filter(todo => todo.completed).length; - - document.getElementById('taskCount').textContent = `${totalTasks} task${totalTasks !== 1 ? 's' : ''}`; - document.getElementById('completedCount').textContent = `${completedTasks} completed`; - } - - updateAddButton() { - const addBtn = document.querySelector('.add-btn'); - const addBtnText = addBtn.querySelector('span') || addBtn; - - if (this.currentEditId) { - addBtn.innerHTML = 'Update Task'; - } else { - addBtn.innerHTML = 'Add Task'; - } - } - - saveToStorage() { - localStorage.setItem('notesvault-todos', JSON.stringify(this.todos)); - } - - escapeHtml(text) { - const div = document.createElement('div'); - div.textContent = text; - return div.innerHTML; + ` + } + + updateStats() { + const totalTasks = this.todos.length + const completedTasks = this.todos.filter((todo) => todo.completed).length + + document.getElementById('taskCount').textContent = `${totalTasks} Task${ + totalTasks !== 1 ? 's' : '' + }` + document.getElementById( + 'completedCount' + ).textContent = `${completedTasks} Completed` + } + + updateAddButton() { + const addBtn = document.querySelector('.add-btn') + const addBtnText = addBtn.querySelector('span') || addBtn + + if (this.currentEditId) { + addBtn.innerHTML = 'Update Task' + } else { + addBtn.innerHTML = 'Add Task' } - - showNotification(message, type = 'info') { - // Create notification element - const notification = document.createElement('div'); - notification.className = `notification notification-${type}`; - notification.innerHTML = ` + } + + saveToStorage() { + localStorage.setItem('notesvault-todos', JSON.stringify(this.todos)) + } + + escapeHtml(text) { + const div = document.createElement('div') + div.textContent = text + return div.innerHTML + } + + showNotification(message, type = 'info') { + // Create Notification Element + const notification = document.createElement('div') + notification.className = `notification notification-${type}` + notification.innerHTML = `
    ${message}
    - `; + ` - // Add styles - notification.style.cssText = ` + // Add Styles + notification.style.cssText = ` position: fixed; top: 20px; right: 20px; @@ -238,85 +263,61 @@ class TodoList { transition: transform 0.3s ease; max-width: 300px; font-family: 'Poppins', sans-serif; - `; - - // Add to page - document.body.appendChild(notification); - - // Animate in - setTimeout(() => { - notification.style.transform = 'translateX(0)'; - }, 100); - - // Remove after 3 seconds - setTimeout(() => { - notification.style.transform = 'translateX(100%)'; - setTimeout(() => { - if (notification.parentNode) { - notification.parentNode.removeChild(notification); - } - }, 300); - }, 3000); - } - - getNotificationIcon(type) { - const icons = { - success: 'fa-check-circle', - error: 'fa-exclamation-circle', - warning: 'fa-exclamation-triangle', - info: 'fa-info-circle' - }; - return icons[type] || icons.info; + ` + + // Add To Page + document.body.appendChild(notification) + + // Animate In + setTimeout(() => { + notification.style.transform = 'translateX(0)' + }, 100) + + // Remove After 3 Seconds + setTimeout(() => { + notification.style.transform = 'translateX(100%)' + setTimeout(() => { + if (notification.parentNode) { + notification.parentNode.removeChild(notification) + } + }, 300) + }, 3000) + } + + getNotificationIcon(type) { + const icons = { + success: 'fa-check-circle', + error: 'fa-exclamation-circle', + warning: 'fa-exclamation-triangle', + info: 'fa-info-circle', } - - getNotificationColor(type) { - const colors = { - success: '#10b981', - error: '#ef4444', - warning: '#f59e0b', - info: '#3b82f6' - }; - return colors[type] || colors.info; + return icons[type] || icons.info + } + + getNotificationColor(type) { + const colors = { + success: '#10b981', + error: '#ef4444', + warning: '#f59e0b', + info: '#3b82f6', } + return colors[type] || colors.info + } } -// Initialize todo list when DOM is loaded -let todoList; +// Initialize To-Do List When DOM Is Loaded +let todoList document.addEventListener('DOMContentLoaded', () => { - todoList = new TodoList(); -}); + todoList = new TodoList() +}) -// Add keyboard shortcuts +// Add Keyboard Shortcuts document.addEventListener('keydown', (e) => { - // Ctrl/Cmd + Enter to submit form - if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') { - const form = document.getElementById('todoForm'); - if (form) { - form.dispatchEvent(new Event('submit')); - } - } -}); - -// Add smooth scrolling for scroll to top button -document.addEventListener('DOMContentLoaded', () => { - const scrollToTopBtn = document.getElementById('scrollToTopBtn'); - - if (scrollToTopBtn) { - // Show/hide button based on scroll position - window.addEventListener('scroll', () => { - if (window.pageYOffset > 300) { - scrollToTopBtn.style.display = 'block'; - } else { - scrollToTopBtn.style.display = 'none'; - } - }); - - // Smooth scroll to top - scrollToTopBtn.addEventListener('click', () => { - window.scrollTo({ - top: 0, - behavior: 'smooth' - }); - }); + // Ctrl/Cmd + Enter To Submit Form + if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') { + const form = document.getElementById('todoForm') + if (form) { + form.dispatchEvent(new Event('submit')) } -}); \ No newline at end of file + } +}) diff --git a/scripts/upload.js b/scripts/upload.js index 0723f0a9..2e6bbe1d 100644 --- a/scripts/upload.js +++ b/scripts/upload.js @@ -1,52 +1,331 @@ -const dropZone = document.getElementById("drop-zone"); -const fileInput = document.getElementById("file"); -const preview = document.getElementById("preview"); - -dropZone.addEventListener("click", () => fileInput.click()); - -fileInput.addEventListener("change", () => { - if (fileInput.files.length) { - handleFile(fileInput.files[0]); - } -}); - - ["dragenter", "dragover", "dragleave", "drop"].forEach(event => { - dropZone.addEventListener(event, e => { - e.preventDefault(); - e.stopPropagation(); - }); -}); - -["dragenter", "dragover"].forEach(event => { - dropZone.addEventListener(event, () => { - dropZone.classList.add("bg-blue-50", "border-blue-400", "text-blue-500"); - }); -}); - -["dragleave", "drop"].forEach(event => { - dropZone.addEventListener(event, () => { - dropZone.classList.remove("bg-blue-50", "border-blue-400", "text-blue-500"); - }); -}); - -dropZone.addEventListener("drop", e => { - const files = e.dataTransfer.files; - if (files.length) { - handleFile(files[0]); - } -}); - - function handleFile(file) { - preview.innerHTML = `

    Selected: ${file.name}

    `; - - if (file.type.startsWith("image/")) { - const reader = new FileReader(); - reader.onload = () => { - const img = document.createElement("img"); - img.src = reader.result; - img.classList.add("mt-2", "mx-auto", "max-w-[200px]", "rounded-md", "shadow"); - preview.appendChild(img); - }; - reader.readAsDataURL(file); +// Upload Notes (JavaScript) + +document.addEventListener('DOMContentLoaded', function () { + let branchData + const branchSelect = document.getElementById('branch') + const semesterSelect = document.getElementById('semester') + const subjectSelect = document.getElementById('subject') + + // Custom Input Containers + const customBranchContainer = document.getElementById('customBranchContainer') + const customSemesterContainer = document.getElementById( + 'customSemesterContainer' + ) + const customSubjectContainer = document.getElementById( + 'customSubjectContainer' + ) + + // Initialize Form State + function initializeForm() { + semesterSelect.disabled = true + subjectSelect.disabled = true + customBranchContainer.style.display = 'none' + customSemesterContainer.style.display = 'none' + customSubjectContainer.style.display = 'none' + } + + // Fetch Branch Data + function loadBranchData() { + fetch('../data/parameters.json') + .then((response) => { + if (!response.ok) throw new Error('Network response was not ok') + return response.json() + }) + .then((data) => { + branchData = data + populateBranches(data.branches) + }) + .catch((error) => { + console.error('Error loading branch data:', error) + showMessage( + 'Failed to load branch data. Please try again later.', + 'error' + ) + }) + } + + // Populate Branches Dropdown + function populateBranches(branches) { + branchSelect.innerHTML = + '' + + branches.forEach((branch) => { + const option = document.createElement('option') + option.value = typeof branch === 'object' ? branch.name : branch + option.textContent = typeof branch === 'object' ? branch.name : branch + branchSelect.appendChild(option) + }) + } + + // Handle Branch Selection Change + function handleBranchChange() { + const selectedBranch = this.value + semesterSelect.innerHTML = + '' + subjectSelect.innerHTML = + '' + + if (selectedBranch === 'custom') { + customBranchContainer.style.display = 'flex' + semesterSelect.disabled = true + subjectSelect.disabled = true + return + } + + customBranchContainer.style.display = 'none' + semesterSelect.disabled = false + subjectSelect.disabled = true + + const branch = branchData.branches.find((b) => + typeof b === 'object' ? b.name === selectedBranch : b === selectedBranch + ) + + if (branch && typeof branch === 'object') { + branch.semesters.forEach((sem) => { + const option = document.createElement('option') + option.value = sem.semester + option.textContent = `Semester ${sem.semester}` + semesterSelect.appendChild(option) + }) + } + } + + // Handle Semester Selection Change + function handleSemesterChange() { + const selectedSemester = this.value + subjectSelect.innerHTML = + '' + + if (selectedSemester === 'custom') { + customSemesterContainer.style.display = 'flex' + subjectSelect.disabled = true + return + } + + customSemesterContainer.style.display = 'none' + subjectSelect.disabled = false + + const branch = branchSelect.value + const semester = parseInt(selectedSemester) + const branchObj = branchData.branches.find((b) => + typeof b === 'object' ? b.name === branch : b === branch + ) + + if (branchObj && typeof branchObj === 'object') { + const semesterObj = branchObj.semesters.find( + (s) => s.semester === semester + ) + if (semesterObj) { + semesterObj.subjects.forEach((sub) => { + const code = Object.keys(sub)[0] + const name = sub[code] + const option = document.createElement('option') + option.value = code + option.textContent = `${code} - ${name}` + subjectSelect.appendChild(option) + }) } - } \ No newline at end of file + } + } + + // Handle Subject Selection Change + function handleSubjectChange() { + if (this.value === 'custom') { + customSubjectContainer.style.display = 'flex' + return + } + customSubjectContainer.style.display = 'none' + } + + // Confirm Custom Branch + function confirmCustomBranch() { + const customBranch = document.getElementById('customBranch').value.trim() + if (!customBranch) { + showMessage('Please enter a branch name', 'error') + return + } + + const option = document.createElement('option') + option.value = customBranch + option.textContent = customBranch + branchSelect.insertBefore(option, branchSelect.lastChild) + branchSelect.value = customBranch + customBranchContainer.style.display = 'none' + semesterSelect.disabled = false + document.getElementById('customBranch').value = '' + } + + // Confirm Custom Semester + function confirmCustomSemester() { + const customSemester = document + .getElementById('customSemester') + .value.trim() + if (!customSemester) { + showMessage('Please enter a semester number', 'error') + return + } + + const option = document.createElement('option') + option.value = customSemester + option.textContent = `Semester ${customSemester}` + semesterSelect.insertBefore(option, semesterSelect.lastChild) + semesterSelect.value = customSemester + customSemesterContainer.style.display = 'none' + subjectSelect.disabled = false + document.getElementById('customSemester').value = '' + } + + // Confirm Custom Subject + function confirmCustomSubject() { + const code = document.getElementById('customSubjectCode').value.trim() + const name = document.getElementById('customSubjectName').value.trim() + + if (!code || !name) { + showMessage('Please enter both subject code and name', 'error') + return + } + + const option = document.createElement('option') + option.value = code + option.textContent = `${code} - ${name}` + subjectSelect.insertBefore(option, subjectSelect.lastChild) + subjectSelect.value = code + customSubjectContainer.style.display = 'none' + document.getElementById('customSubjectCode').value = '' + document.getElementById('customSubjectName').value = '' + } + + // File Drop Zone Functionality + function setupFileDropZone() { + const dropZone = document.getElementById('drop-zone') + const fileInput = document.getElementById('file') + const preview = document.getElementById('preview') + + dropZone.addEventListener('click', () => fileInput.click()) + + fileInput.addEventListener('change', handleFileSelect) + ;['dragenter', 'dragover'].forEach((eventName) => { + dropZone.addEventListener(eventName, highlightDropZone) + }) + ;['dragleave', 'drop'].forEach((eventName) => { + dropZone.addEventListener(eventName, unhighlightDropZone) + }) + + dropZone.addEventListener('drop', handleDrop) + } + + function highlightDropZone(e) { + e.preventDefault() + e.stopPropagation() + document.getElementById('drop-zone').classList.add('active') + } + + function unhighlightDropZone(e) { + e.preventDefault() + e.stopPropagation() + document.getElementById('drop-zone').classList.remove('active') + } + + function handleDrop(e) { + const dt = e.dataTransfer + const files = dt.files + fileInput.files = files + handleFileSelect({ target: fileInput }) + } + + function handleFileSelect(e) { + const files = e.target.files + const preview = document.getElementById('preview') + + if (!files.length) return + + preview.innerHTML = '' + const file = files[0] + + if (!file.type.match('application/pdf')) { + showMessage('Please upload a PDF file', 'error') + return + } + + const fileInfo = document.createElement('div') + fileInfo.textContent = `Selected: ${file.name} (${formatFileSize( + file.size + )})` + preview.appendChild(fileInfo) + } + + function formatFileSize(bytes) { + if (bytes === 0) return '0 Bytes' + const k = 1024 + const sizes = ['Bytes', 'KB', 'MB', 'GB'] + const i = Math.floor(Math.log(bytes) / Math.log(k)) + return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i] + } + + // Show Status Message + function showMessage(text, type) { + const message = document.getElementById('message') + message.textContent = text + message.className = `status-message status-${type}` + + // Auto-Hide Message After 5 Seconds + setTimeout(() => { + message.textContent = '' + message.className = 'status-message' + }, 5000) + } + + // Form Submission + function handleFormSubmit(e) { + e.preventDefault() + + // Validate Form + const title = document.getElementById('title').value.trim() + const file = document.getElementById('file').files[0] + + if (!title || !file) { + showMessage('Please fill all required fields', 'error') + return + } + + // Simulate Successful Upload + showMessage( + 'Notes Uploaded Successfully (For Demo Purposes Only - Not Stored)', + 'success' + ) + + // Reset Form + this.reset() + document.getElementById('preview').innerHTML = '' + initializeForm() + } + + // Initialize Application + function init() { + initializeForm() + loadBranchData() + + // Event Listeners + branchSelect.addEventListener('change', handleBranchChange) + semesterSelect.addEventListener('change', handleSemesterChange) + subjectSelect.addEventListener('change', handleSubjectChange) + + document + .getElementById('confirmBranch') + .addEventListener('click', confirmCustomBranch) + document + .getElementById('confirmSemester') + .addEventListener('click', confirmCustomSemester) + document + .getElementById('confirmSubject') + .addEventListener('click', confirmCustomSubject) + + document + .getElementById('uploadForm') + .addEventListener('submit', handleFormSubmit) + + setupFileDropZone() + } + + init() +}) diff --git a/scripts/utilities.js b/scripts/utilities.js deleted file mode 100644 index 922766eb..00000000 --- a/scripts/utilities.js +++ /dev/null @@ -1,88 +0,0 @@ -// Utility functions for NotesVault -// Common helper functions used across multiple JavaScript files - -/** - * Creates a dropdown select element with options - * @param {HTMLElement} container - The container to append the dropdown to - * @param {string} id - The ID for the select element - * @param {string} defaultText - The default placeholder text - * @param {Array} options - Array of option values - * @returns {HTMLSelectElement} The created select element - */ -function createDropdown(container, id, defaultText, options) { - // Clear the container first - container.innerHTML = ''; - - // Create the