Skip to content

Commit

Permalink
Merge pull request #70 from REAN-Foundation/rupali_ui_fixes
Browse files Browse the repository at this point in the history
Rupali UI fixes
  • Loading branch information
dattatraya-inflection authored Oct 5, 2024
2 parents 8b54c98 + 0cdcf7c commit 66c487f
Show file tree
Hide file tree
Showing 30 changed files with 675 additions and 329 deletions.
137 changes: 69 additions & 68 deletions src/lib/components/input-chips.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -24,34 +24,45 @@
const cInputField = 'unstyled bg-transparent border-0 !ring-0 p-0 pl-1 w-full';
let inputValue = '';
let inputValid = true;
let errorMessage = '';
function onInputHandler() {
inputValid = true;
inputValid = true;
errorMessage = '';
}
function validate() {
if (!inputValue) return false;
if (validation !== void 0 && !validation()) return false;
if (max !== -1 && value.length >= max) return false;
if (minlength !== -1 && inputValue.length < minlength) return false;
if (maxlength !== -1 && inputValue.length > maxlength) return false;
if (whitelist.length > 0 && !whitelist.includes(inputValue)) return false;
if (allowDuplicates === false && value.includes(inputValue)) return false;
return true;
if (!inputValue) return false;
if (validation !== void 0 && !validation()) return false;
if (max !== -1 && value.length >= max) return false;
if (minlength !== -1 && inputValue.length < minlength) return false;
if (maxlength !== -1 && inputValue.length > maxlength) return false;
if (whitelist.length > 0 && !whitelist.includes(inputValue)) return false;
if (allowDuplicates === false && value.includes(inputValue)) {
errorMessage = 'Tag is already added';
return false;
}
return true;
}
function addChip(event) {
event.preventDefault();
inputValid = validate();
if (inputValid === false) return;
inputValue = inputValue.trim();
inputValue = allowUpperCase ? inputValue : inputValue.toLowerCase();
value = [...value, inputValue];
dispatch('add', { event, chipIndex: value.length - 1, chipValue: inputValue });
inputValue = '';
event.preventDefault();
inputValid = validate();
if (inputValid === false) return;
inputValue = inputValue.trim();
inputValue = allowUpperCase ? inputValue : inputValue.toLowerCase();
value = [...value, inputValue];
dispatch('add', { event, chipIndex: value.length - 1, chipValue: inputValue });
inputValue = '';
}
function removeChip(event, chipIndex, chipValue) {
if ($$restProps.disabled) return;
value = value.filter((_, i) => i !== chipIndex);
dispatch('remove', { event, chipIndex, chipValue });
if ($$restProps.disabled) return;
value = value.filter((_, i) => i !== chipIndex);
dispatch('remove', { event, chipIndex, chipValue });
}
$: classesInvalid = inputValid === false ? invalid : '';
$: classesBase = `${cBase} ${padding} ${rounded} ${$$props.class ?? ''} ${classesInvalid}`;
$: classesInterface = `${cInterface}`;
Expand All @@ -60,58 +71,48 @@
</script>
<div class="input-chip {classesBase}" class:opacity-50={$$restProps.disabled}>
<!-- NOTE: Don't use `hidden` as it prevents `required` from operating -->
<div class="h-0 overflow-hidden">
<select bind:value {name} multiple {required} tabindex="-1">
<!-- NOTE: options are required! -->
{#each value as option}<option value={option}>{option}</option>{/each}
</select>
<select bind:value {name} multiple {required} tabindex="-1">
{#each value as option}<option value={option}>{option}</option>{/each}
</select>
</div>
<!-- Interface -->
<div class="input-chip-interface {classesInterface}">
<!-- Input Field -->
<form on:submit={addChip}>
<input
type="text"
bind:value={inputValue}
placeholder={$$restProps.placeholder ?? 'To add a tag, type and press enter.'}
class="input-chip-field {classesInputField}"
on:input={onInputHandler}
on:input
disabled={$$restProps.disabled}
/>
</form>
<form on:submit={addChip}>
<input
type="text"
bind:value={inputValue}
placeholder={$$restProps.placeholder ?? 'To add a tag, type and press enter.'}
class="input-chip-field {classesInputField}"
on:input={onInputHandler}
disabled={$$restProps.disabled}
/>
</form>
<!-- Chip List -->
{#if value.length}
<div
class="input-chip-list {classesChipList}"
transition:fly|local={{ duration, opacity: 0, y: -20 }}
>
{#each value as c, i (c)}
<!-- Wrapping div required for FLIP animation -->
<div animate:flip={{ duration }}>
<button
class="chip {chips}"
on:click={(e) => {
e.preventDefault();
removeChip(e, i, c);
}}
on:click
on:keypress
on:keydown
on:keyup
transition:scale|local={{ duration, opacity: 0 }}
>
<span>{c}</span>
<span>✕</span>
</button>
{#if value.length}
<div class="input-chip-list {classesChipList}" transition:fly|local={{ duration, opacity: 0, y: -20 }}>
{#each value as c, i (c)}
<div animate:flip={{ duration }}>
<button
class="chip {chips}"
on:click={(e) => {
e.preventDefault();
removeChip(e, i, c);
}}
transition:scale|local={{ duration, opacity: 0 }}
>
<span>{c}</span>
<span>✕</span>
</button>
</div>
{/each}
{#if value.length > 9}
<div class="text-error-500">Number of tags should be less than or equal to 10</div>
{/if}
</div>
{/each}
{#if value.length > 9 }
<div class="text-error-500">Number of tags should be less than or equal to 10</div>
{/if}
</div>
{/if}
{/if}
{#if errorMessage}
<div class="text-error-500">{errorMessage}</div>
{/if}
</div>
</div>
14 changes: 11 additions & 3 deletions src/lib/components/navbar/navbar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,23 @@
getPublicFooterText,
getPublicFooterLink
} from '$lib/themes/theme.selector';
import Image from '$lib/components/image.svelte';
///////////////////////////////////////////////////////////////
export let userId = undefined;
export let tenantSettings = undefined;
export let userRole = undefined;
export let username = undefined;
export let email = undefined;
export let imageUrl = undefined;
const navbarTabs: TabDefinition[] = navbarMenu(userId);
const sidebarTabs: TabDefinition[] = sidebarMenu(userId);
const drawerStore = getDrawerStore();
const logoImageSource = getPublicLogoImageSource();
const footerText = `© ${new Date().getFullYear()} ${getPublicFooterText()}`;
const footerLink = getPublicFooterLink();
function drawerRightOpen(): void {
const settings: DrawerSettings = {
id: 'rightSidebar',
Expand Down Expand Up @@ -76,7 +79,12 @@
on:click={drawerRightOpen}
>
<!-- <Icon icon="material-symbols:person-outline-rounded" class="text-3xl" /> -->
<img class="w-8 ml-2 text-lg invert dark:filter-none" src="/user.png" alt="" />
<!-- <img class="w-8 ml-2 text-lg invert dark:filter-none" src="/user.png" alt="" /> -->
{#if imageUrl}
<Image cls="flex h-8 w-8 rounded-full" source={imageUrl} w=24 h=24 />
{:else}
<img class="w-8 ml-2 text-lg invert dark:filter-none" src="/user.png" alt="" />
{/if}
</button>
</svelte:fragment>
</AppBar>
Expand All @@ -95,7 +103,7 @@
</AppShell>
<Drawer>
{#if $drawerStore.id === 'rightSidebar'}
<SettingMenu on:click={drawerRightClose} on:logout userId ={userId} username={username} email={email}/>
<SettingMenu on:click={drawerRightClose} on:logout userId ={userId} username={username} email={email} imageUrl={imageUrl}/>
{:else if $drawerStore.id === 'leftSidebar'}
<div class="grid justify-center w-60 space-y-4 mt-5">
{#each sidebarTabs as t}
Expand Down
23 changes: 18 additions & 5 deletions src/lib/components/navbar/setting.menus.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,17 @@
import Icon from '@iconify/svelte';
import { createEventDispatcher } from 'svelte';
import { writable } from 'svelte/store';
import Image from '$lib/components/image.svelte';
//////////////////////////////////////////////////////////
const expandedMenus = writable({});
export let userId;
export let username = '';
export let email = '';
export let userId = undefined;
export let username = undefined;
export let email = undefined;
export let imageUrl = undefined
$: avatarSource = imageUrl;
const dispatch = createEventDispatcher();
async function changePassword() {
Expand Down Expand Up @@ -109,11 +112,21 @@
</button>
<div class="flex flex-col items-center gap-2">
<div class="relative inline-block bg-primary-200 rounded-full h-16 w-16">
<img
<!-- <img
class="object-cover rounded-full h-16 w-16"
src="/user.png"
alt="avatar"
/>
/> -->
{#if avatarSource}
<Image cls="flex h-16 w-16 rounded-full" source={avatarSource} w=24 h=24 />
<!-- <img class="flex h-24 w-24 rounded-full" src={avatarSource} alt="d" /> -->
{:else}
<img
class="object-cover rounded-full h-16 w-16"
src="/user.png"
alt="avatar"
/>
{/if}
</div>
<div class="text-center w-64">
<h3 class="text-lg font-medium truncate">{username}</h3>
Expand Down
18 changes: 18 additions & 0 deletions src/lib/utils/formValidation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { z, ZodSchema } from 'zod';

export const validateFormData = async <T extends ZodSchema>(
request: Request,
schema: T
) => {
const data = await request.formData();
const formData = Object.fromEntries(
Array.from(data.entries()).map(([key, value]) => [key, typeof value === 'string' ? value : ''])
);
try {
const result = schema.parse(formData);
return { result, errors: null };
} catch (err: any) {
const { fieldErrors: errors } = err.flatten();
return { result: formData, errors };
}
};
Loading

0 comments on commit 66c487f

Please sign in to comment.