Skip to content

Commit 20d3449

Browse files
committed
brr
1 parent 49ded05 commit 20d3449

6 files changed

Lines changed: 55 additions & 28 deletions

File tree

frontend/src/ts/components/pages/login/Login.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ export function Login(): JSXElement {
7272
};
7373

7474
return (
75-
<div class="grid grid-cols-1 justify-center gap-2">
75+
<div class="grid w-full grid-cols-1 justify-center gap-2 sm:w-80">
7676
<div class="inline-flex items-baseline text-sub">
7777
<i class="fas fa-sign-in-alt mr-[0.5em]"></i>
7878
login
@@ -98,7 +98,6 @@ export function Login(): JSXElement {
9898
<input
9999
name="current-email"
100100
type="email"
101-
class="w-68"
102101
placeholder="email"
103102
// oxlint-disable-next-line react/no-unknown-property
104103
autocomplete="current-email"
@@ -108,7 +107,6 @@ export function Login(): JSXElement {
108107
<input
109108
name="current-password"
110109
type="password"
111-
class="w-68"
112110
placeholder="password"
113111
// oxlint-disable-next-line react/no-unknown-property
114112
autocomplete="current-password"

frontend/src/ts/components/pages/login/LoginPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export function LoginPage(): JSXElement {
3232
</div>
3333
}
3434
else={
35-
<div class="flex h-full items-center justify-around gap-4">
35+
<div class="flex h-full flex-col items-center justify-around gap-4 md:flex-row">
3636
<Register />
3737
<Login />
3838
</div>

frontend/src/ts/components/pages/login/Register.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ export function Register(): JSXElement {
108108
};
109109

110110
return (
111-
<div class="grid grid-cols-1 justify-center gap-2">
111+
<div class="grid w-full grid-cols-1 justify-center gap-2 sm:w-80">
112112
<div class="inline-flex items-baseline text-sub">
113113
<i class="fas fa-user-plus mr-[0.5em]"></i>
114114
register
@@ -122,7 +122,6 @@ export function Register(): JSXElement {
122122
>
123123
<ValidatedInput
124124
type="text"
125-
class="w-68"
126125
placeholder="username"
127126
autocomplete="new-username"
128127
schema={UserNameSchema}
@@ -140,7 +139,6 @@ export function Register(): JSXElement {
140139
/>
141140
<ValidatedInput
142141
type="email"
143-
class="w-68"
144142
placeholder="email"
145143
autocomplete="new-email"
146144
schema={UserEmailSchema}
@@ -166,7 +164,6 @@ export function Register(): JSXElement {
166164
/>
167165
<ValidatedInput
168166
type="email"
169-
class="w-68"
170167
placeholder="verify email"
171168
autocomplete="verify-email"
172169
// oxlint-disable-next-line solid/reactivity
@@ -177,13 +174,13 @@ export function Register(): JSXElement {
177174
}
178175
disabled={!getLoginPageInputsEnabled()}
179176
debounceDelay={0}
177+
revalidateOn={emailValue}
180178
callback={(result: ValidationResult) => {
181179
setEmailVerifyValid(emailValid() && result.success);
182180
}}
183181
/>
184182
<ValidatedInput
185183
type="password"
186-
class="w-68"
187184
placeholder="password"
188185
autocomplete="new-password"
189186
name="new-password"
@@ -196,7 +193,6 @@ export function Register(): JSXElement {
196193
/>
197194
<ValidatedInput
198195
type="password"
199-
class="w-68"
200196
placeholder="verify password"
201197
autocomplete="verify-password"
202198
disabled={!getLoginPageInputsEnabled()}
@@ -208,6 +204,7 @@ export function Register(): JSXElement {
208204
: "verify password not matching password"
209205
}
210206
debounceDelay={0}
207+
revalidateOn={passwordValue}
211208
callback={(result: ValidationResult) => {
212209
setPasswordVerifyValid(passwordValid() && result.success);
213210
}}

frontend/src/ts/components/ui/ValidatedInput.tsx

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {
22
splitProps,
33
createEffect,
44
JSXElement,
5+
on,
56
onCleanup,
67
onMount,
78
} from "solid-js";
@@ -23,6 +24,7 @@ export function ValidatedInput<T = string>(
2324
onInput?: (value: T) => void;
2425
onFocus?: () => void;
2526
disabled?: boolean;
27+
revalidateOn?: () => unknown;
2628
},
2729
): JSXElement {
2830
// Refs are assigned by SolidJS via the ref attribute
@@ -46,6 +48,7 @@ export function ValidatedInput<T = string>(
4648
"autocomplete",
4749
"name",
4850
"onFocus",
51+
"revalidateOn",
4952
]);
5053
validatedInput = new ValidatedHtmlInputElement(
5154
element,
@@ -54,20 +57,37 @@ export function ValidatedInput<T = string>(
5457
validatedInput.setValue(props.value ?? null);
5558
});
5659

57-
onCleanup(() => validatedInput?.remove());
60+
createEffect(
61+
on(
62+
() => props.revalidateOn?.(),
63+
() => {
64+
if (validatedInput && inputEl()?.getValue() !== "") {
65+
validatedInput.triggerValidation();
66+
}
67+
},
68+
{ defer: true },
69+
),
70+
);
71+
72+
onCleanup(() => {
73+
validatedInput?.destroy();
74+
});
75+
5876
return (
59-
<input
60-
ref={inputRef}
61-
type={props.type ?? "text"}
62-
class={props.class}
63-
placeholder={props.placeholder}
64-
value={props.value ?? ""}
65-
disabled={props.disabled}
66-
// oxlint-disable-next-line react/no-unknown-property
67-
autocomplete={props.autocomplete}
68-
name={props.name}
69-
onInput={(e) => props.onInput?.(e.target.value as T)}
70-
onFocus={() => props.onFocus?.()}
71-
/>
77+
<div class="inputAndIndicator">
78+
<input
79+
ref={inputRef}
80+
type={props.type ?? "text"}
81+
class={props.class}
82+
placeholder={props.placeholder}
83+
value={props.value ?? ""}
84+
disabled={props.disabled}
85+
// oxlint-disable-next-line react/no-unknown-property
86+
autocomplete={props.autocomplete}
87+
name={props.name}
88+
onInput={(e) => props.onInput?.(e.target.value as T)}
89+
onFocus={() => props.onFocus?.()}
90+
/>
91+
</div>
7292
);
7393
}

frontend/src/ts/elements/input-indicator.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,17 @@ export class InputIndicator {
1818
options: Record<string, InputIndicatorOption>,
1919
) {
2020
this.inputElement = inputElement;
21-
const wrapper = this.inputElement.wrapWith(
22-
`<div class="inputAndIndicator"></div>`,
23-
);
24-
this.parentElement = wrapper;
21+
const existingWrapper = inputElement.native.closest(".inputAndIndicator");
22+
if (existingWrapper) {
23+
existingWrapper.querySelector(".statusIndicator")?.remove();
24+
this.parentElement = new ElementWithUtils(
25+
existingWrapper as HTMLInputElement,
26+
);
27+
} else {
28+
this.parentElement = this.inputElement.wrapWith(
29+
`<div class="inputAndIndicator"></div>`,
30+
);
31+
}
2532
this.options = options;
2633
this.currentStatus = null;
2734

frontend/src/ts/elements/input-validation.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,11 @@ export class ValidatedHtmlInputElement<
234234
triggerValidation(): void {
235235
this.dispatch("input");
236236
}
237+
238+
destroy(): void {
239+
this.indicator.hide();
240+
this.remove();
241+
}
237242
}
238243

239244
export type ConfigInputOptions<K extends ConfigKey, T = ConfigType[K]> = {

0 commit comments

Comments
 (0)