419 lines
11 KiB
Vue
419 lines
11 KiB
Vue
<template>
|
|
<div class="login-page">
|
|
<div class="login-container">
|
|
<!-- Left Side - Branding -->
|
|
<div class="login-branding">
|
|
<div class="branding-content">
|
|
<div class="logo-container">
|
|
<img src="/MONACOUSA-Flags_376x376.png" alt="MonacoUSA" class="logo" />
|
|
</div>
|
|
<h1 class="brand-title">MonacoUSA Portal</h1>
|
|
<p class="brand-tagline">Excellence in Partnership</p>
|
|
|
|
<div class="feature-list">
|
|
<div class="feature-item" v-for="feature in features" :key="feature">
|
|
<svg class="feature-icon" fill="currentColor" viewBox="0 0 20 20">
|
|
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd" />
|
|
</svg>
|
|
<span>{{ feature }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Background pattern -->
|
|
<div class="branding-pattern"></div>
|
|
</div>
|
|
|
|
<!-- Right Side - Login Form -->
|
|
<div class="login-form-section">
|
|
<NeumorphicCard size="lg" elevation="lg" class="login-card">
|
|
<template #header>
|
|
<h2 class="login-title">Welcome Back</h2>
|
|
<p class="login-subtitle">Sign in to access your account</p>
|
|
</template>
|
|
|
|
<form @submit.prevent="handleLogin" class="login-form">
|
|
<div class="form-group">
|
|
<label for="email" class="form-label">Email Address</label>
|
|
<div class="input-wrapper">
|
|
<input
|
|
id="email"
|
|
v-model="credentials.email"
|
|
type="email"
|
|
class="form-input"
|
|
placeholder="you@example.com"
|
|
required
|
|
/>
|
|
<span class="input-icon">
|
|
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
|
|
</svg>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="password" class="form-label">Password</label>
|
|
<div class="input-wrapper">
|
|
<input
|
|
id="password"
|
|
v-model="credentials.password"
|
|
:type="showPassword ? 'text' : 'password'"
|
|
class="form-input"
|
|
placeholder="Enter your password"
|
|
required
|
|
/>
|
|
<button
|
|
type="button"
|
|
@click="showPassword = !showPassword"
|
|
class="input-icon clickable"
|
|
>
|
|
<svg v-if="!showPassword" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
|
|
</svg>
|
|
<svg v-else fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21" />
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-options">
|
|
<label class="checkbox-label">
|
|
<input v-model="credentials.rememberMe" type="checkbox" class="checkbox-input" />
|
|
<span>Remember me</span>
|
|
</label>
|
|
|
|
<button type="button" class="forgot-password-link" @click="showForgotPassword = true">
|
|
Forgot password?
|
|
</button>
|
|
</div>
|
|
|
|
<ProfessionalButton
|
|
type="submit"
|
|
variant="primary"
|
|
size="lg"
|
|
block
|
|
:loading="loading"
|
|
class="login-button"
|
|
>
|
|
Sign In
|
|
</ProfessionalButton>
|
|
</form>
|
|
|
|
<template #footer>
|
|
<div class="login-footer">
|
|
<p class="signup-prompt">
|
|
Don't have an account?
|
|
<a href="/signup" class="signup-link">Create Account</a>
|
|
</p>
|
|
</div>
|
|
</template>
|
|
</NeumorphicCard>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref } from 'vue';
|
|
import NeumorphicCard from '../../components/core/NeumorphicCard.vue';
|
|
import ProfessionalButton from '../../components/core/ProfessionalButton.vue';
|
|
|
|
// Data
|
|
const credentials = ref({
|
|
email: '',
|
|
password: '',
|
|
rememberMe: false
|
|
});
|
|
|
|
const showPassword = ref(false);
|
|
const loading = ref(false);
|
|
const showForgotPassword = ref(false);
|
|
|
|
const features = [
|
|
'Secure Member Access',
|
|
'Event Management',
|
|
'Document Library',
|
|
'Payment Processing'
|
|
];
|
|
|
|
// Methods
|
|
const handleLogin = async () => {
|
|
loading.value = true;
|
|
// Simulate API call
|
|
setTimeout(() => {
|
|
loading.value = false;
|
|
console.log('Login with:', credentials.value);
|
|
}, 2000);
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
@import '../../styles/neumorphic-system.scss';
|
|
|
|
.login-page {
|
|
min-height: 100vh;
|
|
background: linear-gradient(135deg, $neutral-50 0%, $neutral-100 100%);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.login-container {
|
|
width: 100%;
|
|
max-width: 1400px;
|
|
margin: 0 auto;
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
min-height: 100vh;
|
|
|
|
@media (max-width: $breakpoint-md) {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
}
|
|
|
|
// Left side - Branding
|
|
.login-branding {
|
|
position: relative;
|
|
background: linear-gradient(135deg, $primary-600, $primary-800);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: $space-12;
|
|
overflow: hidden;
|
|
|
|
@media (max-width: $breakpoint-md) {
|
|
display: none;
|
|
}
|
|
|
|
.branding-content {
|
|
position: relative;
|
|
z-index: 2;
|
|
text-align: center;
|
|
color: white;
|
|
}
|
|
|
|
.logo-container {
|
|
width: 120px;
|
|
height: 120px;
|
|
margin: 0 auto $space-6;
|
|
background: white;
|
|
border-radius: $radius-2xl;
|
|
padding: $space-4;
|
|
box-shadow: $shadow-soft-lg;
|
|
|
|
.logo {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: contain;
|
|
}
|
|
}
|
|
|
|
.brand-title {
|
|
font-family: $font-heading;
|
|
font-size: $text-3xl;
|
|
font-weight: $font-bold;
|
|
margin-bottom: $space-2;
|
|
letter-spacing: -0.025em;
|
|
}
|
|
|
|
.brand-tagline {
|
|
font-size: $text-lg;
|
|
opacity: 0.9;
|
|
margin-bottom: $space-12;
|
|
}
|
|
|
|
.feature-list {
|
|
text-align: left;
|
|
max-width: 300px;
|
|
margin: 0 auto;
|
|
}
|
|
|
|
.feature-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: $space-3;
|
|
margin-bottom: $space-4;
|
|
font-size: $text-base;
|
|
|
|
.feature-icon {
|
|
width: 20px;
|
|
height: 20px;
|
|
flex-shrink: 0;
|
|
color: rgba(white, 0.9);
|
|
}
|
|
}
|
|
|
|
.branding-pattern {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background-image: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23ffffff' fill-opacity='0.05'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
|
|
opacity: 0.5;
|
|
}
|
|
}
|
|
|
|
// Right side - Login form
|
|
.login-form-section {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: $space-8;
|
|
|
|
.login-card {
|
|
width: 100%;
|
|
max-width: 480px;
|
|
}
|
|
|
|
.login-title {
|
|
font-family: $font-heading;
|
|
font-size: $text-2xl;
|
|
font-weight: $font-bold;
|
|
color: $neutral-800;
|
|
margin-bottom: $space-2;
|
|
}
|
|
|
|
.login-subtitle {
|
|
font-size: $text-base;
|
|
color: $neutral-600;
|
|
}
|
|
|
|
.login-form {
|
|
.form-group {
|
|
margin-bottom: $space-5;
|
|
}
|
|
|
|
.form-label {
|
|
display: block;
|
|
font-size: $text-sm;
|
|
font-weight: $font-medium;
|
|
color: $neutral-700;
|
|
margin-bottom: $space-2;
|
|
}
|
|
|
|
.input-wrapper {
|
|
position: relative;
|
|
}
|
|
|
|
.form-input {
|
|
width: 100%;
|
|
padding: $space-3 $space-4;
|
|
padding-right: $space-12;
|
|
background: $neutral-50;
|
|
border: none;
|
|
border-radius: $radius-lg;
|
|
box-shadow: $shadow-inset-sm;
|
|
font-size: $text-base;
|
|
color: $neutral-800;
|
|
transition: all $transition-base;
|
|
|
|
&::placeholder {
|
|
color: $neutral-400;
|
|
}
|
|
|
|
&:focus {
|
|
outline: none;
|
|
box-shadow: $shadow-inset-md, 0 0 0 3px rgba($primary-500, 0.1);
|
|
}
|
|
}
|
|
|
|
.input-icon {
|
|
position: absolute;
|
|
right: $space-3;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
width: 20px;
|
|
height: 20px;
|
|
color: $neutral-400;
|
|
|
|
&.clickable {
|
|
cursor: pointer;
|
|
background: none;
|
|
border: none;
|
|
padding: 0;
|
|
transition: color $transition-base;
|
|
|
|
&:hover {
|
|
color: $neutral-600;
|
|
}
|
|
}
|
|
}
|
|
|
|
.form-options {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: $space-6;
|
|
}
|
|
|
|
.checkbox-label {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: $space-2;
|
|
font-size: $text-sm;
|
|
color: $neutral-700;
|
|
cursor: pointer;
|
|
|
|
.checkbox-input {
|
|
width: 18px;
|
|
height: 18px;
|
|
border-radius: $radius-sm;
|
|
cursor: pointer;
|
|
}
|
|
}
|
|
|
|
.forgot-password-link {
|
|
background: none;
|
|
border: none;
|
|
color: $primary-600;
|
|
font-size: $text-sm;
|
|
font-weight: $font-medium;
|
|
cursor: pointer;
|
|
padding: 0;
|
|
transition: color $transition-base;
|
|
|
|
&:hover {
|
|
color: $primary-700;
|
|
text-decoration: underline;
|
|
}
|
|
}
|
|
|
|
.login-button {
|
|
margin-top: $space-4;
|
|
}
|
|
}
|
|
|
|
.login-footer {
|
|
text-align: center;
|
|
|
|
.signup-prompt {
|
|
font-size: $text-sm;
|
|
color: $neutral-600;
|
|
}
|
|
|
|
.signup-link {
|
|
color: $primary-600;
|
|
font-weight: $font-medium;
|
|
text-decoration: none;
|
|
margin-left: $space-1;
|
|
transition: color $transition-base;
|
|
|
|
&:hover {
|
|
color: $primary-700;
|
|
text-decoration: underline;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Dark mode support
|
|
@include dark-mode {
|
|
.login-page {
|
|
background: linear-gradient(135deg, $neutral-900 0%, $neutral-800 100%);
|
|
}
|
|
}
|
|
</style> |