register new inputs ability
This commit is contained in:
parent
5f5e54b51a
commit
ad62ea5735
|
@ -1,13 +1,27 @@
|
|||
<script lang="ts">
|
||||
import elementIdGenerator from '$lib/utils/elementIdGenerator'
|
||||
import { Input } from 'flowbite-svelte'
|
||||
import { createEventDispatcher, onMount } from 'svelte'
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
export let value = ''
|
||||
export let placeholder = ''
|
||||
export let id = elementIdGenerator()
|
||||
export let podm = true
|
||||
export let readOnly = false
|
||||
export let maxLength = Infinity
|
||||
export let icon: string | null = null
|
||||
export let iconFunction: 'password' = null
|
||||
export let changedIconOnActive = icon
|
||||
export let iconPosition: 'right' | 'left' = 'left'
|
||||
|
||||
//erant-new
|
||||
export let autocomplete = ''
|
||||
export let pattern: any = null
|
||||
|
||||
export let value: string = ''
|
||||
export let focus = false
|
||||
export let prefix: string = ''
|
||||
export let placeholder: string = ''
|
||||
export let autocomplete: string = ''
|
||||
const id = elementIdGenerator()
|
||||
export let invisiblePrefix = icon ? true : false
|
||||
|
||||
export let type:
|
||||
| 'color'
|
||||
| 'date'
|
||||
|
@ -29,28 +43,106 @@
|
|||
| 'search'
|
||||
| 'textarea' = 'text'
|
||||
|
||||
let className = 'bg-white text-black border-4 border-blue-300 rounded-[25px] text-left text-[30px] p-[16px] outline-none appearance-none w-full'
|
||||
let className: string = ''
|
||||
export { className as class }
|
||||
|
||||
const setType = (node: HTMLInputElement) => {
|
||||
node.type = type
|
||||
$: inputValue = pattern ? value.replace(pattern, '') : value //this is here because we always want to equal input.value = value
|
||||
|
||||
$: prefixControl(inputValue) //when inputValue changes => it will check prefix (so when we do $: inputValue = value this func will trigger every moment when inputValue will change and it will overwhite currect input.value thats will be {value})
|
||||
|
||||
const prefixControl = (_e) => {
|
||||
if (prefix) {
|
||||
if (!invisiblePrefix) {
|
||||
if (inputValue?.indexOf(prefix) < 0) inputValue = `${prefix}${inputValue}`
|
||||
value = inputValue
|
||||
} else if (inputValue?.indexOf(prefix) < 0) {
|
||||
value = `${prefix}${inputValue}`
|
||||
//inputValue = value.slice(prefix.length, value.length)
|
||||
} else value = inputValue
|
||||
} else {
|
||||
value = inputValue
|
||||
}
|
||||
}
|
||||
|
||||
const setFocus = (node: HTMLInputElement | HTMLTextAreaElement) => {
|
||||
focus && node.focus()
|
||||
}
|
||||
onMount(() => {
|
||||
prefixControl('')
|
||||
})
|
||||
|
||||
$: if (prefix && !value.startsWith(prefix)) value = `${prefix}${value}`
|
||||
let iconActived = false
|
||||
let iconPushedCount = 0
|
||||
|
||||
const iconClick = () => {
|
||||
iconPushedCount++
|
||||
iconActived = iconPushedCount % 2 === 1
|
||||
dispatch('iconClick')
|
||||
if (iconFunction === 'password') type = type === 'text' ? 'password' : 'text'
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if type === 'textarea'}
|
||||
<textarea {id} {placeholder} use:setFocus bind:value class={className} {...$$restProps} />
|
||||
{#if icon}
|
||||
{#if iconPosition === 'left'}
|
||||
<Input
|
||||
{autocomplete}
|
||||
{...$$restProps}
|
||||
maxlength={maxLength}
|
||||
readonly={readOnly ? true : null}
|
||||
{id}
|
||||
{type}
|
||||
bind:value={inputValue}
|
||||
class="input rounded-[24px] p-4 text-gray-900 border border-gray-300 text-left outline-none appearance-none {className} {readOnly ? 'cursor-pointer' : ''}"
|
||||
color={!podm ? 'red' : null}
|
||||
{placeholder}
|
||||
on:input
|
||||
>
|
||||
<button class={`w-auto pointer-events-auto z-50 `} on:click={iconClick} slot="left">
|
||||
{#if iconActived}
|
||||
{changedIconOnActive}
|
||||
{:else}
|
||||
<input {autocomplete} {id} {placeholder} class:prefixPlaceholder={prefix.length === value.length} class={'' + className} use:setType use:setFocus bind:value {...$$restProps} />
|
||||
{icon}
|
||||
{/if}
|
||||
</button>
|
||||
</Input>
|
||||
{:else}
|
||||
<Input
|
||||
{autocomplete}
|
||||
{...$$restProps}
|
||||
maxlength={maxLength}
|
||||
readonly={readOnly ? true : null}
|
||||
{id}
|
||||
{type}
|
||||
bind:value={inputValue}
|
||||
class="input rounded-[24px] p-4 text-gray-900 border border-gray-300 text-left outline-none appearance-none {className} {readOnly ? 'cursor-pointer' : ''}"
|
||||
color={!podm ? 'red' : null}
|
||||
{placeholder}
|
||||
on:input
|
||||
>
|
||||
<button class={`w-auto pointer-events-auto z-50 `} on:click={iconClick} slot="right">
|
||||
{#if iconActived}
|
||||
{changedIconOnActive}
|
||||
{:else}
|
||||
{icon}
|
||||
{/if}
|
||||
</button>
|
||||
</Input>
|
||||
{/if}
|
||||
{:else}
|
||||
<Input
|
||||
{autocomplete}
|
||||
{...$$restProps}
|
||||
maxlength={maxLength}
|
||||
readonly={readOnly ? true : null}
|
||||
{id}
|
||||
{type}
|
||||
bind:value={inputValue}
|
||||
class="input rounded-[24px] p-4 text-gray-900 border border-gray-300 text-left outline-none appearance-none {className} {readOnly ? 'cursor-pointer' : ''}"
|
||||
color={!podm ? 'red' : null}
|
||||
{placeholder}
|
||||
on:input
|
||||
/>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
input::placeholder {
|
||||
.input::placeholder {
|
||||
color: #8f8f8f;
|
||||
font-size: 18px;
|
||||
font-family: 'Source Sans Pro';
|
||||
|
|
|
@ -5,7 +5,10 @@
|
|||
const urlFail = `${location.origin}/register/failed`
|
||||
const urlSuccess = `${location.origin}/create/account`
|
||||
|
||||
export let disableLogin = false
|
||||
|
||||
const login = async (platform: 'facebook' | 'google') => {
|
||||
if (disableLogin) return
|
||||
try {
|
||||
await user.deleteSessions()
|
||||
} catch (error) {}
|
||||
|
@ -14,12 +17,12 @@
|
|||
</script>
|
||||
|
||||
<div class="continue_with">
|
||||
<button>
|
||||
<button on:click>
|
||||
<GoogleLogo />
|
||||
<p>Continue with Google</p>
|
||||
</button>
|
||||
|
||||
<button on:click={() => login('facebook')}>
|
||||
<button on:click on:click={() => login('facebook')}>
|
||||
<p>Continue with Facebook</p>
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -18,13 +18,15 @@
|
|||
let repeatPassword = ''
|
||||
let name = ''
|
||||
let erantId = ''
|
||||
let termsChecked: boolean = false
|
||||
let termsChecked = false
|
||||
let termsCheckboxShake = false
|
||||
$: if (termsCheckboxShake) setTimeout(() => (termsCheckboxShake = false), 750)
|
||||
|
||||
let state: 'email-sent' | 'register' | 'loading' = 'register'
|
||||
let error: string | null = null
|
||||
$: buttonCodition = name.length > 0 && email.length > 0 && password.length >= 8 && password === repeatPassword && erantId.length > 2 && termsChecked && nicknameIsValid
|
||||
|
||||
const pattern = /^[a-zA-Z0-9+@]+$/
|
||||
const pattern = /[^a-zA-Z0-9]/g
|
||||
$: nicknameIsValid = pattern.test(erantId)
|
||||
|
||||
const register = async () => {
|
||||
|
@ -70,14 +72,38 @@
|
|||
<Input bind:value={name} placeholder="Your name" autocomplete="full-name" class="p-3 border-1 rounded-[15px] bg-[#eeeeee] text-lg w-full" />
|
||||
<Input bind:value={email} placeholder="Your e-mail" autocomplete="email" class="p-3 border-1 rounded-[15px] bg-[#eeeeee] text-lg w-full" />
|
||||
<div class="w-full">
|
||||
<Input bind:value={erantId} placeholder="@your_nickname" class="p-3 border-1 rounded-[15px] bg-[#eeeeee] text-lg w-full" prefix="@" />
|
||||
<Input
|
||||
bind:value={erantId}
|
||||
prefix="@"
|
||||
placeholder="your_nickname"
|
||||
class="p-3 border-1 rounded-[15px] bg-[#eeeeee] text-lg w-full"
|
||||
{pattern}
|
||||
invisiblePrefix
|
||||
icon="@"
|
||||
/>
|
||||
{#if !nicknameIsValid}
|
||||
<Helper class="flex justify-start w-full pl-4" color="red">Your nickname can include only a-zA-Z0-9 characters</Helper>
|
||||
{/if}
|
||||
</div>
|
||||
<HiddenInput bind:value={password} placeholder="Password" />
|
||||
<Input
|
||||
iconFunction="password"
|
||||
bind:value={password}
|
||||
placeholder="Password"
|
||||
class="p-3 border-1 rounded-[15px] bg-[#eeeeee] text-lg w-full"
|
||||
inputFunction="password"
|
||||
iconPosition="right"
|
||||
icon="eye"
|
||||
/>
|
||||
<div class="w-full">
|
||||
<HiddenInput bind:value={repeatPassword} placeholder="Re-type password" />
|
||||
<Input
|
||||
iconFunction="password"
|
||||
bind:value={repeatPassword}
|
||||
placeholder="Re-type password"
|
||||
class="p-3 border-1 rounded-[15px] bg-[#eeeeee] text-lg w-full"
|
||||
inputFunction="password"
|
||||
iconPosition="right"
|
||||
icon="eye"
|
||||
/>
|
||||
{#if password !== repeatPassword && password.length >= 8}
|
||||
<Helper class="flex justify-start w-full pl-4" helperClass="text-sm" color="red">Passwords are not equal</Helper>
|
||||
{/if}
|
||||
|
@ -86,7 +112,9 @@
|
|||
<div class="flex items-center">
|
||||
<Checkbox
|
||||
bind:checked={termsChecked}
|
||||
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
|
||||
class="w-5 h-5 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600 {termsCheckboxShake
|
||||
? 'animate-bounce border-4 border-red-500'
|
||||
: ''}"
|
||||
/>
|
||||
<label for="link-checkbox" class="ml-2 text-sm font-medium text-gray-900 dark:text-gray-300"
|
||||
>I agree with the <a href="erant.cz/terms-and-conditions" class="text-blue-600 dark:text-blue-500 hover:underline">terms and conditions</a>,
|
||||
|
@ -104,7 +132,12 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<SocialLogin />
|
||||
<SocialLogin
|
||||
disableLogin={!termsChecked}
|
||||
on:click={() => {
|
||||
if (!termsChecked) termsCheckboxShake = true
|
||||
}}
|
||||
/>
|
||||
|
||||
<div class="LR_switch">
|
||||
<p>Already have an account? <a href="/login">Log In</a></p>
|
||||
|
|
Loading…
Reference in New Issue