botserver/web/app/welcome.html

451 lines
No EOL
13 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<welcome>
<script>
export default {
// Component state
data() {
return {
email: '',
password: '',
isLoading: false,
error: '',
};
},
// Configuration (ZITADEL)
onBeforeMount() {
// this.zitadelConfig = {
// authority: 'https://your-zitadel-instance.com',
// clientId: 'your-client-id',
// redirectUri: typeof window !== 'undefined' ? window.location.origin : '',
// scopes: ['openid', 'profile', 'email'],
// };
},
// Methods
methods: {
handleSocialLogin(provider) {
this.isLoading = true;
this.error = '';
try {
const authUrl = `${this.zitadelConfig.authority}/oauth/v2/authorize?` +
`client_id=${this.zitadelConfig.clientId}&` +
`redirect_uri=${encodeURIComponent(this.zitadelConfig.redirectUri)}&` +
`response_type=code&` +
`scope=${encodeURIComponent(this.zitadelConfig.scopes.join(' '))}&` +
`provider=${provider}`;
window.location.href = authUrl;
} catch (err) {
this.error = 'Failed to initiate login';
console.error('Login error:', err);
} finally {
this.isLoading = false;
}
},
handleEmailLogin(e) {
e.preventDefault();
this.isLoading = true;
this.error = '';
try {
// Mock implementation store dummy token
localStorage.setItem('authToken', 'dummy-token');
// Navigate to dashboard (adjust path as needed)
window.location.href = '/dashboard';
} catch (err) {
this.error = 'Login failed. Please check your credentials.';
console.error('Login error:', err);
} finally {
this.isLoading = false;
}
}
}
};
</script>
<div class="auth-screen">
<div class="auth-content">
<div class="auth-left-panel">
<div class="auth-logo">
<h1>Welcome to General Bots Online</h1>
</div>
<div class="auth-quote">
<p>"Errar é Humano."</p>
<p>General Bots</p>
</div>
</div>
<div class="auth-form-container">
<div class="auth-form-header">
<h2>Sign in to your account</h2>
<p>Choose your preferred login method</p>
</div>
<div class="auth-error" if={error}>{error}</div>
<div class="auth-social-buttons">
<button class="auth-social-button google" @click={()=> handleSocialLogin('google')}
disabled={isLoading}>
<svg class="auth-social-icon" viewBox="0 0 24 24">
<path
d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"
fill="#4285F4" />
<path
d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"
fill="#34A853" />
<path
d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"
fill="#FBBC05" />
<path
d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"
fill="#EA4335" />
</svg>
Continue with Google
</button>
<button class="auth-social-button microsoft" @click={()=> handleSocialLogin('microsoft')}
disabled={isLoading}>
<svg class="auth-social-icon" viewBox="0 0 23 23">
<path d="M0 0h11v11H0zM12 0h11v11H12zM0 12h11v11H0zM12 12h11v11H12z" fill="#F25022" />
<path d="M12 0h11v11H12z" fill="#7FBA00" />
<path d="M0 12h11v11H0z" fill="#00A4EF" />
<path d="M12 12h11v11H12z" fill="#FFB900" />
</svg>
Continue with Microsoft
</button>
<button class="auth-social-button facebook" @click={()=> handleSocialLogin('facebook')}
disabled={isLoading}>
<svg class="auth-social-icon" viewBox="0 0 24 24">
<path
d="M22 12c0-5.52-4.48-10-10-10S2 6.48 2 12c0 4.84 3.44 8.87 8 9.8V15H8v-3h2V9.5C10 7.57 11.57 6 13.5 6H16v3h-2c-.55 0-1 .45-1 1v2h3v3h-3v6.95c5.05-.5 9-4.76 9-9.95z"
fill="#1877F2" />
</svg>
Continue with Facebook
</button>
<button class="auth-social-button pragmatismo" @click={()=> handleSocialLogin('pragmatismo')}
disabled={isLoading}>
<svg class="auth-social-icon" viewBox="0 0 24 24">
<path
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1-13h2v6h-2zm0 8h2v2h-2z"
fill="currentColor" />
</svg>
Continue with Pragmatismo
</button>
</div>
<div class="auth-divider">
<span>OR</span>
</div>
<form class="auth-form" @submit={handleEmailLogin}>
<div class="auth-form-group">
<label for="email">Email</label>
<input id="email" type="email" value={email} oninput={e=> this.email = e.target.value}
placeholder="your@email.com" required />
</div>
<div class="auth-form-group">
<label for="password">Password</label>
<input id="password" type="password" value={password} oninput={e=> this.password = e.target.value}
placeholder="••••••••" required />
</div>
<div class="auth-form-options">
<div class="auth-remember-me">
<input type="checkbox" id="remember" />
<label for="remember">Remember me</label>
</div>
<a href="#" class="auth-forgot-password">Forgot password?</a>
</div>
<button type="submit" class="auth-submit-button" disabled={isLoading}>
{isLoading ? 'Signing in...' : 'Sign in with Email'}
</button>
</form>
<div class="auth-signup-link">
Don't have an account? <a href="#">Sign up</a>
</div>
<p class="auth-terms">
By continuing, you agree to our <a href="#">Terms of Service</a> and <a href="#">Privacy Policy</a>.
</p>
</div>
</div>
<style>
.auth-screen {
--background: hsl(var(--background));
--foreground: hsl(var(--foreground));
--card: hsl(var(--card));
--card-foreground: hsl(var(--card-foreground));
--primary: hsl(var(--primary));
--primary-foreground: hsl(var(--primary-foreground));
--secondary: hsl(var(--secondary));
--secondary-foreground: hsl(var(--secondary-foreground));
--muted: hsl(var(--muted));
--muted-foreground: hsl(var(--muted-foreground));
--accent: hsl(var(--accent));
--accent-foreground: hsl(var(--accent-foreground));
--destructive: hsl(var(--destructive));
--destructive-foreground: hsl(var(--destructive-foreground));
--border: hsl(var(--border));
--input: hsl(var(--input));
--ring: hsl(var(--ring));
--radius: var(--radius);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background-color: var(--background);
color: var(--foreground);
padding: 1rem;
}
.auth-content {
display: flex;
width: 100%;
max-width: 1200px;
background-color: var(--card);
border-radius: var(--radius);
overflow: hidden;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
}
.auth-left-panel {
flex: 1;
padding: 4rem;
background: linear-gradient(135deg, var(--primary), var(--accent));
color: var(--primary-foreground);
display: flex;
flex-direction: column;
justify-content: space-between;
}
.auth-logo h1 {
font-size: 2rem;
margin-bottom: 1rem;
}
.auth-quote {
font-style: italic;
margin-top: auto;
}
.auth-quote p:last-child {
text-align: right;
margin-top: 0.5rem;
}
.auth-form-container {
flex: 1;
padding: 4rem;
max-width: 500px;
}
.auth-form-header {
margin-bottom: 2rem;
text-align: center;
}
.auth-form-header h2 {
font-size: 1.5rem;
margin-bottom: 0.5rem;
}
.auth-form-header p {
color: var(--muted-foreground);
}
.auth-error {
background-color: var(--destructive);
color: var(--destructive-foreground);
padding: 0.75rem;
border-radius: var(--radius);
margin-bottom: 1rem;
text-align: center;
}
.auth-social-buttons {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 0.75rem;
margin-bottom: 1.5rem;
}
.auth-social-button {
display: flex;
align-items: center;
justify-content: center;
padding: 0.75rem;
border-radius: var(--radius);
font-weight: 500;
cursor: pointer;
transition: all 0.2s;
border: 1px solid var(--border);
background-color: var(--secondary);
color: var(--secondary-foreground);
}
.auth-social-button:hover {
background-color: var(--muted);
}
.auth-social-button:disabled {
opacity: 0.7;
cursor: not-allowed;
}
.auth-social-icon {
width: 1.25rem;
height: 1.25rem;
margin-right: 0.5rem;
}
.auth-divider {
display: flex;
align-items: center;
margin: 1.5rem 0;
color: var(--muted-foreground);
}
.auth-divider::before,
.auth-divider::after {
content: "";
flex: 1;
border-bottom: 1px solid var(--border);
}
.auth-divider span {
padding: 0 1rem;
}
.auth-form {
margin-top: 1.5rem;
}
.auth-form-group {
margin-bottom: 1rem;
}
.auth-form-group label {
display: block;
margin-bottom: 0.5rem;
font-weight: 500;
}
.auth-form-group input {
width: 100%;
padding: 0.75rem;
border-radius: var(--radius);
border: 1px solid var(--border);
background-color: var(--input);
color: var(--foreground);
}
.auth-form-group input:focus {
outline: none;
border-color: var(--ring);
box-shadow: 0 0 0 2px var(--ring);
}
.auth-form-options {
display: flex;
justify-content: space-between;
align-items: center;
margin: 1rem 0;
}
.auth-remember-me {
display: flex;
align-items: center;
}
.auth-remember-me input {
margin-right: 0.5rem;
}
.auth-forgot-password {
color: var(--primary);
text-decoration: none;
}
.auth-forgot-password:hover {
text-decoration: underline;
}
.auth-submit-button {
width: 100%;
padding: 0.75rem;
border-radius: var(--radius);
background-color: var(--primary);
color: var(--primary-foreground);
font-weight: 500;
border: none;
cursor: pointer;
transition: all 0.2s;
}
.auth-submit-button:hover {
background-color: color-mix(in srgb, var(--primary), black 10%);
}
.auth-submit-button:disabled {
opacity: 0.7;
cursor: not-allowed;
}
.auth-signup-link {
text-align: center;
margin: 1.5rem 0;
color: var(--muted-foreground);
}
.auth-signup-link a {
color: var(--primary);
text-decoration: none;
}
.auth-signup-link a:hover {
text-decoration: underline;
}
.auth-terms {
text-align: center;
font-size: 0.875rem;
color: var(--muted-foreground);
}
.auth-terms a {
color: var(--primary);
text-decoration: none;
}
.auth-terms a:hover {
text-decoration: underline;
}
@media (max-width: 768px) {
.auth-content {
flex-direction: column;
}
.auth-left-panel {
padding: 2rem;
}
.auth-form-container {
padding: 2rem;
max-width: 100%;
}
.auth-social-buttons {
grid-template-columns: 1fr;
}
}
</style>
</div>
</welcome>