Simplify Login, remove registration for now
Adds a login page with username and password fields. Includes input validation, loading state, error handling, and a success message after successful login. Registration has been temporarily disabled.
This commit is contained in:
parent
6c0dbc655b
commit
5f795cef0e
1 changed files with 14 additions and 115 deletions
|
|
@ -15,7 +15,13 @@
|
||||||
<Card class="border-0 shadow-lg">
|
<Card class="border-0 shadow-lg">
|
||||||
<CardContent class="p-6 sm:p-8">
|
<CardContent class="p-6 sm:p-8">
|
||||||
<!-- Mode Toggle -->
|
<!-- Mode Toggle -->
|
||||||
<div class="flex rounded-lg bg-muted p-1 mb-8">
|
<!-- TODO: Make register tab dynamic based on server config
|
||||||
|
Once LNbits adds a public endpoint like /api/v1/server/config that returns:
|
||||||
|
{ "allow_new_accounts": boolean, "auth_methods": string[] }
|
||||||
|
We can fetch this on mount and conditionally show the Register tab.
|
||||||
|
For now, registration is disabled server-side so we hide the toggle.
|
||||||
|
-->
|
||||||
|
<!-- <div class="flex rounded-lg bg-muted p-1 mb-8">
|
||||||
<button
|
<button
|
||||||
@click="activeMode = 'login'"
|
@click="activeMode = 'login'"
|
||||||
:class="[
|
:class="[
|
||||||
|
|
@ -28,6 +34,7 @@
|
||||||
Sign In
|
Sign In
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
v-if="allowRegistration"
|
||||||
@click="activeMode = 'register'"
|
@click="activeMode = 'register'"
|
||||||
:class="[
|
:class="[
|
||||||
'flex-1 rounded-md px-3 py-2 text-sm font-medium transition-all',
|
'flex-1 rounded-md px-3 py-2 text-sm font-medium transition-all',
|
||||||
|
|
@ -38,10 +45,10 @@
|
||||||
>
|
>
|
||||||
Register
|
Register
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div> -->
|
||||||
|
|
||||||
<!-- Login Form -->
|
<!-- Login Form -->
|
||||||
<form v-if="activeMode === 'login'" @submit.prevent="handleLogin" class="space-y-4">
|
<form @submit.prevent="handleLogin" class="space-y-4">
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
<Label for="login-username" class="text-sm font-medium">Username</Label>
|
<Label for="login-username" class="text-sm font-medium">Username</Label>
|
||||||
<Input
|
<Input
|
||||||
|
|
@ -84,72 +91,6 @@
|
||||||
</Button>
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<!-- Register Form -->
|
|
||||||
<form v-else @submit.prevent="handleRegister" class="space-y-4">
|
|
||||||
<div class="space-y-2">
|
|
||||||
<Label for="register-username" class="text-sm font-medium">Username</Label>
|
|
||||||
<Input
|
|
||||||
id="register-username"
|
|
||||||
v-model="registerForm.username"
|
|
||||||
placeholder="Choose a username"
|
|
||||||
:disabled="isLoading"
|
|
||||||
class="h-11"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="space-y-2">
|
|
||||||
<Label for="register-email" class="text-sm font-medium">Email <span class="text-muted-foreground">(optional)</span></Label>
|
|
||||||
<Input
|
|
||||||
id="register-email"
|
|
||||||
type="email"
|
|
||||||
v-model="registerForm.email"
|
|
||||||
placeholder="your@email.com"
|
|
||||||
:disabled="isLoading"
|
|
||||||
class="h-11"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="space-y-2">
|
|
||||||
<Label for="register-password" class="text-sm font-medium">Password</Label>
|
|
||||||
<Input
|
|
||||||
id="register-password"
|
|
||||||
type="password"
|
|
||||||
v-model="registerForm.password"
|
|
||||||
placeholder="Minimum 6 characters"
|
|
||||||
:disabled="isLoading"
|
|
||||||
class="h-11"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="space-y-2">
|
|
||||||
<Label for="register-password-repeat" class="text-sm font-medium">Confirm Password</Label>
|
|
||||||
<Input
|
|
||||||
id="register-password-repeat"
|
|
||||||
type="password"
|
|
||||||
v-model="registerForm.password_repeat"
|
|
||||||
placeholder="Re-enter your password"
|
|
||||||
:disabled="isLoading"
|
|
||||||
class="h-11"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Error Display -->
|
|
||||||
<p v-if="error" class="text-sm text-destructive">
|
|
||||||
{{ error }}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
type="submit"
|
|
||||||
:disabled="isLoading || !canRegister"
|
|
||||||
class="w-full h-11 text-base font-medium"
|
|
||||||
>
|
|
||||||
<span v-if="isLoading" class="mr-2">
|
|
||||||
<svg class="animate-spin h-4 w-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
|
||||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
|
||||||
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
|
||||||
</svg>
|
|
||||||
</span>
|
|
||||||
{{ isLoading ? 'Creating Account...' : 'Create Account' }}
|
|
||||||
</Button>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<!-- Success Message -->
|
<!-- Success Message -->
|
||||||
<div
|
<div
|
||||||
v-if="successMessage"
|
v-if="successMessage"
|
||||||
|
|
@ -182,7 +123,10 @@ const router = useRouter()
|
||||||
const isLoading = ref(false)
|
const isLoading = ref(false)
|
||||||
const error = ref('')
|
const error = ref('')
|
||||||
const successMessage = ref('')
|
const successMessage = ref('')
|
||||||
const activeMode = ref<'login' | 'register'>('login')
|
|
||||||
|
// TODO: Fetch from server config endpoint when available
|
||||||
|
// const allowRegistration = ref(false)
|
||||||
|
// const activeMode = ref<'login' | 'register'>('login')
|
||||||
|
|
||||||
// Login form
|
// Login form
|
||||||
const loginForm = ref({
|
const loginForm = ref({
|
||||||
|
|
@ -190,23 +134,10 @@ const loginForm = ref({
|
||||||
password: ''
|
password: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
// Register form
|
|
||||||
const registerForm = ref({
|
|
||||||
username: '',
|
|
||||||
email: '',
|
|
||||||
password: '',
|
|
||||||
password_repeat: ''
|
|
||||||
})
|
|
||||||
|
|
||||||
const canLogin = computed(() => {
|
const canLogin = computed(() => {
|
||||||
return loginForm.value.username.trim() && loginForm.value.password.trim()
|
return loginForm.value.username.trim() && loginForm.value.password.trim()
|
||||||
})
|
})
|
||||||
|
|
||||||
const canRegister = computed(() => {
|
|
||||||
const { username, password, password_repeat } = registerForm.value
|
|
||||||
return username.trim() && password.trim() && password === password_repeat && password.length >= 6
|
|
||||||
})
|
|
||||||
|
|
||||||
// Login with existing credentials
|
// Login with existing credentials
|
||||||
async function handleLogin() {
|
async function handleLogin() {
|
||||||
if (!canLogin.value) return
|
if (!canLogin.value) return
|
||||||
|
|
@ -236,36 +167,4 @@ async function handleLogin() {
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register new account
|
|
||||||
async function handleRegister() {
|
|
||||||
if (!canRegister.value) return
|
|
||||||
|
|
||||||
try {
|
|
||||||
isLoading.value = true
|
|
||||||
error.value = ''
|
|
||||||
successMessage.value = ''
|
|
||||||
|
|
||||||
await auth.register({
|
|
||||||
username: registerForm.value.username,
|
|
||||||
email: registerForm.value.email || undefined,
|
|
||||||
password: registerForm.value.password,
|
|
||||||
password_repeat: registerForm.value.password_repeat
|
|
||||||
})
|
|
||||||
|
|
||||||
successMessage.value = 'Registration successful! Redirecting...'
|
|
||||||
toast.success(`Account created! Welcome ${registerForm.value.username}!`)
|
|
||||||
|
|
||||||
// Redirect to home page after successful registration
|
|
||||||
setTimeout(() => {
|
|
||||||
router.push('/')
|
|
||||||
}, 1500)
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
error.value = err instanceof Error ? err.message : 'Registration failed'
|
|
||||||
toast.error('Registration failed. Please try again.')
|
|
||||||
} finally {
|
|
||||||
isLoading.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue