From aa8dad9809ef3452fbe82c150840f4e70c3b60c1 Mon Sep 17 00:00:00 2001 From: Cipher Vance Date: Tue, 9 Sep 2025 08:30:05 -0500 Subject: [PATCH] feat(ui): integrate login/signup into navbar, enhance login flow, and set dynamic titles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Removed outdated comments and unused component - Cleaned up login.css header comment - Updated Home.vue navigation to use for Login/Sign Up - Enhanced UserLogin.vue: • Added loginSuccess state, success styling, and green “Success! Redirecting” feedback • Redirect to homepage (/) after sign-in • Persist user data & simple auth token in local/session storage • Updated API call URL to /auth/login - Added route definitions for /signup in router - Added meta.title to Home/Login/Sign Up routes and global afterEach hook to update document.title - Simplified unused methods and cleaned up commented code in Home.vue --- src/assets/css/components/login.css | 1 - src/assets/css/components/signup.css | 517 +++++++++++++++++++++++++++ src/components/Home.vue | 24 +- src/components/LoggedinPage.vue | 19 - src/components/UserLogin.vue | 45 ++- src/components/UserSignup.vue | 344 ++++++++++++++++++ src/router/index.js | 47 +-- 7 files changed, 924 insertions(+), 73 deletions(-) create mode 100644 src/assets/css/components/signup.css delete mode 100644 src/components/LoggedinPage.vue create mode 100644 src/components/UserSignup.vue diff --git a/src/assets/css/components/login.css b/src/assets/css/components/login.css index 028b58d..4690cd8 100644 --- a/src/assets/css/components/login.css +++ b/src/assets/css/components/login.css @@ -1,4 +1,3 @@ -/* login.css */ * { margin: 0; padding: 0; diff --git a/src/assets/css/components/signup.css b/src/assets/css/components/signup.css new file mode 100644 index 0000000..5e8afc9 --- /dev/null +++ b/src/assets/css/components/signup.css @@ -0,0 +1,517 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +.signup-page { + min-height: 100vh; + background: linear-gradient(135deg, #0c0c0c 0%, #1a1a2e 50%, #16213e 100%); + display: flex; + align-items: center; + justify-content: center; + position: relative; + overflow: hidden; + font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; +} + +.signup-bg { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: radial-gradient(circle at 20% 80%, rgba(0, 212, 255, 0.05) 0%, transparent 50%), + radial-gradient(circle at 80% 20%, rgba(124, 58, 237, 0.05) 0%, transparent 50%); +} + +.floating-elements { + position: absolute; + width: 100%; + height: 100%; + pointer-events: none; +} + +.floating-element { + position: absolute; + width: 3px; + height: 3px; + background: linear-gradient(45deg, #00d4ff, #7c3aed); + border-radius: 50%; + animation: float 8s ease-in-out infinite; +} + +@keyframes float { + 0%, 100% { + transform: translateY(0px) rotate(0deg); + opacity: 0.3; + } + 50% { + transform: translateY(-30px) rotate(180deg); + opacity: 0.8; + } +} + +.signup-container { + position: relative; + z-index: 2; + width: 100%; + max-width: 480px; + padding: 2rem; +} + +.signup-card { + background: rgba(255, 255, 255, 0.08); + backdrop-filter: blur(20px); + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: 24px; + padding: 3rem; + box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3); + animation: slideInUp 0.8s ease-out; +} + +@keyframes slideInUp { + from { + opacity: 0; + transform: translateY(50px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.signup-header { + text-align: center; + margin-bottom: 2.5rem; +} + +.logo { + font-size: 2rem; + font-weight: 800; + color: #ffffff; + margin-bottom: 1rem; +} + +.logo-accent { + background: linear-gradient(45deg, #00d4ff, #7c3aed); + background-clip: text; + -webkit-background-clip: text; + color: transparent; +} + +.signup-title { + font-size: 1.75rem; + font-weight: 700; + color: #ffffff; + margin-bottom: 0.5rem; +} + +.signup-subtitle { + color: #a0a0a0; + font-size: 0.95rem; +} + +.signup-form { + display: flex; + flex-direction: column; + gap: 1.5rem; +} + +.form-row { + display: flex; + gap: 1rem; +} + +.form-group { + display: flex; + flex-direction: column; + gap: 0.5rem; + margin-bottom: 1rem; +} + +.form-group.half-width { + flex: 1; + margin-bottom: 0; +} + +.form-label { + font-weight: 600; + color: #ffffff; + font-size: 0.9rem; +} + +.input-wrapper { + position: relative; +} + +.input-icon { + position: absolute; + left: 1rem; + top: 50%; + transform: translateY(-50%); + color: #888; + font-size: 0.9rem; +} + +.form-input { + width: 100%; + padding: 1rem 1rem 1rem 2.75rem; + background: rgba(255, 255, 255, 0.05); + border: 2px solid rgba(255, 255, 255, 0.1); + border-radius: 12px; + color: #ffffff; + font-size: 1rem; + transition: all 0.3s ease; + backdrop-filter: blur(10px); +} + +.form-input:focus { + outline: none; + border-color: #00d4ff; + box-shadow: 0 0 20px rgba(0, 212, 255, 0.2); + background: rgba(255, 255, 255, 0.08); +} + +.form-input.error { + border-color: #ff4757; + box-shadow: 0 0 20px rgba(255, 71, 87, 0.2); +} + +.form-input::placeholder { + color: #666; +} + +.password-toggle { + position: absolute; + right: 1rem; + top: 50%; + transform: translateY(-50%); + background: none; + border: none; + color: #888; + cursor: pointer; + padding: 0.25rem; + transition: color 0.3s ease; +} + +.password-toggle:hover { + color: #00d4ff; +} + +.password-strength { + margin-top: 0.5rem; +} + +.strength-bar { + width: 100%; + height: 4px; + background-color: rgba(255, 255, 255, 0.1); + border-radius: 2px; + overflow: hidden; + margin-bottom: 0.25rem; +} + +.strength-fill { + height: 100%; + transition: width 0.3s ease, background-color 0.3s ease; +} + +.strength-fill.weak { + background: linear-gradient(45deg, #ff4757, #ff6b7a); +} + +.strength-fill.fair { + background: linear-gradient(45deg, #ffa502, #ffb347); +} + +.strength-fill.good { + background: linear-gradient(45deg, #2ed573, #7bed9f); +} + +.strength-fill.strong { + background: linear-gradient(45deg, #00d4ff, #7c3aed); +} + +.strength-text { + font-size: 0.75rem; + font-weight: 500; +} + +.strength-text.weak { + color: #ff4757; +} + +.strength-text.fair { + color: #ffa502; +} + +.strength-text.good { + color: #2ed573; +} + +.strength-text.strong { + background: linear-gradient(45deg, #00d4ff, #7c3aed); + background-clip: text; + -webkit-background-clip: text; + color: transparent; +} + +.password-mismatch { + display: flex; + align-items: center; + gap: 0.5rem; + margin-top: 0.5rem; + font-size: 0.75rem; + color: #ff4757; + animation: shake 0.5s ease-in-out; +} + +.form-options { + display: flex; + flex-direction: column; + gap: 1rem; + margin-bottom: 0.5rem; +} + +.checkbox-wrapper { + display: flex; + align-items: flex-start; + cursor: pointer; + gap: 0.75rem; +} + +.checkbox-input { + display: none; +} + +.checkbox-custom { + width: 18px; + height: 18px; + border: 2px solid rgba(255, 255, 255, 0.3); + border-radius: 4px; + display: flex; + align-items: center; + justify-content: center; + transition: all 0.3s ease; + flex-shrink: 0; + margin-top: 1px; +} + +.checkbox-input:checked + .checkbox-custom { + background: linear-gradient(45deg, #00d4ff, #7c3aed); + border-color: transparent; +} + +.checkbox-input:checked + .checkbox-custom::after { + content: '✓'; + color: white; + font-size: 12px; + font-weight: bold; +} + +.checkbox-label { + color: #a0a0a0; + font-size: 0.9rem; + line-height: 1.4; +} + +.link { + color: #00d4ff; + text-decoration: none; + transition: color 0.3s ease; +} + +.link:hover { + color: #7c3aed; + text-decoration: underline; +} + +.signup-button { + width: 100%; + padding: 1rem; + background: linear-gradient(45deg, #00d4ff, #7c3aed); + color: white; + border: none; + border-radius: 12px; + font-weight: 600; + font-size: 1.1rem; + cursor: pointer; + transition: all 0.3s ease; + margin-top: 0.5rem; +} + +.signup-button:hover:not(:disabled) { + transform: translateY(-2px); + box-shadow: 0 15px 40px rgba(0, 212, 255, 0.4); +} + +.signup-button:disabled { + opacity: 0.5; + cursor: not-allowed; + transform: none; + background: rgba(255, 255, 255, 0.1); +} + +.loading-text { + display: flex; + align-items: center; + justify-content: center; + gap: 0.5rem; +} + +.divider { + position: relative; + text-align: center; + margin: 1.5rem 0; + color: #666; +} + +.divider::before { + content: ''; + position: absolute; + top: 50%; + left: 0; + right: 0; + height: 1px; + background: rgba(255, 255, 255, 0.1); +} + +.divider span { + background: rgba(255, 255, 255, 0.08); + padding: 0 1rem; + position: relative; + z-index: 1; +} + +.social-signup { + width: 100%; + padding: 0.875rem; + background: rgba(255, 255, 255, 0.05); + border: 2px solid rgba(255, 255, 255, 0.1); + border-radius: 12px; + color: #ffffff; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + display: flex; + align-items: center; + justify-content: center; + gap: 0.75rem; + margin-bottom: 0.75rem; + backdrop-filter: blur(10px); +} + +.social-signup:hover { + background: rgba(255, 255, 255, 0.08); + border-color: rgba(255, 255, 255, 0.2); +} + +.social-signup.google:hover { + border-color: rgba(219, 68, 55, 0.5); + box-shadow: 0 0 20px rgba(219, 68, 55, 0.1); +} + +.social-signup.github:hover { + border-color: rgba(255, 255, 255, 0.5); + box-shadow: 0 0 20px rgba(255, 255, 255, 0.1); +} + +.error-message { + background: rgba(255, 71, 87, 0.1); + border: 1px solid rgba(255, 71, 87, 0.3); + border-radius: 12px; + padding: 1rem; + color: #ff4757; + font-size: 0.9rem; + display: flex; + align-items: center; + gap: 0.5rem; + margin-top: 1rem; + animation: shake 0.5s ease-in-out; +} + +.success-message { + background: rgba(46, 213, 115, 0.1); + border: 1px solid rgba(46, 213, 115, 0.3); + border-radius: 12px; + padding: 1rem; + color: #2ed573; + font-size: 0.9rem; + display: flex; + align-items: center; + gap: 0.5rem; + margin-top: 1rem; + animation: slideInUp 0.5s ease-out; +} + +@keyframes shake { + 0%, 100% { transform: translateX(0); } + 25% { transform: translateX(-5px); } + 75% { transform: translateX(5px); } +} + +.login-prompt { + text-align: center; + margin-top: 2rem; + padding-top: 2rem; + border-top: 1px solid rgba(255, 255, 255, 0.1); +} + +.login-prompt p { + color: #a0a0a0; +} + +.login-link { + color: #00d4ff; + text-decoration: none; + font-weight: 600; + transition: color 0.3s ease; +} + +.login-link:hover { + color: #7c3aed; +} + +/* Responsive */ +@media (max-width: 640px) { + .signup-container { + padding: 1rem; + max-width: 100%; + } + + .signup-card { + padding: 2rem; + } + + .form-row { + flex-direction: column; + gap: 0; + } + + .form-group.half-width { + margin-bottom: 1rem; + } + + .checkbox-wrapper { + align-items: flex-start; + } + + .checkbox-label { + font-size: 0.85rem; + } +} + +@media (max-width: 480px) { + .signup-card { + padding: 1.5rem; + } + + .signup-title { + font-size: 1.5rem; + } + + .logo { + font-size: 1.75rem; + } +} \ No newline at end of file diff --git a/src/components/Home.vue b/src/components/Home.vue index 9d90b71..9ad41b5 100644 --- a/src/components/Home.vue +++ b/src/components/Home.vue @@ -1,19 +1,24 @@