botserver/web/app/settings/profile-form.html
Rodrigo Rodriguez (Pragmatismo) 02eaac783f feat(editor, settings): refactor state handling and enhance validation
Refactored editor.page.html to use a Vue-style `data()` function for reactive state, adding a new `content` property and cleaning up redundant inline styles. Updated profile-form.html to replace single `error` handling with field-specific `errors.<field>` bindings, improving form validation clarity and user feedback.
2025-11-15 21:52:53 -03:00

109 lines
3.3 KiB
HTML

<!-- Riot.js component for the profile form (converted from app/settings/profile-form.tsx) -->
<template>
<div class="space-y-4">
<controller name="username">
<div class="mb-4">
<label class="block text-sm font-medium mb-1">Username</label>
<input class="w-full p-2 border rounded {errors.username ? 'border-red-500' : 'border-gray-300'}"
bind="{username}"
placeholder="Enter username" />
{errors.username && <p class="text-red-500 text-xs mt-1">{errors.username.message}</p>}
<p class="text-sm text-gray-500 mt-1">
This is your public display name. It can be your real name or a pseudonym. You can only change this once every 30 days.
</p>
</div>
</controller>
<controller name="email">
<div class="mb-4">
<label class="block text-sm font-medium mb-1">Email</label>
<input type="email"
class="w-full p-2 border rounded {errors.email ? 'border-red-500' : 'border-gray-300'}"
bind="{email}"
placeholder="Enter email" />
{errors.email && <p class="text-red-500 text-xs mt-1">{errors.email.message}</p>}
<p class="text-sm text-gray-500 mt-1">
You can manage verified email addresses in your email settings.
</p>
</div>
</controller>
<controller name="bio">
<div class="mb-4">
<label class="block text-sm font-medium mb-1">Bio</label>
<textarea class="w-full p-2 border rounded {errors.bio ? 'border-red-500' : 'border-gray-300'}"
bind="{bio}"
rows="4"
placeholder="Tell us a little bit about yourself"></textarea>
{errors.bio && <p class="text-red-500 text-xs mt-1">{errors.bio.message}</p>}
<p class="text-sm text-gray-500 mt-1">
You can @mention other users and organizations to link to them.
</p>
</div>
</controller>
<button class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600"
@click="{handleSubmit(onSubmit)}">
Update profile
</button>
</div>
</template>
<script >
import { useState } from 'riot';
import { useForm, Controller } from 'react-hook-form';
import { z } from 'zod';
import { zodResolver } from '@hookform/resolvers/zod';
import './style.css';
export default {
// Reactive state
data() {
return {
username: '',
email: '',
bio: '',
errors: {
username: null,
email: null,
bio: null
}
}
},
// Validation schema
schema: z.object({
username: z.string().min(2, { message: "Username must be at least 2 characters." }).max(30, { message: "Username must not be longer than 30 characters." }),
email: z.string().email(),
bio: z.string().min(4).max(160)
}),
// Methods
handleSubmit(callback) {
const result = this.schema.safeParse({
username: this.username,
email: this.email,
bio: this.bio
});
// Clear previous errors
this.errors = {
username: null,
email: null,
bio: null
};
if (result.success) {
callback(result.data);
} else {
result.error.errors.forEach(err => {
this.errors[err.path[0]] = err;
});
}
},
onSubmit(data) {
console.log(JSON.stringify(data, null, 2));
}
};
</script>