diff --git a/core/static/css/index.css b/core/static/css/index.css index b335f1d..3c187d7 100644 --- a/core/static/css/index.css +++ b/core/static/css/index.css @@ -12,6 +12,16 @@ --feature-title-color: #12241f; --feature-description-color: #F0F7E6; } +.trail-dot { + position: fixed; + width: 12px; + height: 12px; + border-radius: 50%; + background-color: #6024eb; + pointer-events: none; + transform: translate(-50%, -50%); + z-index: 9999; + } body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: linear-gradient(135deg, #0f172a 0%, #1e293b 30%, #334155 100%); diff --git a/core/static/js/index.js b/core/static/js/index.js index 802d347..f2a2135 100644 --- a/core/static/js/index.js +++ b/core/static/js/index.js @@ -1,54 +1,5 @@ -// Theme management -const THEME_KEY = "peerprep_theme"; - -function applyThemeFromStorage() { - let theme = localStorage.getItem(THEME_KEY); - - // Set default theme to dark if not set - if (!theme) { - theme = "dark"; - localStorage.setItem(THEME_KEY, theme); - } - - if (theme === "light") { - document.body.classList.add("light-mode"); - setLightModeIcon(true); - } else { - document.body.classList.remove("light-mode"); - setLightModeIcon(false); - } -} - -function setLightModeIcon(isLight) { - const icon = document.getElementById("modeToggle")?.querySelector("i"); - if (!icon) return; - - if (isLight) { - icon.classList.remove("fa-moon"); - icon.classList.add("fa-sun"); - icon.title = "Switch to Dark Mode"; - } else { - icon.classList.remove("fa-sun"); - icon.classList.add("fa-moon"); - icon.title = "Switch to Light Mode"; - } -} - -function toggleMode() { - const isNowLight = !document.body.classList.contains("light-mode"); - - if (isNowLight) { - document.body.classList.add("light-mode"); - } else { - document.body.classList.remove("light-mode"); - } - - setLightModeIcon(isNowLight); - localStorage.setItem(THEME_KEY, isNowLight ? "light" : "dark"); -} - // Smooth scrolling for navigation links -document.querySelectorAll('a[href^="#"]').forEach(anchor => { + document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function (e) { e.preventDefault(); const target = document.querySelector(this.getAttribute('href')); @@ -62,7 +13,7 @@ document.querySelectorAll('a[href^="#"]').forEach(anchor => { }); // Form submission with Django backend -document.querySelector('.contact-form')?.addEventListener('submit', function(e) { +document.querySelector('.contact-form').addEventListener('submit', function(e) { e.preventDefault(); const submitBtn = document.querySelector('.submit-btn'); @@ -155,9 +106,104 @@ document.querySelectorAll('.form-input').forEach(input => { this.parentElement.style.transform = 'translateY(0)'; }); }); +// Adding success stories + +document.addEventListener("DOMContentLoaded", function () { + const modal = document.getElementById("storyModal"); + const btn = document.getElementById("addStoryBtn"); + const span = document.querySelector(".modal .close"); + const form = document.getElementById("storyForm"); + const storiesContainer = document.getElementById("storiesContainer"); + + // Open modal + btn?.addEventListener("click", () => modal.style.display = "block"); + + // Close modal + span?.addEventListener("click", () => modal.style.display = "none"); + window.addEventListener("click", e => { + if (e.target == modal) modal.style.display = "none"; + }); + + // AJAX form submission + form?.addEventListener("submit", function (e) { + e.preventDefault(); + const url = form.action; + const formData = new FormData(form); + + fetch(url, { + method: "POST", + headers: { "X-Requested-With": "XMLHttpRequest" }, + body: formData, + }) + .then(response => response.json()) + .then(data => { + if (data.success) { + // Close modal + modal.style.display = "none"; + form.reset(); + + // Append new story + const newStory = document.createElement("div"); + newStory.classList.add("feature-card"); + newStory.innerHTML = ` +
🏆
+

${data.title}

+

${data.story}

+ By ${data.user} + `; + storiesContainer.prepend(newStory); + } else { + alert("Error: " + JSON.stringify(data.errors)); + } + }) + .catch(err => console.error(err)); + }); +}); + +// Dark Mode to Light Mode toggle + +const THEME_KEY="theme"; -// Login form handling -document.querySelector('.login-form')?.addEventListener('submit', function(e) { +function applyThemeFromStorage() { + let theme = localStorage.getItem(THEME_KEY); + if (!theme) { + theme = "dark"; + localStorage.setItem(THEME_KEY, theme); + } + + if (theme === "light") { + document.body.classList.add("light-mode"); + document.body.classList.remove("dark-mode"); + setLightModeIcon(true); + } else { + document.body.classList.remove("light-mode"); + document.body.classList.add("dark-mode"); + setLightModeIcon(false); + } +} + +function setLightModeIcon(isLight){ + const icon = document.getElementById("modeToggle").querySelector("i"); + if (!icon) return; + if (isLight) { + icon.classList.remove("fa-sun"); + icon.classList.add("fa-moon"); + } else { + icon.classList.remove("fa-moon"); + icon.classList.add("fa-sun"); + } +} +function toggleMode() +{ + const isNowLight=!document.body.classList.contains("light-mode"); + document.body.classList.toggle("light-mode"); + setLightModeIcon(isNowLight); + localStorage.setItem(THEME_KEY, isNowLight ? "light" : "dark"); + applyThemeFromStorage(); +} +window.addEventListener("DOMContentLoaded", applyThemeFromStorage); +// Add this new section for the login form +document.querySelector('.login-form').addEventListener('submit', function(e) { e.preventDefault(); const submitBtn = this.querySelector('.submit-btn'); @@ -167,6 +213,7 @@ document.querySelector('.login-form')?.addEventListener('submit', function(e) { submitBtn.textContent = 'Signing In...'; submitBtn.disabled = true; + // The fetch URL should be the login endpoint fetch(this.action, { method: 'POST', body: formData, @@ -181,7 +228,8 @@ document.querySelector('.login-form')?.addEventListener('submit', function(e) { submitBtn.style.background = 'linear-gradient(135deg, #10b981, #059669)'; showNotification('Login successful!', 'success'); - window.location.href = data.redirect_url || '/dashboard/'; + // Redirect to dashboard or home page on successful login + window.location.href = data.redirect_url || '{% url "dashboard" %}'; } else { submitBtn.textContent = 'Try Again'; submitBtn.disabled = false; @@ -203,80 +251,32 @@ document.querySelector('.login-form')?.addEventListener('submit', function(e) { }); }); -// Initialize theme on page load -document.addEventListener('DOMContentLoaded', function() { - applyThemeFromStorage(); -}); -// Enhanced theme management with session storage fallback -function getStoredTheme() { - // Try localStorage first, then sessionStorage, then default to dark - return localStorage.getItem(THEME_KEY) || - sessionStorage.getItem(THEME_KEY) || - 'dark'; -} - -function setStoredTheme(theme) { - // Store in both localStorage and sessionStorage for redundancy - localStorage.setItem(THEME_KEY, theme); - sessionStorage.setItem(THEME_KEY, theme); -} - -function applyThemeFromStorage() { - const theme = getStoredTheme(); - - if (theme === "light") { - document.body.classList.add("light-mode"); - setLightModeIcon(true); - } else { - document.body.classList.remove("light-mode"); - setLightModeIcon(false); - } -} - -function toggleMode() { - const isNowLight = !document.body.classList.contains("light-mode"); - const newTheme = isNowLight ? "light" : "dark"; - - if (isNowLight) { - document.body.classList.add("light-mode"); - } else { - document.body.classList.remove("light-mode"); + // Number of trail dots + const trailCount = 15; + const trail = []; + + for (let i = 0; i < trailCount; i++) { + const dot = document.createElement('div'); + dot.className = 'trail-dot'; + document.body.appendChild(dot); + trail.push({el: dot, x: 0, y: 0}); + } + + document.addEventListener('mousemove', (e) => { + trail[0].x = e.clientX; + trail[0].y = e.clientY; + }); + + function animateTrail() { + for (let i = trail.length - 1; i > 0; i--) { + trail[i].x += (trail[i-1].x - trail[i].x) * 0.25; + trail[i].y += (trail[i-1].y - trail[i].y) * 0.25; + trail[i].el.style.left = trail[i].x + 'px'; + trail[i].el.style.top = trail[i].y + 'px'; } - - setLightModeIcon(isNowLight); - setStoredTheme(newTheme); - - // Sync with server session - syncThemeWithServer(newTheme); -} - -function syncThemeWithServer(theme) { - // Optional: Sync theme preference with server - fetch('/api/toggle-theme/', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-Requested-With': 'XMLHttpRequest', - 'X-CSRFToken': getCookie('csrftoken'), - }, - body: JSON.stringify({theme: theme}) - }).catch(error => { - console.log('Theme sync failed, but local storage will persist'); - }); -} + trail[0].el.style.left = trail[0].x + 'px'; + trail[0].el.style.top = trail[0].y + 'px'; + requestAnimationFrame(animateTrail); + } -// Helper function to get CSRF token -function getCookie(name) { - let cookieValue = null; - if (document.cookie && document.cookie !== '') { - const cookies = document.cookie.split(';'); - for (let i = 0; i < cookies.length; i++) { - const cookie = cookies[i].trim(); - if (cookie.substring(0, name.length + 1) === (name + '=')) { - cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); - break; - } - } - } - return cookieValue; -} \ No newline at end of file + animateTrail(); \ No newline at end of file diff --git a/core/templates/about.html b/core/templates/about.html index 5e7d7a5..2d2a2b4 100644 --- a/core/templates/about.html +++ b/core/templates/about.html @@ -83,46 +83,6 @@ transform: translateY(-10px) scale(1.03); box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2); } -.feature { - display: flex; - align-items: center; - gap: 1rem; - margin-bottom: 1.5rem; - opacity: 0; - transform: translateY(30px); - animation: fadeInUp 0.8s forwards; -} - -.feature-icon i { - font-size: 2rem; - color: #00e6ff; -} - -.card.fade-in { - opacity: 0; - transform: translateY(20px); - animation: fadeInUp 0.5s forwards; - animation-delay: 0.2s; -} - -@keyframes fadeInUp { - to { - opacity: 1; - transform: translateY(0); - } -} - -/* Responsive adjustments */ -@media (max-width: 768px) { - .cards { - flex-direction: column; - gap: 1rem; - } - .feature { - flex-direction: column; - text-align: center; - } -} @@ -133,50 +93,34 @@

About PeerPrep

-

Our Mission

-
-
- -
-
-

At PeerPrep, our mission is to empower open-source communities by giving project maintainers and contributors the tools they need to collaborate effectively.

-
-
-
+

Our Mission

+

At PeerPrep, our mission is to empower open-source communities by giving project maintainers and contributors the tools they need to collaborate effectively. + We believe in making project management transparent, efficient, and engaging.

+ -
-

Our Vision

-
-
- -
-
-

We envision a future where open-source development is seamless, contributors feel valued, and maintainers focus on innovation.

-
-
-
+
+

Our Vision

+

We envision a future where open-source development is seamless, where contributors feel valued, and where project maintainers + can focus on innovation instead of repetitive management tasks.

+
-
-

What We Offer

-
-
- -

Collaboration

-

Streamlined dashboards for admins and contributors to stay in sync.

-
-
- -

Transparency

-

Track contributions, pull requests, and issues with clear visibility.

-
-
- -

Community

-

Encourage growth and engagement within open-source projects.

+
+

What We Offer

+
+
+

Collaboration

+

Streamlined dashboards for project admins and contributors to stay in sync.

+
+
+

Transparency

+

Track contributions, pull requests, and issues with clear visibility.

+
+
+

Community

+

Encourage growth and engagement within open-source projects.

+
-
-
- +

Looking Ahead

diff --git a/core/templates/dashboard.html b/core/templates/dashboard.html index 2bf9db8..33e0a5e 100644 --- a/core/templates/dashboard.html +++ b/core/templates/dashboard.html @@ -1,5 +1,46 @@ -{% extends "base.html" %} -{% block content %} +{% load static %} + + + + + + Dashboard - Peer Prep + + + + +
+
+
+
+ + + +
@@ -42,28 +83,8 @@

Reminders & Timetable

👥

Find Study Partners

-

Connect with peers who share your learning goals and interests.

- - - -
- -
-
🤝
-

My Study Partners

-

Manage your study partnerships and schedule collaborative sessions.

- - - -
- -
-
📧
-

Partner Requests

-

View and respond to study partner requests from other students.

- - - +

Connect with peers who share your learning goals and interests. Find

+
@@ -76,10 +97,8 @@

Study Materials

📈

Progress Tracking

-

Monitor your learning progress, set goals, and track achievements with detailed analytics.

- - - +

Monitor your learning progress and achievements.

+
@@ -119,4 +138,7 @@

Live Chat

border-color: rgba(59, 130, 246, 0.4); } -{% endblock content %} \ No newline at end of file + {% include "footer.html" %} + + + \ No newline at end of file diff --git a/core/templates/profile.html b/core/templates/profile.html new file mode 100644 index 0000000..5adf2f5 --- /dev/null +++ b/core/templates/profile.html @@ -0,0 +1,138 @@ +{% load static %} + + + + + + Profile - Peer Prep + + + + + + +
+
+

Hello {{ user.username }} 👋

+

Welcome back to Peer Prep!

+
+ +
+
+

Email

+

{{ user.email }}

+
+ +
+

Joined On

+

{{ user.date_joined|date:"F j, Y" }}

+
+
+ +
+ Dashboard + Change Password +
+ {% csrf_token %} + +
+
+
+ + diff --git a/core/templates/questions.html b/core/templates/questions.html new file mode 100644 index 0000000..fea0e3d --- /dev/null +++ b/core/templates/questions.html @@ -0,0 +1,1516 @@ + + + + + + Questions & Answers - PeerPrep + + + + +
+
+
+ + + + + +
+
+ +
+
+

Questions & Answers

+

+ Get help from the community! Ask questions, share knowledge, and learn together. +

+
+
+ +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+
+ Loading questions... +
+ + + +
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/core/templates/timetable.html b/core/templates/timetable.html index 33576b6..db1692f 100644 --- a/core/templates/timetable.html +++ b/core/templates/timetable.html @@ -6,19 +6,6 @@ Reminders & Timetable - PeerPrep - -