feat(forms): add inline blur validation for name and email
This commit is contained in:
parent
1079e8212f
commit
10f8cab6e3
3 changed files with 66 additions and 0 deletions
|
|
@ -32,7 +32,10 @@
|
|||
class="form-input"
|
||||
type="text"
|
||||
required
|
||||
@blur="validateName"
|
||||
@input="if (fieldErrors.name) fieldErrors.name = ''"
|
||||
>
|
||||
<p v-if="fieldErrors.name" class="field-error">{{ fieldErrors.name }}</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="accept-email">Email</label>
|
||||
|
|
@ -201,6 +204,13 @@ const form = reactive({
|
|||
agreedToGuidelines: false,
|
||||
});
|
||||
|
||||
// Inline blur validation (UI feedback only — does not block submission)
|
||||
const fieldErrors = reactive({ name: "" });
|
||||
|
||||
const validateName = () => {
|
||||
fieldErrors.name = form.name.trim() ? "" : "Please enter your name.";
|
||||
};
|
||||
|
||||
const isFormValid = computed(() => {
|
||||
return (
|
||||
form.name &&
|
||||
|
|
@ -447,6 +457,12 @@ textarea.form-input {
|
|||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.field-error {
|
||||
font-size: 11px;
|
||||
color: var(--ember);
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
/* ---- CIRCLE RADIOS ---- */
|
||||
.circle-radios {
|
||||
display: grid;
|
||||
|
|
|
|||
|
|
@ -128,7 +128,10 @@
|
|||
class="form-input"
|
||||
type="text"
|
||||
required
|
||||
@blur="validateName"
|
||||
@input="if (fieldErrors.name) fieldErrors.name = ''"
|
||||
>
|
||||
<p v-if="fieldErrors.name" class="field-error">{{ fieldErrors.name }}</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="join-email">Email</label>
|
||||
|
|
@ -139,7 +142,10 @@
|
|||
type="email"
|
||||
placeholder="you@example.com"
|
||||
required
|
||||
@blur="validateEmail"
|
||||
@input="if (fieldErrors.email) fieldErrors.email = ''"
|
||||
>
|
||||
<p v-if="fieldErrors.email" class="field-error">{{ fieldErrors.email }}</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Circle</label>
|
||||
|
|
@ -346,6 +352,23 @@ const errorMessage = ref("");
|
|||
const successMessage = ref("");
|
||||
const cadence = ref("monthly"); // 'monthly' | 'annual'
|
||||
|
||||
// Inline blur validation (UI feedback only — does not block submission)
|
||||
const fieldErrors = reactive({ name: "", email: "" });
|
||||
|
||||
const validateName = () => {
|
||||
fieldErrors.name = form.name.trim() ? "" : "Please enter your name.";
|
||||
};
|
||||
|
||||
const validateEmail = () => {
|
||||
const value = form.email.trim();
|
||||
if (!value) {
|
||||
fieldErrors.email = "";
|
||||
return;
|
||||
}
|
||||
const ok = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
|
||||
fieldErrors.email = ok ? "" : "Please enter a valid email address.";
|
||||
};
|
||||
|
||||
// Flow overlay state — drives the post-submit full-viewport UI.
|
||||
// 'idle' = overlay hidden; user is editing the form.
|
||||
// 'creating-customer' | 'opening-payment' | 'processing-payment'
|
||||
|
|
@ -762,6 +785,11 @@ onUnmounted(() => {
|
|||
.form-input::placeholder {
|
||||
color: var(--text-faint);
|
||||
}
|
||||
.field-error {
|
||||
font-size: 11px;
|
||||
color: var(--ember);
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
/* ---- CIRCLE RADIOS ---- */
|
||||
.circle-radios {
|
||||
|
|
|
|||
|
|
@ -173,9 +173,12 @@
|
|||
type="email"
|
||||
placeholder="you@example.com"
|
||||
autofocus
|
||||
@blur="validateNewEmail"
|
||||
@input="if (fieldErrors.email) fieldErrors.email = ''"
|
||||
@keydown.enter="handleUpdateEmail"
|
||||
@keydown.escape="cancelEmailEdit"
|
||||
>
|
||||
<p v-if="fieldErrors.email" class="field-error">{{ fieldErrors.email }}</p>
|
||||
</div>
|
||||
<div class="email-edit-actions">
|
||||
<button
|
||||
|
|
@ -317,6 +320,19 @@ const showEmailEdit = ref(false);
|
|||
const newEmail = ref("");
|
||||
const isUpdatingEmail = ref(false);
|
||||
|
||||
// Inline blur validation (UI feedback only — does not block submission)
|
||||
const fieldErrors = reactive({ email: "" });
|
||||
|
||||
const validateNewEmail = () => {
|
||||
const value = newEmail.value.trim();
|
||||
if (!value) {
|
||||
fieldErrors.email = "";
|
||||
return;
|
||||
}
|
||||
const ok = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
|
||||
fieldErrors.email = ok ? "" : "Please enter a valid email address.";
|
||||
};
|
||||
|
||||
// Payment history state
|
||||
const paymentHistory = ref([]);
|
||||
const paymentHistoryLoading = ref(false);
|
||||
|
|
@ -516,6 +532,7 @@ const handleUpdateCircle = async () => {
|
|||
const cancelEmailEdit = () => {
|
||||
showEmailEdit.value = false;
|
||||
newEmail.value = "";
|
||||
fieldErrors.email = "";
|
||||
};
|
||||
|
||||
const handleUpdateEmail = async () => {
|
||||
|
|
@ -823,6 +840,11 @@ const confirmCancelMembership = async () => {
|
|||
.email-edit .field input:focus {
|
||||
border-color: var(--candle);
|
||||
}
|
||||
.email-edit .field .field-error {
|
||||
font-size: 11px;
|
||||
color: var(--ember);
|
||||
margin-top: 4px;
|
||||
}
|
||||
.email-edit-actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue