Create a Beag API Login page for this SaaS application:
**My Beag App ID:** [YOUR_APP_ID]
**Redirect URL after login:** [YOUR_APP_URL]
1. Create a login page in the appropriate location based on the framework:
- Static HTML: login.html
- React (Vite/CRA): src/pages/Login.jsx or src/Login.jsx
- Next.js (pages): pages/login.tsx
- Next.js (app router): app/login/page.tsx
- Vue: src/views/Login.vue or src/pages/Login.vue
- Nuxt: pages/login.vue
- SvelteKit: src/routes/login/+page.svelte
- Angular: generate login component
- Template engines: login.ejs, login.hbs, etc.
2. The login page needs:
- Email form with: email input, error display, submit button to send OTP
- OTP form (hidden initially) with: email display, OTP input, error display, submit button to verify
- Clean, professional styling matching the existing app design
3. Implement the login logic using this reference code, adapting it to the framework's patterns (e.g., useState for React, ref for Vue, etc.):
const APP_ID = '[YOUR_APP_ID]';
let userEmail = '';
async function sendOTP() {
const email = document.getElementById('email').value.trim();
const errorEl = document.getElementById('email-error');
if (!email) {
errorEl.textContent = 'Please enter your email';
return;
}
try {
const response = await fetch('<https://my-saas-basic-api-d5e3hpgdf0gnh2em.eastus-01.azurewebsites.net/auth/api/login>', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
my_saas_id: APP_ID,
email: email
})
});
const result = await response.json();
if (result.status === 'success') {
userEmail = email;
document.getElementById('user-email').textContent = email;
document.getElementById('email-form').style.display = 'none';
document.getElementById('otp-form').style.display = 'block';
} else {
errorEl.textContent = result.message;
}
} catch (error) {
console.error('Error:', error);
errorEl.textContent = 'An error occurred. Please try again.';
}
}
async function verifyOTP() {
const otp = document.getElementById('otp').value.trim();
const errorEl = document.getElementById('otp-error');
if (!otp) {
errorEl.textContent = 'Please enter the verification code';
return;
}
try {
const response = await fetch('<https://my-saas-basic-api-d5e3hpgdf0gnh2em.eastus-01.azurewebsites.net/auth/api/verify-otp>', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
my_saas_id: APP_ID,
email: userEmail,
otp: otp
})
});
const result = await response.json();
if (result.status === 'success') {
const { token_data } = result;
Object.keys(token_data).forEach(key => {
localStorage.setItem(key, token_data[key]);
});
window.location.href = '[YOUR_APP_URL]';
} else {
errorEl.textContent = result.message;
}
} catch (error) {
console.error('Error:', error);
errorEl.textContent = 'An error occurred. Please try again.';
}
}
4. Framework-specific adaptations:
- React: Use useState for email, userEmail, error messages, and showOTPForm state
- Vue: Use ref() or reactive() for state management
- Svelte: Use let variables with reactivity
- Next.js/Nuxt: Use client-side rendering for the login logic ('use client' directive if needed)
- Angular: Use component properties and [(ngModel)] for two-way binding
5. Show me the created files.