Good progress on styling post-registration form

This commit is contained in:
Melody Becker 2024-10-29 13:23:04 +01:00
parent 8b03454d6f
commit 1fb924f59c
17 changed files with 234 additions and 85 deletions

View file

@ -1,5 +1,6 @@
<div class="registration-form"> <div class="registration-form">
<h1 class="registration-form-username">username: {{this.args.username}}</h1> <h1 class="registration-form-username">username: {{this.args.username}}</h1>
<div class="registration-form-name-mail-wrapper">
<div class="registration-form-displayname-wrapper"> <div class="registration-form-displayname-wrapper">
<label> <label>
Displayname Displayname
@ -10,38 +11,53 @@
/> />
</label> </label>
</div> </div>
<Util::MailEntry @data={{this.mail}}/> <Util::MailEntry
@wrapper-classes="registration-form-mail-wrapper"
@input-classes="registration-form-mail-input"
@data={{this.mail}}
/>
</div>
<div class="registration-form-description-wrapper"> <div class="registration-form-description-wrapper">
<label> <label for="registration-description">
Description Description
<Input </label>
@type="text" <Textarea
id="registration-description"
@value={{this.description}} @value={{this.description}}
placeholder="Account description" placeholder="Account description"
/> />
</label>
</div> </div>
<div class="registration-form-gender-wrapper"> <fieldset class="registration-form-gender-wrapper">
<p class="registration-form-gender-info">Add your preferred pronouns</p> <legend class="registration-form-gender-info">Add your preferred pronouns</legend>
<Util::StringArray <Util::StringArray
@list={{this.gender}} @list={{this.gender}}
@onNewElement={{this.genderAddedHandler}} @onNewElement={{this.genderAddedHandler}}
@onDeleteElement={{this.genderRemovedHandler}} @onDeleteElement={{this.genderRemovedHandler}}
@wrapper-classes=""
@element-wrapper-classes=""
@element-classes=""
@remove-element-classes=""
@add-element-classes=""
/> />
</div> </fieldset>
<div class="register-form-being-wrapper"> <fieldset class="register-form-being-wrapper">
<p class="registration-form-being-info">Select the type of being you are. Multiselect is possible</p> <legend class="registration-form-being-info">Select the type of being you are. Multiselect is possible</legend>
<Util::Multiselect @elements={{this.beingTypes}} /> <Util::Multiselect
</div> @elements={{this.beingTypes}}
<div class="register-form-default-post-mode-wrapper"> @wrapper-class=""
<p class="registration-form-default-post-mode-info">Select the default mode for your posts</p> @label-class=""
@input-classes=""
/>
</fieldset>
<fieldset class="register-form-default-post-mode-wrapper">
<legend class="registration-form-default-post-mode-info">Select the default mode for your posts</legend>
<Util::OneOfArray <Util::OneOfArray
@elements={{array "Public" "Local" "Followers" "Direct"}} @elements={{array "Public" "Local" "Followers" "Direct"}}
@selected={{this.defaultpostmode}} @selected={{this.defaultpostmode}}
@name="default-post-mode" @name="default-post-mode"
@required={{true}} @required={{true}}
/> />
</div> </fieldset>
<div class="register-form-follow-approval-wrapper"> <div class="register-form-follow-approval-wrapper">
<label> <label>
Require approval for follow requests Require approval for follow requests
@ -58,8 +74,9 @@
<Input @type="checkbox" name="Indexable" @checked={{this.indexable}} /> <Input @type="checkbox" name="Indexable" @checked={{this.indexable}} />
</label> </label>
</div> </div>
<div class="register-form-custom-fields-wrapper"> <fieldset class="register-form-custom-fields-wrapper">
<legend>Custom fields</legend>
<Util::MapEdit @list={{this.customProperties}} /> <Util::MapEdit @list={{this.customProperties}} />
</div> </fieldset>
{{! TODO: Icon, Background, Banner }} {{! TODO: Icon, Background, Banner, Bluesky toggle }}
</div> </div>

View file

@ -1,29 +1,29 @@
import { action } from '@ember/object' import { action } from '@ember/object';
import Component from '@glimmer/component' import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking' import { tracked } from '@glimmer/tracking';
import isValidMail from 'frontend-reactive/helpers/is-valid-mail' import isValidMail from 'frontend-reactive/helpers/is-valid-mail';
export interface AuthPostRegistrationFormSignature { export interface AuthPostRegistrationFormSignature {
// The arguments accepted by the component // The arguments accepted by the component
Args: { Args: {
username: string username: string;
} };
// Any blocks yielded by the component // Any blocks yielded by the component
Blocks: { Blocks: {
default: [] default: [];
} };
// The element to which `...attributes` is applied in the component template // The element to which `...attributes` is applied in the component template
Element: null Element: null;
} }
export default class AuthPostRegistrationForm extends Component<AuthPostRegistrationFormSignature> { export default class AuthPostRegistrationForm extends Component<AuthPostRegistrationFormSignature> {
@tracked displayname: string = this.args.username @tracked displayname: string = this.args.username;
@tracked description: string = '' @tracked description: string = '';
@tracked gender: Array<{ value: string }> = [] @tracked gender: Array<{ value: string }> = [];
@tracked beingTypes: Array<{ @tracked beingTypes: Array<{
name: string name: string;
checked: boolean checked: boolean;
description: string description: string;
}> = [ }> = [
{ {
name: 'Human', name: 'Human',
@ -55,22 +55,22 @@ export default class AuthPostRegistrationForm extends Component<AuthPostRegistra
description: 'Doll', description: 'Doll',
checked: false, checked: false,
}, },
] ];
@tracked defaultpostmode: string = 'Public' @tracked defaultpostmode: string = 'Public';
@tracked followapproval: boolean = false @tracked followapproval: boolean = false;
// Actual custom properties stored in here // Actual custom properties stored in here
@tracked customProperties: Array<{ key: string; value: string }> = [] @tracked customProperties: Array<{ key: string; value: string }> = [];
@tracked indexable: boolean = true @tracked indexable: boolean = true;
@tracked mail = { mail: '', valid: false } @tracked mail = { mail: '', valid: false };
genderAddedHandler(newIndex: number) { genderAddedHandler(newIndex: number) {
console.log('gender added') console.log('gender added');
} }
genderRemovedHandler(removedIndex: number) { genderRemovedHandler(removedIndex: number) {
console.log('gender removed') console.log('gender removed');
} }
@action test() { @action test() {
console.log(this.mail) console.log(this.mail);
} }
} }

View file

@ -1,11 +1,18 @@
<div class="mail-entry {{@wrapper-classes}}"> <div class="mail-entry {{@wrapper-classes}}">
<label> <label>
Email Email
<Input @type="text" @value={{this.args.data.mail}} placeholder="Email address" {{on "change" (fn this.checkMail)}}/> <!--<div class="filling-spacer"/>-->
<Input
class="mail-input {{if this.mailOk "mail-input-ok" "mail-input-error"}} {{@input-classes}}"
@type="text"
@value={{this.args.data.mail}}
placeholder="Email address"
{{on "change" this.checkMail}}
/>
</label> </label>
{{#if this.mailOk}} {{#if this.mailOk}}
<p class="mail-ok">O</p> <p class="mail-ok mail-status">&#10004;</p>
{{else}} {{else}}
<p class="mail-error">X</p> <p class="mail-error mail-status">X</p>
{{/if}} {{/if}}
</div> </div>

View file

@ -1,27 +1,27 @@
import { action } from '@ember/object' import { action } from '@ember/object';
import { map } from '@ember/object/computed' import { map } from '@ember/object/computed';
import Component from '@glimmer/component' import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking' import { tracked } from '@glimmer/tracking';
const re = /.+@\S+\.\S+/ const re = /.+@\S+\.\S+/;
export interface UtilMailEntrySignature { export interface UtilMailEntrySignature {
// The arguments accepted by the component // The arguments accepted by the component
Args: { Args: {
data: { mail: string; valid: boolean } data: { mail: string; valid: boolean };
} };
// Any blocks yielded by the component // Any blocks yielded by the component
Blocks: { Blocks: {
default: [] default: [];
} };
// The element to which `...attributes` is applied in the component template // The element to which `...attributes` is applied in the component template
Element: null Element: null;
} }
export default class UtilMailEntry extends Component<UtilMailEntrySignature> { export default class UtilMailEntry extends Component<UtilMailEntrySignature> {
@tracked mailOk = this.args.data.valid @tracked mailOk = this.args.data.valid;
@action checkMail() { @action checkMail() {
this.args.data.valid = re.test(this.args.data.mail) this.args.data.valid = re.test(this.args.data.mail);
this.mailOk = this.args.data.valid this.mailOk = this.args.data.valid;
} }
} }

View file

@ -5,6 +5,7 @@
<Input <Input
@type="checkbox" @type="checkbox"
name="{{element.name}}" name="{{element.name}}"
class="{{@input-classes}}"
@checked={{element.checked}} @checked={{element.checked}}
{{on "change" this.onChange}} {{on "change" this.onChange}}
/> />

View file

@ -2,8 +2,9 @@
<ul> <ul>
{{#each this.args.list as |element index|}} {{#each this.args.list as |element index|}}
<li> <li>
<div class="string-array-element-wrapper"> <div class="string-array-element-wrapper {{@element-wrapper-classes}}">
<Input <Input
class="{{@element-classes}}"
@type="text" @type="text"
@value={{element.value}} @value={{element.value}}
/> />

View file

@ -1,7 +1,7 @@
import { helper } from '@ember/component/helper' import { helper } from '@ember/component/helper';
export default helper(function equals(args) { export default helper(function equals(args) {
if (args.length != 2) return false if (args.length != 2) return false;
console.log(args[0], args[1]) console.log(args[0], args[1]);
return args[0] == args[1] return args[0] == args[1];
}) });

View file

@ -0,0 +1,3 @@
import Route from '@ember/routing/route';
export default class IndexRoute extends Route {}

View file

@ -1,3 +1,75 @@
.registration-form { .registration-form {
background: var(--accent); background: var(--secondary);
display: flex;
flex-direction: column;
align-items: center;
width: fit-content;
}
.registration-form-name-mail-wrapper {
width: fit-content;
display: flex;
flex-direction: column;
align-items: end;
}
.registration-form-username {
width: max-content;
}
.registration-form-displayname-wrapper {
display: flex;
}
.registration-form-mail-wrapper {
display: flex;
width: max-content;
flex-direction: row;
}
.registration-form-mail-input {
width: max-content;
/*display: flex;*/
/*flex-grow: 1;*/
}
.registration-form-description-wrapper {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
}
.registration-form-gender-wrapper {
}
.registration-form-gender-info {
}
.register-form-being-wrapper {
margin: 1em;
}
.registration-form-being-info {
}
.register-form-default-post-mode-wrapper {
margin-bottom: 1em;
}
.registration-form-default-post-mode-info {
}
.register-form-follow-approval-wrapper {
margin-bottom: 0.5em;
}
.register-form-indexable-wrapper {
margin-bottom: 0.5em;
}
.register-form-custom-fields-wrapper {
flex-grow: 1;
width: 80%;
margin-bottom: 1em;
} }

View file

@ -15,3 +15,7 @@
margin-top: 0.2em; margin-top: 0.2em;
margin-bottom: 0.2em; margin-bottom: 0.2em;
} }
.filling-spacer {
flex-grow: 1;
}

View file

@ -1,6 +1,41 @@
.mail-entry { .mail-entry {
display: flex;
flex-direction: row;
} }
.mail-input {
outline: 0;
margin-top: 1em;
margin-bottom: 1em;
}
.mail-input-ok {
border: 1px solid green;
box-shadow: 0px 0px 5px green;
}
.mail-input-error {
border: 1px solid red;
box-shadow: 0px 0px 5px red;
}
.mail-status {
/*margin: 0;*/
margin-top: 0.75em;
margin-left: 0.4em;
}
.mail-ok { .mail-ok {
color: green;
/*margin-top: -0.25lh;*/
/*margin-bottom: -0.28lh;*/
font-size: 0.9lh;
margin: 0;
margin-left: 0.2em;
} }
.mail-ok {
.mail-error {
color: red;
margin-bottom: 0;
margin-left: 0.6em;
} }

View file

@ -1,4 +1,2 @@
{{page-title "FrontendReactive"}} {{page-title "FrontendReactive"}}
{{outlet}}
{{outlet}}{{!----}}
{{!--<Timeline @notes={{@model.notes}} />--}}

View file

@ -1,2 +1,2 @@
{{page-title "Auth"}} {{page-title "Auth"}}
{{outlet}} <Auth::Login />

View file

@ -0,0 +1,2 @@
{{page-title "Index"}}
<Timeline @notes={{@model.notes}} />

View file

@ -1,4 +1,2 @@
{{page-title "RegisterForm"}} {{page-title "RegisterForm"}}
<Auth::Login /> <Auth::PostRegistrationForm @username="bob" />
<br>
{{!--<Auth::PostRegistrationForm @username="bob" />--}}

View file

@ -0,0 +1,11 @@
import { module, test } from 'qunit';
import { setupTest } from 'frontend-reactive/tests/helpers';
module('Unit | Route | index', function (hooks) {
setupTest(hooks);
test('it exists', function (assert) {
const route = this.owner.lookup('route:index');
assert.ok(route);
});
});