Added the access code component. Improved layout. General clean up and improvements.

This commit is contained in:
Scott Idem
2024-02-22 17:21:22 -05:00
parent 5a13852432
commit d1328eb67c
16 changed files with 973 additions and 152 deletions

View File

@@ -27,7 +27,7 @@ let sponsorship_location_select_option_li = {}; // This is a list (dict) of key
if ($slct.sponsorship_id) {
// console.log(`Sponsorship ID selected: ${$slct.sponsorship_id}`);
// console.log(`Sponsorship Object selected: ${$slct.sponsorship_obj}`)
// console.log(`Sponsorship object selected:`, $slct.sponsorship_obj);
// $slct_trigger = 'load__sponsorship_obj';
disable_submit_btn = false;

60
package-lock.json generated
View File

@@ -41,6 +41,7 @@
"tailwindcss": "3.4.1",
"tslib": "^2.4.1",
"typescript": "^5.0.0",
"typescript-svelte-plugin": "^0.3.37",
"vite": "^5.0.3",
"vite-plugin-tailwind-purgecss": "0.2.0",
"vitest": "^1.2.0"
@@ -2100,6 +2101,12 @@
}
}
},
"node_modules/dedent-js": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dedent-js/-/dedent-js-1.0.1.tgz",
"integrity": "sha512-OUepMozQULMLUmhxS95Vudo0jb0UchLimi3+pQ2plj61Fcy8axbP9hbiD4Sz6DPqn6XG3kfmziVfQ1rSys5AJQ==",
"dev": true
},
"node_modules/deep-eql": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz",
@@ -3289,6 +3296,15 @@
"get-func-name": "^2.0.1"
}
},
"node_modules/lower-case": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
"integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
"dev": true,
"dependencies": {
"tslib": "^2.0.3"
}
},
"node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -3512,6 +3528,16 @@
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
"dev": true
},
"node_modules/no-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
"integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
"dev": true,
"dependencies": {
"lower-case": "^2.0.2",
"tslib": "^2.0.3"
}
},
"node_modules/node-releases": {
"version": "2.0.14",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
@@ -3664,6 +3690,16 @@
"node": ">=6"
}
},
"node_modules/pascal-case": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz",
"integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==",
"dev": true,
"dependencies": {
"no-case": "^3.0.4",
"tslib": "^2.0.3"
}
},
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@@ -4910,6 +4946,20 @@
"@types/estree": "*"
}
},
"node_modules/svelte2tsx": {
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/svelte2tsx/-/svelte2tsx-0.7.1.tgz",
"integrity": "sha512-0lKa6LrqJxRan0bDmBd/uFsVzYSXnoFUDaczaH0znke/XI79oy1JjFaF51J9EsOvpn8lXPlrUc3n/MA/ORNxBg==",
"dev": true,
"dependencies": {
"dedent-js": "^1.0.1",
"pascal-case": "^3.1.1"
},
"peerDependencies": {
"svelte": "^3.55 || ^4.0.0-next.0 || ^4.0 || ^5.0.0-next.0",
"typescript": "^4.9.4 || ^5.0.0"
}
},
"node_modules/tailwindcss": {
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.1.tgz",
@@ -5168,6 +5218,16 @@
"node": ">=14.17"
}
},
"node_modules/typescript-svelte-plugin": {
"version": "0.3.37",
"resolved": "https://registry.npmjs.org/typescript-svelte-plugin/-/typescript-svelte-plugin-0.3.37.tgz",
"integrity": "sha512-eg+uod/Ao6PEQ606DpexbbKF9Rzm3w8W53DyVFaNnR1CTmQQ4LbKwjcVqFhwFnGeXqrvB+0UK3atTaE+HyK0uA==",
"dev": true,
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.4.14",
"svelte2tsx": "~0.7.0"
}
},
"node_modules/ufo": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/ufo/-/ufo-1.4.0.tgz",

View File

@@ -42,6 +42,7 @@
"tailwindcss": "3.4.1",
"tslib": "^2.4.1",
"typescript": "^5.0.0",
"typescript-svelte-plugin": "^0.3.37",
"vite": "^5.0.3",
"vite-plugin-tailwind-purgecss": "0.2.0",
"vitest": "^1.2.0"

View File

@@ -43,6 +43,13 @@ body {
opacity: .5;
}
/* Allow content to scroll horizontal if too wide */
.ae_h_scrollfix {
max-width: 100%;
overflow-x: auto;
}
/* These helps with the Skeleton Tailwind modal utility. */
.ae_modal_scrollfix {
/* Allow modal content to scroll if it's too long */
overflow-y: auto;

View File

@@ -3,7 +3,7 @@ import { readable, writable } from 'svelte/store';
import type { Writable } from 'svelte/store';
import { PUBLIC_TESTING, PUBLIC_AE_API_PROTOCOL, PUBLIC_AE_API_SERVER, PUBLIC_AE_API_BAK_SERVER, PUBLIC_AE_API_PORT, PUBLIC_AE_API_PATH, PUBLIC_AE_API_SECRET_KEY, PUBLIC_AE_API_CRUD_SUPER_KEY, PUBLIC_AE_ACCOUNT_ID } from '$env/static/public';
import { PUBLIC_TESTING, PUBLIC_AE_API_PROTOCOL, PUBLIC_AE_API_SERVER, PUBLIC_AE_API_BAK_SERVER, PUBLIC_AE_API_PORT, PUBLIC_AE_API_PATH, PUBLIC_AE_API_SECRET_KEY, PUBLIC_AE_API_CRUD_SUPER_KEY, PUBLIC_AE_ACCOUNT_ID, PUBLIC_AE_SPONSORSHIP_CFG_ID } from '$env/static/public';
console.log(`Aether Config - TESTING:`, PUBLIC_TESTING);
const api_base_url = `${PUBLIC_AE_API_PROTOCOL}://${PUBLIC_AE_API_SERVER}:${PUBLIC_AE_API_PORT}${PUBLIC_AE_API_PATH}`;
@@ -13,6 +13,7 @@ const api_secret_key = PUBLIC_AE_API_SECRET_KEY;
const api_crud_super_key = PUBLIC_AE_API_CRUD_SUPER_KEY;
const ae_account_id = PUBLIC_AE_ACCOUNT_ID;
const ae_sponsorship_cfg_id = PUBLIC_AE_SPONSORSHIP_CFG_ID;
// import { getStores, navigating, page, updated } from '$app/stores';
@@ -32,13 +33,24 @@ type key_val = {
// *** BEGIN *** Longer-term app data. This should be stored to local storage.
export let ae_app_local_data_struct: key_val = {
'ver': '0.0.5',
'ver': '0.0.7',
'name': 'Aether App Template',
'theme': 'light',
'account_id': ae_account_id, // OSIT Demo _XY7DXtc9MY
'site_domain': null, // https://example.com, https://dev.example.com, etc.
'administrator_access': true,
'trusted_access': true,
'page_access_code_li': {'administrator': '11500', 'trusted': '19111', 'authenticated': '00000'},
'administrator_passcode': '11500',
'trusted_passcode': '19111',
'access_type': 'anonymous',
'administrator_access': false,
'trusted_access': false,
'public_access': false,
'authenticated_access': false,
'anonymous_access': true,
'ds': {},
'hub': {
'ds': {},
@@ -46,6 +58,8 @@ export let ae_app_local_data_struct: key_val = {
'mod': { // module
'events': {},
'sponsorships': {
'cfg_id': ae_sponsorship_cfg_id,
for_type: null,
for_id: null,
@@ -60,10 +74,10 @@ export let ae_app_local_data_struct: key_val = {
console.log(`Aether Config - App Local Storage Data:`, ae_app_local_data_struct);
// This works, but does not uses local storage:
export let ae_loc = writable(ae_app_local_data_struct);
// export let ae_loc = writable(ae_app_local_data_struct);
// This works and uses local storage:
// export let ae_loc: Writable<key_val> = localStorageStore('ae_loc', ae_app_local_data_struct);
export let ae_loc: Writable<key_val> = localStorageStore('ae_loc', ae_app_local_data_struct);
// This does not work yet...? Don't use.
@@ -73,10 +87,10 @@ export let ae_loc = writable(ae_app_local_data_struct);
// *** BEGIN *** Temporary app data. This should be stored to session storage.
export let ae_app_session_data_struct: key_val = {
'ver': '0.0.1',
'ver': '0.0.2',
// 'name': 'Aether App Template',
// 'theme': 'light',
'account_id': ae_app_local_data_struct.account_id,
'account_id': ae_account_id,
// 'obj': {},
}
console.log(`Aether Config - App Session Storage Data:`, ae_app_session_data_struct);
@@ -92,7 +106,7 @@ export let ae_api_data_struct: key_val = {
'api_secret_key_bak': api_secret_key, // 'YOUR_API_SECRET_KEY',
'api_crud_super_key': api_crud_super_key, // 'YOUR_SUPER_KEY' 'zp5PtX4zUsI'
'headers': {},
'account_id': ae_app_local_data_struct.account_id,
'account_id': ae_account_id,
}
let ae_api_headers: key_val = {};
@@ -101,7 +115,7 @@ ae_api_headers['content-type'] = 'application/json';
ae_api_headers['x-aether-api-key'] = ae_api_data_struct.api_secret_key;
ae_api_headers['x-aether-api-token'] = 'fake-temp-token';
ae_api_headers['x-aether-api-expire-on'] = '';
ae_api_headers['x-account-id'] = ae_app_local_data_struct.account_id;
ae_api_headers['x-account-id'] = ae_account_id,
ae_api_data_struct['headers'] = ae_api_headers;
console.log(`Aether Config - API Data:`, ae_api_data_struct);
@@ -114,7 +128,7 @@ export let slct_trigger: any = writable(null);
console.log(`Aether Config - Selected Trigger:`, slct_trigger);
let slct_obj_template: key_val = {
'account_id': null,
'account_id': ae_account_id,
'account_obj': {},
'event_id': null,
'event_obj': {},

View File

@@ -1,5 +1,9 @@
import dayjs from 'dayjs';
type key_val = {
[key: string]: any;
};
export let iso_datetime_formatter = function iso_datetime_formatter(raw_datetime: string|Date, named_format: string) {
// console.log('*** iso_datetime_formatter() ***');
@@ -234,10 +238,177 @@ export let extract_prefixed_form_data = function extract_prefixed_form_data({pre
}
// NOTE: I know there is a better more efficient way to do this, but I don't have time for that right now.
export let process_permission_checks = function process_permission_checks(access_type: string) {
// let access_checks = { 'access_type': null, 'super_check': null };
let access_checks: key_val = {};
if (access_type == 'super') {
access_checks.access_type = 'super';
access_checks.super_check = true;
access_checks.manager_check = false;
access_checks.administrator_check = false;
access_checks.support_check = false;
access_checks.assistant_check = false;
access_checks.trusted_check = false;
access_checks.verified_check = false;
access_checks.provisional_check = false;
access_checks.public_check = false;
access_checks.authenticated_check = true;
access_checks.anonymous_check = false;
access_checks.super_access = true;
access_checks.manager_access = true;
access_checks.administrator_access = true;
access_checks.support_access = true;
access_checks.assistant_access = true;
access_checks.trusted_access = true;
access_checks.verified_access = true;
access_checks.provisional_access = true;
access_checks.public_access = true;
access_checks.authenticated_access = true;
access_checks.anonymous_access = true;
} else if (access_type == 'manager') {
access_checks.access_type = 'manager';
access_checks.super_check = false;
access_checks.manager_check = true;
access_checks.administrator_check = false;
access_checks.support_check = false;
access_checks.assistant_check = false;
access_checks.trusted_check = false;
access_checks.verified_check = false;
access_checks.provisional_check = false;
access_checks.public_check = false;
access_checks.authenticated_check = true;
access_checks.anonymous_check = false;
access_checks.super_access = false;
access_checks.manager_access = true;
access_checks.administrator_access = true;
access_checks.support_access = true;
access_checks.assistant_access = true;
access_checks.trusted_access = true;
access_checks.verified_access = true;
access_checks.provisional_access = true;
access_checks.public_access = true;
access_checks.authenticated_access = true;
access_checks.anonymous_access = true;
} else if (access_type == 'administrator') {
access_checks.access_type = 'administrator';
access_checks.super_check = false;
access_checks.manager_check = false;
access_checks.administrator_check = true;
access_checks.support_check = false;
access_checks.assistant_check = false;
access_checks.trusted_check = false;
access_checks.verified_check = false;
access_checks.provisional_check = false;
access_checks.public_check = false;
access_checks.authenticated_check = false;
access_checks.anonymous_check = false;
access_checks.super_access = false;
access_checks.manager_access = false;
access_checks.administrator_access = true;
access_checks.support_access = true;
access_checks.assistant_access = true;
access_checks.trusted_access = true;
access_checks.verified_access = true;
access_checks.provisional_access = true;
access_checks.public_access = true;
access_checks.authenticated_access = true;
access_checks.anonymous_access = true;
} else if (access_type == 'trusted') {
access_checks.access_type = 'trusted';
access_checks.super_check = false;
access_checks.manager_check = false;
access_checks.administrator_check = false;
access_checks.support_check = false;
access_checks.assistant_check = false;
access_checks.trusted_check = true;
access_checks.verified_check = false;
access_checks.provisional_check = false;
access_checks.public_check = false;
access_checks.authenticated_check = true;
access_checks.anonymous_check = false;
access_checks.super_access = false;
access_checks.manager_access = false;
access_checks.administrator_access = false;
access_checks.support_access = false;
access_checks.assistant_access = false;
access_checks.trusted_access = true;
access_checks.verified_access = true;
access_checks.provisional_access = true;
access_checks.public_access = true;
access_checks.authenticated_access = true;
access_checks.anonymous_access = true;
} else if (access_type == 'authenticated') {
access_checks.access_type = 'authenticated';
access_checks.super_check = false;
access_checks.manager_check = false;
access_checks.administrator_check = false;
access_checks.support_check = false;
access_checks.assistant_check = false;
access_checks.trusted_check = false;
access_checks.verified_check = false;
access_checks.provisional_check = false;
access_checks.public_check = false;
access_checks.authenticated_check = true;
access_checks.anonymous_check = false;
access_checks.super_access = false;
access_checks.manager_access = false;
access_checks.administrator_access = false;
access_checks.support_access = false;
access_checks.assistant_access = false;
access_checks.trusted_access = false;
access_checks.verified_access = false;
access_checks.provisional_access = false;
access_checks.public_access = false;
access_checks.authenticated_access = true;
access_checks.anonymous_access = true;
} else {
access_checks.access_type = 'anonymous';
access_checks.super_check = false;
access_checks.manager_check = false;
access_checks.administrator_check = false;
access_checks.support_check = false;
access_checks.assistant_check = false;
access_checks.trusted_check = false;
access_checks.verified_check = false;
access_checks.provisional_check = false;
access_checks.public_check = false;
access_checks.authenticated_check = false;
access_checks.anonymous_check = true;
access_checks.super_access = false;
access_checks.manager_access = false;
access_checks.administrator_access = false;
access_checks.support_access = false;
access_checks.assistant_access = false;
access_checks.trusted_access = false;
access_checks.verified_access = false;
access_checks.provisional_access = false;
access_checks.public_access = false;
access_checks.authenticated_access = false;
access_checks.anonymous_access = true;
}
return access_checks;
}
export let ae_util = {
iso_datetime_formatter: iso_datetime_formatter,
extract_prefixed_form_data: extract_prefixed_form_data,
process_permission_checks: process_permission_checks,
};
// export default ae_util;

View File

@@ -0,0 +1,291 @@
<script lang="ts">
import { createEventDispatcher, onMount, tick } from 'svelte';
import { ae_util } from '$lib/ae_utils';
import { ae_loc, ae_sess, ae_api, slct, slct_trigger } from '$lib/ae_stores';
let entered_passcode: null|string = null;
let show_passcode_input: boolean = false;
let trigger: null|string = null;
const dispatch = createEventDispatcher();
onMount(() => {
console.log('** Element Mounted: ** Element Access Type');
});
$: if (entered_passcode && entered_passcode.length >= 5) {
console.log(`entered_passcode=${entered_passcode}`);
handle_check_access_type_passcode();
}
$: if (trigger && $ae_loc.access_type) {
console.log(`$ae_loc.access_type=${$ae_loc.access_type}`);
let access_checks_results = ae_util.process_permission_checks($ae_loc.access_type);
$ae_loc = {...$ae_loc, ...access_checks_results};
} else if (trigger) {
console.log(`$ae_loc.access_type=not set`);
// Send an empty string to reset the permissions. This is the same as sending 'anonymous'.
let access_checks_results = ae_util.process_permission_checks('');
$ae_loc = {...$ae_loc, ...access_checks_results};
}
function handle_check_access_type_passcode() {
// console.log('*** handle_check_access_type_passcode() ***');
if (entered_passcode && entered_passcode.length >= 5) {
if ($ae_loc.page_access_code_li.administrator == entered_passcode) {
console.log('Administrator passcode matched');
window.localStorage.setItem('access_type', 'administrator');
entered_passcode = null;
$ae_loc.access_type = 'administrator';
trigger = 'process_permission_check';
// $ae_loc = $ae_loc; // Trigger Svelte just in case
// ae_loc.set($ae_loc);
// console.log($ae_loc);
dispatch_access_type_changed();
return true;
} else if ($ae_loc.page_access_code_li.trusted == entered_passcode) {
console.log('Trusted passcode matched');
window.localStorage.setItem('access_type', 'trusted');
entered_passcode = null;
$ae_loc.access_type = 'trusted';
trigger = 'process_permission_check';
// $ae_loc = $ae_loc; // Trigger Svelte just in case
// ae_loc.set($ae_loc);
// console.log($ae_loc);
dispatch_access_type_changed();
return true;
} else if ($ae_loc.page_access_code_li.public == entered_passcode) {
console.log('Authenticated passcode matched');
window.localStorage.setItem('access_type', 'public');
entered_passcode = null;
$ae_loc.access_type = 'public';
trigger = 'process_permission_check';
dispatch_access_type_changed();
return true;
} else if ($ae_loc.page_access_code_li.authenticated == entered_passcode) {
console.log('Authenticated passcode matched');
window.localStorage.setItem('access_type', 'authenticated');
entered_passcode = null;
$ae_loc.access_type = 'authenticated';
trigger = 'process_permission_check';
dispatch_access_type_changed();
return true;
} else {
console.log('Passcode does not match');
window.localStorage.setItem('access_type', 'anonymous');
$ae_loc.access_type = 'anonymous';
trigger = 'process_permission_check';
// $ae_loc = $ae_loc; // Trigger Svelte just in case
// ae_loc.set($ae_loc);
// console.log($ae_loc);
dispatch_access_type_changed();
return false;
}
} else {
console.log('Entered passcode too short.');
// $ae_loc.access_type = null; // 'anonymous';
// dispatch_access_type_changed()
return null;
}
}
function handle_clear_access() {
// NOTE: I think it makes since to reset this to anonymous even if logged in as an admin or similar.
window.localStorage.setItem('access_type', 'anonymous');
// $ae_loc.access_type = null; // 'anonymous';
$ae_loc.access_type = 'anonymous';
trigger = 'process_permission_check';
show_passcode_input = false;
// $ae_loc = $ae_loc; // Trigger Svelte just in case
// ae_loc.set($ae_loc);
// console.log($ae_loc);
dispatch_access_type_changed();
return true;
}
function dispatch_access_type_changed() {
console.log('*** dispatch_access_type_changed() ***');
console.log(ae_util);
console.log($ae_loc);
dispatch('access_type_changed', {
access_type: $ae_loc.access_type
});
}
</script>
<section id="AE-Quick-Access-Type" class="access_type transition duration-300 delay-150 hover:delay-300 hover:transition-all hidden-print">
{#if $ae_loc.access_type && $ae_loc.access_type != 'anonymous'}
{#if $ae_loc.access_type == 'super'}
<span class="fas fa-unlock"></span> Super Access
{:else if $ae_loc.access_type == 'manager'}
<span class="fas fa-unlock"></span> Manager Access
{:else if $ae_loc.access_type == 'administrator'}
<span class="fas fa-unlock"></span> Administrator Access
{:else if $ae_loc.access_type == 'trusted'}
<span class="fas fa-unlock"></span> Trusted Access
{:else if $ae_loc.access_type == 'authenticated'}
<span class="fas fa-unlock"></span> Authenticated Access
{:else if $ae_loc.access_type == 'anonymous'}
<span class="fas fa-unlock"></span> Anonymous Access
{:else}
<span class="fas fa-unlock mx-1"></span> Unknown Access
{/if}
<button
class="btn btn-sm access_type_lock_btn hover:transition-all"
on:click={() => {
handle_clear_access();
}}
title="Access mode is currently enabled/unlocked. Click to exit and lock."
>
<span class="fas fa-lock mx-1"></span> Lock
</button>
{:else}
<button
class="btn btn-sm access_type_unlock_btn hover:transition-all"
on:click={async () => {
show_passcode_input = !show_passcode_input;
await tick();
document.getElementById('access_passcode_input').focus();
// element.focus({preventScroll:false});
}}
title="Anonymous public access is currently set. Access mode is disabled/locked."
>
<span class="fas fa-lock"></span>
<span class="unlock_text">Unlock?</span>
</button>
<input
id="access_passcode_input"
bind:value={entered_passcode}
class="input w-32 transition-all"
class:hidden={!show_passcode_input}
type="text"
placeholder="Access code"
/>
<!-- <div class="current_text transition-all">{$ae_loc.access_type}</div> -->
{/if}
</section>
<style lang="postcss">
/* BEGIN: AE's Svelte Quick Access Type component */
#AE-Quick-Access-Type {
/* position: absolute; */
position: fixed;
/* position: relative; */
/* position: static; */
/* position: sticky; */
/* top: 1em; */
bottom: 1.5rem;
right: 0rem;
padding: .5rem;
/* lightyellow */
/* background-color: hsla(60,100%,90%,.30); */
background-color: rgba(var(--color-surface-500) / .5);
border-top: solid thin black;
border-left: solid thin black;
border-bottom: solid thin black;
border-top-left-radius: .5em;
border-bottom-left-radius: .5em;
opacity: .50;
font-size: .75rem;
z-index: 5;
/* NOTE: transition when no longer hovering */
transition-property: opacity, background-color;
transition-delay: .1s;
transition-duration: .4s;
transition-timing-function: linear;
}
#AE-Quick-Access-Type:hover {
/* lightyellow */
/* background-color: hsla(60,100%,90%,.95); */
background-color: rgba(var(--color-surface-500) / 1);
opacity: 1;
/* NOTE: transition when hover starts */
transition-property: opacity, background-color;
/* transition-delay: .5s; */
transition-duration: .10s;
transition-timing-function: linear;
}
/* #Access-Type .unlock_text {
transition: width 2s, height 2s, background-color 2s, transform 2s;
} */
/* END: Svelte Access Type component */
.access_type_unlock_btn .unlock_text {
display: none;
}
.access_type_unlock_btn:hover .unlock_text {
display: initial;
/* outline: solid thin red; */
}
.access_type .current_text {
display: none;
}
.access_type:hover .current_text {
display: initial;
/* outline: solid thin red; */
}
</style>

View File

@@ -57,6 +57,8 @@ import { ae_loc, ae_sess, ae_api, slct, slct_trigger } from '$lib/ae_stores';
console.log($ae_loc, $ae_sess, $ae_api);
import Element_access_type from '$lib/element_access_type.svelte';
// const ae_loc_test_store: Writable<string> = localStorageStore('ae_loc_test', {'test': 'This is a test'});
// // Subscribe to the store
// ae_loc_test_store.subscribe(() => {});
@@ -74,13 +76,18 @@ console.log($ae_loc, $ae_sess, $ae_api);
// $ae_loc_test_store
let data_store_obj_get_promises: key_val = {};
let get_ds_hub_page_access_code_li_json_promise = handle_get_data_store_obj_w_code({code: 'hub__page__access_code_li_json', data_type: 'json', trigger: 'set_access_code_li'});
let get_ds_hub_site_header_promise = handle_get_data_store_obj_w_code({code: 'hub_site_header'});
let get_ds_hub_site_footer_promise = handle_get_data_store_obj_w_code({code: 'hub_site_footer'});
async function handle_get_data_store_obj_w_code({code, data_type='text'}) {
async function handle_get_data_store_obj_w_code({ code=null, data_type='text', trigger=null }) {
console.log(`*** handle_get_data_store_obj_w_code() *** code=${code}`);
if (!code) {
console.log('No code provided.');
return;
}
// let get_item_result = window.localStorage.getItem(code);
// localStorage.getItem(code);
@@ -109,6 +116,10 @@ async function handle_get_data_store_obj_w_code({code, data_type='text'}) {
// console.log(`Code: ${$ae_loc.hub.ds[code]}`);
// console.log(`Code:`, $ae_loc.hub.ds[code]);
if (trigger) {
$slct_trigger = trigger;
}
}
})
.catch(function (error) {
@@ -116,6 +127,15 @@ async function handle_get_data_store_obj_w_code({code, data_type='text'}) {
});
}
$: if ($slct_trigger == 'set_access_code_li' && $ae_loc.hub.ds['hub__page__access_code_li_json']) {
console.log(`$ae_loc.hub.ds['hub__page__access_code_li_json'] = `, $ae_loc.hub.ds['hub__page__access_code_li_json']);
$slct_trigger = null; // Reset the trigger to prevent loops
$ae_loc.page_access_code_li = $ae_loc.hub.ds['hub__page__access_code_li_json'];
$ae_loc = $ae_loc; // Trigger Svelte just in case
console.log($ae_loc);
}
</script>
@@ -143,6 +163,7 @@ async function handle_get_data_store_obj_w_code({code, data_type='text'}) {
<!-- App Shell -->
<AppShell>
<svelte:fragment slot="header">
<!-- App Bar -->
<AppBar gridColumns="grid-cols-3" slotDefault="place-self-center" slotTrail="place-content-end">
@@ -151,7 +172,8 @@ async function handle_get_data_store_obj_w_code({code, data_type='text'}) {
&AElig; Home
</a>
</svelte:fragment>
OSIT's Aether App
<!-- OSIT's Aether App -->
{@html $ae_loc.hub.ds['hub_site_header']}
<svelte:fragment slot="trail">
<!-- <a
class="btn btn-sm variant-ghost-surface"
@@ -169,6 +191,7 @@ async function handle_get_data_store_obj_w_code({code, data_type='text'}) {
</svelte:fragment>
</AppBar>
<!-- <AppBar>
<svelte:fragment slot="lead">
<strong class="text-xl uppercase">Skeleton</strong>
@@ -203,15 +226,22 @@ async function handle_get_data_store_obj_w_code({code, data_type='text'}) {
</svelte:fragment>
<!-- Page Route Content -->
<slot />
<svelte:fragment slot="footer">
<div class="flex justify-between space-x-2">
{@html $ae_loc.hub.ds['hub_site_footer']}
</div>
</svelte:fragment>
</AppShell>
<Element_access_type />
<style lang="postcss">
</style>

View File

@@ -25,7 +25,7 @@ let data_store_obj_get_promises: key_val = {};
let get_ds_hub_site_header_promise = handle_get_data_store_obj_w_code({code: 'hub_site_header'});
let get_ds_hub_site_footer_promise = handle_get_data_store_obj_w_code({code: 'hub_site_footer'});
async function handle_get_data_store_obj_w_code({code, data_type='text'}) {
async function handle_get_data_store_obj_w_code({code}: {code: string}, data_type='text') {
console.log('*** handle_get_data_store_obj_w_code() ***');
// let get_item_result = window.localStorage.getItem(code);

View File

@@ -79,10 +79,10 @@ onMount(() => {
// console.log(`$ae_loc = `, $ae_loc);
let href_url = window.location.href;
console.log(href_url);
// console.log(href_url);
$ae_loc.href_url = href_url;
console.log(`$ae_loc.href_url = `, $ae_loc.href_url);
// console.log(`$ae_loc.href_url = `, $ae_loc.href_url);
});
@@ -205,7 +205,7 @@ async function handle_load_ae_obj_li__sponsorship({account_id, try_cache=true})
})
.finally(function () {
$ae_loc.mod.sponsorships.qry_status = 'done';
console.log('Sponsorship list:', $slct.sponsorship_obj_li);
// console.log('Sponsorship list:', $slct.sponsorship_obj_li);
});
return ae_sponsorship_obj_li_get_promise;
@@ -213,7 +213,12 @@ async function handle_load_ae_obj_li__sponsorship({account_id, try_cache=true})
// Load the Sponsorship Cfg Obj with ID based on the URL param.
$slct.sponsorship_cfg_id = data.url.searchParams.get('sponsorship_cfg_id');
if (data.url.searchParams.get('sponsorship_cfg_id')) {
$slct.sponsorship_cfg_id = data.url.searchParams.get('sponsorship_cfg_id');
$slct_trigger = 'load__sponsorship_cfg_obj';
} else {
$slct.sponsorship_cfg_id = $ae_loc.mod.sponsorships.cfg_id;
}
$slct_trigger = 'load__sponsorship_cfg_obj';
$: if ($slct_trigger == 'load__sponsorship_cfg_obj' && $slct.sponsorship_cfg_id) {

View File

@@ -4,11 +4,24 @@ import { createEventDispatcher, onMount } from 'svelte';
// const dispatch = createEventDispatcher();
// This works and uses local storage:
// store_current_tab must be prefixed with $ to be reactive.
import { clipboard, localStorageStore, ProgressRadial } from '@skeletonlabs/skeleton';
import type { Writable } from 'svelte/store';
// const store_current_tab: Writable<string> = localStorageStore('store_current_tab', 'start');
let store_current_tab: string = 'start';
// console.log(`store_current_tab:`, $store_current_tab);
const store_current_tab: Writable<string> = localStorageStore('store_current_tab', 'start');
console.log(`store_current_tab:`, $store_current_tab);
// This works, but does not uses local storage:
// store_current_tab is not reactive and should not be prefixed with $.
// let store_current_tab: string = 'start';
// console.log(`store_current_tab:`, store_current_tab);
// This does not work:
// let tab_set = $store_current_tab;
// let tab_set = store_current_tab;
// Stores
import { getModalStore, FileDropzone, TabGroup, Tab, TabAnchor } from '@skeletonlabs/skeleton';
@@ -54,7 +67,8 @@ onMount(() => {
// }
// Base Classes
const cBase = 'card p-4 w-modal-wide shadow-xl space-y-4 ae_modal_scrollfix';
const cBase = 'card p-4 shadow-xl space-y-4 ae_modal_scrollfix';
// w-modal-wide
// const cBase = 'bg-surface-100-800-token w-screen h-screen';
// const cBase = 'card h-screen';
// const cBase = 'card p-4 w-modal-wide h-screen shadow-xl space-y-4';
@@ -63,8 +77,6 @@ const cHeader = 'text-2xl font-bold';
const cForm = 'border border-surface-500 p-4 space-y-4 rounded-container-token';
// let tab_set = $store_current_tab;
let tab_set = store_current_tab;
$ae_loc.mod.sponsorships.disable_submit__sponsorship_obj = false;
let placeholder_li: key_val = {
@@ -78,7 +90,7 @@ let ae_promises: key_val = {};
if ($slct.sponsorship_id) {
console.log(`Sponsorship ID selected: ${$slct.sponsorship_id}`);
console.log(`Sponsorship Object selected: ${$slct.sponsorship_obj}`)
console.log(`Sponsorship object selected:`, $slct.sponsorship_obj);
// $slct_trigger = 'load__sponsorship_obj';
@@ -158,22 +170,21 @@ async function handle_submit_form(event) {
};
}
if (sponsorship_di.name) {
sponsorship_do['name'] = sponsorship_di.name;
}
if (sponsorship_di.description) {
sponsorship_do['description'] = sponsorship_di.description;
if (sponsorship_di.organization_name) {
// Using the organization_name field to store the name of the sponsorship.
sponsorship_do['name'] = sponsorship_di.organization_name;
}
// if (sponsorship_di.description) {
// sponsorship_do['description'] = sponsorship_di.description;
// }
if (sponsorship_di.level_num) {
sponsorship_do['level_num'] = Number(sponsorship_di.level_num);
let level_num = sponsorship_do['level_num'];
if (sponsorship_do['level_num'] == 1) {
sponsorship_do['level_str'] = 'Lowest Level Sponsorship ($5,000)';
} else if (sponsorship_do['level_num'] == 2) {
sponsorship_do['level_str'] = 'Mid-level Sponsor ($7,500)';
} else if (sponsorship_do['level_num'] == 3) {
sponsorship_do['level_str'] = 'High Level Sponsor ($15,000)';
if ($slct.sponsorship_cfg_obj.level_li_json) {
let level_str = `${$slct.sponsorship_cfg_obj.level_li_json[level_num].name} - ${$slct.sponsorship_cfg_obj.level_li_json[level_num].amount}`;
sponsorship_do['level_str'] = level_str;
}
}
@@ -453,8 +464,6 @@ async function handle_update__sponsorship({
<header class={cHeader}>
{$modalStore[0].title ?? '-- No Title --'}
{#await ae_promises.update__sponsorship_obj}
<div class="modal-loading">
<span class="fas fa-spinner fa-spin"></span>
@@ -478,6 +487,7 @@ async function handle_update__sponsorship({
{/await}
</header>
{#if $ae_loc.mod.sponsorships.link}
<div class="flex justify-end">
<button
@@ -490,6 +500,7 @@ async function handle_update__sponsorship({
</div>
{/if}
<TabGroup
justify="justify-center"
active="variant-ghost-primary"
@@ -499,19 +510,19 @@ async function handle_update__sponsorship({
border=""
class="bg-surface-100-800-token w-full"
>
<Tab bind:group={store_current_tab} name="tab_start" value={'start'}>
<Tab bind:group={$store_current_tab} name="tab_start" value={'start'}>
<svelte:fragment slot="lead"><span class="fas fa-home"></span></svelte:fragment>
<span>Start</span>
</Tab>
<Tab bind:group={store_current_tab} name="tab_files" value={'files'} disabled={!$slct.sponsorship_obj.sponsorship_id_random}>
<Tab bind:group={$store_current_tab} name="tab_files" value={'files'} disabled={!$slct.sponsorship_obj.sponsorship_id_random}>
<svelte:fragment slot="lead"><span class="fas fa-file-upload"></span></svelte:fragment>
Files
</Tab>
<Tab bind:group={store_current_tab} name="tab_gala_guests" value={'gala_guests'} disabled={!$slct.sponsorship_obj.sponsorship_id_random}>
<Tab bind:group={$store_current_tab} name="tab_gala_guests" value={'gala_guests'} disabled={!$slct.sponsorship_obj.sponsorship_id_random}>
<svelte:fragment slot="lead"><span class="fas fa-users"></span></svelte:fragment>
Gala Guests
</Tab>
<Tab bind:group={store_current_tab} name="tab_options" value={'options'} disabled={!$slct.sponsorship_obj.sponsorship_id_random}>
<Tab bind:group={$store_current_tab} name="tab_options" value={'options'} disabled={!$slct.sponsorship_obj.sponsorship_id_random}>
<svelte:fragment slot="lead"><span class="fas fa-info"></span></svelte:fragment>
More
</Tab>
@@ -520,116 +531,311 @@ async function handle_update__sponsorship({
<svelte:fragment slot="panel">
{#if store_current_tab === 'start'}
{#if $store_current_tab === 'start'}
<form
class="modal-form {cForm}"
on:submit|preventDefault={handle_submit_form}
>
<section class="ae_section sponsorship__contacts border border-gray-500/20 p-4">
<fieldset class="sponsorship__poc_person flex flex-wrap gap-4">
<legend class="legend">Point of Contact</legend>
<!-- <section class="ae_section sponsorship__contacts border border-gray-500/20 p-4"> -->
<fieldset class="mb-8">
<legend class="legend">General Information</legend>
<label for="poc_full_name">Full name
<div class="input-group grid-cols-[auto_1fr_auto]">
<div class="input-group-shim">
{#if !$ae_loc.trusted_access && $slct.sponsorship_obj.sposorship_id_random}
<span class="fas fa-lock" title="Field is locked"></span>
{:else}
<span class="fas fa-unlock" title="Field is unlocked"></span>
{/if}
</div>
<input
type="text"
class="input"
id="poc_full_name" name="poc_full_name"
placeholder="Full name"
value={($slct.sponsorship_obj.poc_json && $slct.sponsorship_obj.poc_json.full_name ? $slct.sponsorship_obj.poc_json.full_name : '')}
autocomplete="name"
readonly={!$ae_loc.trusted_access && $slct.sponsorship_obj.sposorship_id_random}
required
>
</div>
</label>
<label for="poc_email">Email
<div class="input-group grid-cols-[auto_1fr_auto]">
<div class="input-group-shim">
{#if !$ae_loc.trusted_access && $slct.sponsorship_obj.sposorship_id_random}
<span class="fas fa-lock" title="Field is locked"></span>
{:else}
<span class="fas fa-unlock" title="Field is unlocked"></span>
{/if}
</div>
<input
type="email"
class="input"
id="poc_email"
name="poc_email"
placeholder="Email"
value={($slct.sponsorship_obj.poc_json && $slct.sponsorship_obj.poc_json.email ? $slct.sponsorship_obj.poc_json.email : '')}
autocomplete="email"
readonly={!$ae_loc.trusted_access && $slct.sponsorship_obj.sposorship_id_random}
required
>
</div>
<label for="organization_name" class="label">Name of organization/company
<input type="text" id="organization_name" name="organization_name" required max="200" value={$slct.sponsorship_obj.organization_name ?? ''} placeholder="Name of organization/company" autocomplete="off" class="input" />
</label>
<label for="poc_phone_mobile">Mobile phone
<input
type="tel"
class="input"
id="poc_phone_mobile"
name="poc_phone_mobile"
placeholder="Mobile phone"
value={($slct.sponsorship_obj.poc_json && $slct.sponsorship_obj.poc_json.phone_mobile ? $slct.sponsorship_obj.poc_json.phone_mobile : '')}
autocomplete="tel"
>
</label>
</fieldset>
</section>
<section class="ae_section sponsorship__general_information">
<label for="name" class="label">Name of Sponsorship
<input type="text" id="name" name="name" required max="200" value={$slct.sponsorship_obj.name ?? ''} placeholder="Name of Sponsorship" autocomplete="off" class="input" />
</label>
<label class="label ae_label sponsorship__description">Short description
<!-- <label class="label ae_label sponsorship__description">Short description
<textarea name="description" id="description" class="textarea ae_value sponsorship__description tinymce_editor editor_basic" rows="5" cols="70" bind:value={$slct.sponsorship_obj.description} placeholder="A short description or overview of this sponsorship."></textarea>
</label> -->
<!-- Collect the organization mailing address -->
<fieldset class="mb-8 flex flex-wrap gap-4">
<legend class="legend">Mailing Address</legend>
<label for="address_line_1" class="label max-w-64">
<!-- Line 1 (Street) -->
<input type="text" id="address_line_1" name="address_line_1" value={$slct.sponsorship_obj.address_street ?? ''} placeholder="Line 1 (street)" autocomplete="street-address" class="input text-xs" />
</label>
<label for="address_line_2" class="label max-w-64">
<!-- Line 2 (Suite) -->
<input type="text" id="address_line_2" name="address_line_2" value={$slct.sponsorship_obj.address_suite ?? ''} placeholder="Line 2 (suite)" autocomplete="address-line2" class="input text-xs" />
</label>
<label for="address_city" class="label max-w-64">
<!-- City -->
<input type="text" id="address_city" name="address_city" value={$slct.sponsorship_obj.address_city ?? ''} placeholder="City" autocomplete="address-level2" class="input text-xs" />
</label>
<label for="address_state" class="label max-w-64">
<!-- State/Province -->
<input type="text" id="address_state_province" name="address_state_province" value={$slct.sponsorship_obj.address_state_province ?? ''} placeholder="State/Province" autocomplete="address-level1" class="input text-xs" />
</label>
<label for="address_postal_code" class="label max-w-64">
<!-- Postal code/Zip -->
<input type="text" id="address_postal_code" name="address_postal_code" value={$slct.sponsorship_obj.address_postal_code ?? ''} placeholder="Postal code/Zip" autocomplete="postal-code" class="input text-xs" />
</label>
<label for="address_country" class="label max-w-64">
<!-- Country -->
<input type="text" id="address_country" name="address_country" value={$slct.sponsorship_obj.address_country ?? ''} placeholder="Country" autocomplete="country-name" class="input text-xs" />
</label>
</fieldset>
<fieldset class="mb-8 flex flex-wrap gap-4">
<legend class="legend">Point of Contact</legend>
<label for="poc_full_name">Full name
<div class="input-group grid-cols-[auto_1fr_auto]">
<div class="input-group-shim">
{#if !$ae_loc.trusted_access && $slct.sponsorship_obj.sposorship_id_random}
<span class="fas fa-lock" title="Field is locked"></span>
{:else}
<span class="fas fa-unlock" title="Field is unlocked"></span>
{/if}
</div>
<input
type="text"
class="input"
id="poc_full_name" name="poc_full_name"
placeholder="Full name"
value={($slct.sponsorship_obj.poc_json && $slct.sponsorship_obj.poc_json.full_name ? $slct.sponsorship_obj.poc_json.full_name : '')}
autocomplete="name"
readonly={!$ae_loc.trusted_access && $slct.sponsorship_obj.sposorship_id_random}
required
>
</div>
</label>
<label for="poc_email">Email
<div class="input-group grid-cols-[auto_1fr_auto]">
<div class="input-group-shim">
{#if !$ae_loc.trusted_access && $slct.sponsorship_obj.sposorship_id_random}
<span class="fas fa-lock" title="Field is locked"></span>
{:else}
<span class="fas fa-unlock" title="Field is unlocked"></span>
{/if}
</div>
<input
type="email"
class="input"
id="poc_email"
name="poc_email"
placeholder="Email"
value={($slct.sponsorship_obj.poc_json && $slct.sponsorship_obj.poc_json.email ? $slct.sponsorship_obj.poc_json.email : '')}
autocomplete="email"
readonly={!$ae_loc.trusted_access && $slct.sponsorship_obj.sposorship_id_random}
required
>
</div>
</label>
<label class="label">Level of sponsorship?
<!-- {$slct.sponsorship_cfg_obj.level_li_json[1].name} -->
<!-- {#if $slct.sponsorship_cfg_obj && $slct.sponsorship_cfg_obj.level_li_json}
{$slct.sponsorship_cfg_obj.level_li_json[0]}
{#each $slct.sponsorship_cfg_obj.level_li_json as level, index}
<div class="flex gap-4">
<input
type="radio"
id="level_num_{index}"
name="level_num"
value={index + 1}
checked={($slct.sponsorship_obj.level_num == index + 1 ? 'checked' : '')}
>
<label for="level_num_{index}">{index + 1} &mdash; {level.name}</label>
</div>
{/each}
{/if} -->
<label for="poc_phone_mobile">Mobile phone
<input
type="tel"
class="input"
id="poc_phone_mobile"
name="poc_phone_mobile"
placeholder="Mobile phone"
value={($slct.sponsorship_obj.poc_json && $slct.sponsorship_obj.poc_json.phone_mobile ? $slct.sponsorship_obj.poc_json.phone_mobile : '')}
autocomplete="tel"
>
</label>
</fieldset>
<fieldset class="mb-8 flex flex-wrap gap-4">
<legend class="legend">Additional Contacts</legend>
{#if $slct.sponsorship_obj.contact_li_json && $slct.sponsorship_obj.contact_li_json.length}
{#each $slct.sponsorship_obj.contact_li_json as contact, index}
<fieldset class="border border-gray-500/20 p-4">
<legend class="legend">
Contact #{index + 1} -
{contact.full_name ?? ``}
</legend>
<div class="flex flex-wrap gap-2 p-1">
<label for="contact_{index}_full_name">
<!-- Full name -->
<input
type="text"
class="input text-xs"
id="contact_{index}_full_name"
name="contact_{index}_full_name"
placeholder="Full name"
value={contact.full_name ?? ``}
autocomplete="name"
>
</label>
<label for="contact_{index}_email">
<!-- Email -->
<input
type="email"
class="input text-xs"
id="contact_{index}_email"
name="contact_{index}_email"
placeholder="Email"
value={contact.email}
autocomplete="email"
>
</label>
<label for="contact_{index}_phone">
<!-- Phone -->
<input
type="tel"
class="input text-xs"
id="contact_{index}_phone"
name="contact_{index}_phone"
placeholder="Phone"
value={contact.phone}
autocomplete="tel"
>
</label>
</div>
<div class="flex flex-wrap gap-2 p-1">
<button
type="submit"
class="btn {parent.buttonPositive} btn-sm"
disabled={($ae_loc.mod.sponsorships.disable_submit__sponsorship_obj)}
on:click={() => {
console.log('*** Save button clicked ***');
}}
>
<span class="fas fa-check mx-1"></span>
Save
</button>
<button
class="btn {parent.buttonNegative} btn-sm"
on:click={(event) => {
console.log('*** Delete button clicked ***');
if (!confirm('Are you sure you want to delete this contact?')) {return false;}
$slct.sponsorship_obj.contact_li_json.splice(index, 1);
$slct = $slct;
// Now we are ready to submit the form
event.target.form.dispatchEvent(new Event('submit', {cancelable: true}));
}}
>
<span class="fas fa-minus mx-1"></span>
Delete
</button>
</div>
</fieldset>
{/each}
{:else}
<!-- <div class="ae_warning">No additional contacts found!</div> -->
{/if}
<button
class="btn {parent.buttonPositive} m-2"
on:click={() => {
console.log('*** Add contact button clicked ***');
// if (!confirm('Are you sure you want to add a contact?')) {return false;}
if (!$slct.sponsorship_obj.contact_li_json) {
$slct.sponsorship_obj.contact_li_json = [];
}
$slct.sponsorship_obj.contact_li_json.push({
full_name: null,
email: null,
phone: null,
});
}}
>
<span class="fas fa-plus mx-1"></span>
Add Contact
</button>
</fieldset>
<!-- </section> -->
<fieldset class="mb-8">
<legend class="legend">Additional Information</legend>
<!-- <label for="organization_name" class="label">Name of organization/company
<input type="text" id="organization_name" name="organization_name" required max="200" value={$slct.sponsorship_obj.organization_name ?? ''} placeholder="Name of organization/company" autocomplete="off" class="input" />
</label> -->
<!-- <label class="label ae_label sponsorship__description">Short description
<textarea name="description" id="description" class="textarea ae_value sponsorship__description tinymce_editor editor_basic" rows="5" cols="70" bind:value={$slct.sponsorship_obj.description} placeholder="A short description or overview of this sponsorship."></textarea>
</label> -->
<div class="label">
Level of sponsorship?
{#if $slct.sponsorship_cfg_obj}
<!--
Example JSON level_li_json:
{
"1": {
"name": "Friend",
"amount": 5000
},
"2": {
"name": "Supporter",
"amount": 7500
},
"3": {
"name": "Champion",
"amount": 12500
},
"4": {
"name": "Advocate",
"amount": 20000
},
"5": {
"name": "Presenting Partner",
"amount": 30000
},
"6": {
"name": "Signature Partner",
"amount": 50000
}
}
-->
{#if $slct.sponsorship_cfg_obj && $slct.sponsorship_cfg_obj.level_li_json}
<select
name="level_num"
class="select"
readonly={$slct.sponsorship_obj.paid}
>
{#each Object.entries($slct.sponsorship_cfg_obj.level_li_json) as [key, value]}
<option value={key} selected={($slct.sponsorship_obj.level_num == key ? 'selected' : '')}>{value.name} (${value.amount})</option>
{/each}
</select>
{/if}
{:else}
Not found?
{/if}
{#if $slct.sponsorship_obj.paid}
<span class="fas fa-check-circle"></span>
<span class="ae_value">Yes, marked as paid</span>
{:else}
<a href="https://example.com" class="btn variant-soft-primary m-2">
<span class="fas fa-credit-card mx-1"></span>
Go Pay Here
</a>
<span class="fas fa-times-circle"></span>
<span class="ae_value">Not yet marked as paid</span>
{/if}
<!-- <input name="level_num" value={$slct.sponsorship_obj.level_num} /> -->
<select name="level_num" class="select">
<!-- <select name="level_num" class="select">
<option value=1 selected={($slct.sponsorship_obj.level_num == 1 ? 'selected' : '')}>The Lowest Level Sponsorship ($5,000)</option>
<option value=2 selected={($slct.sponsorship_obj.level_num == 2 ? 'selected' : '')}>Mid-level Sponsor ($7,500)</option>
<option value=3 selected={($slct.sponsorship_obj.level_num == 3 ? 'selected' : '')}>High Level Sponsor ($15,000)</option>
</select>
</select> -->
<ul>
<!-- <ul>
<li><strong>Lowest Level</strong> - Thank you?</li>
<li><strong>Mid-level</strong> - Please join the gala along with 5 guests.</li>
<li><strong>High Level</strong> - Please join the gala along with 10 guests. You will also be able to upload a promo video that will play at the end of the gala.</li>
</ul>
</label>
</ul> -->
</div>
<label for="amount">Additional amount?
<label for="amount">Amount?
<div class="input-group grid-cols-[auto_1fr_auto]">
<div class="input-group-shim">
<span>$</span>
@@ -642,19 +848,47 @@ async function handle_update__sponsorship({
placeholder="Amount"
value={$slct.sponsorship_obj.amount ?? ''}
autocomplete="off"
readonly={$ae_loc.trusted_access}
readonly={$slct.sponsorship_obj.paid}
required
>
</div>
</label>
</section>
</fieldset>
<fieldset class="mb-8">
<legend class="legend">Agreements & Accommodations</legend>
<label for="waiver" class="label">
<input
type="checkbox"
class="checkbox"
id="waiver"
name="waiver"
value="1"
checked={$slct.sponsorship_obj.waiver}
>
Yes, I understand the "Sponsor General Waiver".
</label>
<label for="accommodations" class="label">
<input
type="checkbox"
class="checkbox"
id="accommodations"
name="accommodations"
value="1"
checked={$slct.sponsorship_obj.accommodations}
>
Yes, please have a member of the CHOW team reach out for special accommodations or assistance.
</label>
</fieldset>
<button
type="submit"
class="btn {parent.buttonPositive}"
class="btn {parent.buttonPositive} m-2"
disabled={($ae_loc.mod.sponsorships.disable_submit__sponsorship_obj)}
on:click={() => {
console.log('*** Save button clicked ***');
console.log('*** Save start button clicked ***');
// if (!confirm('Are you sure you want to save this sponsorship?')) {return false;}
// handle_submit_form();
// handle_submit_form;
@@ -667,7 +901,7 @@ async function handle_update__sponsorship({
</form>
{:else if store_current_tab === 'files'}
{:else if $store_current_tab === 'files'}
<form
@@ -776,7 +1010,7 @@ async function handle_update__sponsorship({
</form>
{:else if store_current_tab === 'gala_guests'}
{:else if $store_current_tab === 'gala_guests'}
<section class="gala_guests">
@@ -790,7 +1024,7 @@ async function handle_update__sponsorship({
<fieldset class="border border-gray-500/20 p-4">
<legend class="legend">
Guest #{index+1} -
{guest.full_name ?? `${guest.given_name} {guest.family_name}`}
{guest.full_name ?? `${guest.given_name} ${guest.family_name}`}
</legend>
<div class="flex flex-wrap gap-2 p-1">
<label for="guest_{index}_given_name" class="label max-w-64">
@@ -866,8 +1100,8 @@ async function handle_update__sponsorship({
<button
class="btn {parent.buttonPositive} m-2"
on:click={() => {
console.log('*** Add new guest button clicked ***');
// if (!confirm('Are you sure you want to add a new guest?')) {return false;}
console.log('*** Add guest button clicked ***');
// if (!confirm('Are you sure you want to add a guest?')) {return false;}
console.log($slct.sponsorship_obj.guest_li_json);
@@ -889,13 +1123,13 @@ async function handle_update__sponsorship({
}}
>
<span class="fas fa-plus mx-1"></span>
Add New Guest
Add Guest
</button>
</section>
{:else if store_current_tab === 'options'}
{:else if $store_current_tab === 'options'}
<form

View File

@@ -18,7 +18,7 @@ onMount(() => {
</script>
<section class="svelte_component ae_section ae_list list__sponsorship_obj sponsorship_obj_li {container_class_li.join(' ')}">
<section class="svelte_component ae_section ae_list list__sponsorship_obj sponsorship_obj_li {container_class_li.join(' ')} ae_h_scrollfix">
{#if $slct.sponsorship_obj_li}
<table class="table table-compact table-hover">
<thead>
@@ -67,7 +67,7 @@ onMount(() => {
View
</button>
{#if $ae_loc.administrator_access}
{#if $ae_loc.trusted_access}
<button
on:click={() => {
$slct.sponsorship_id = ae_sponsorship_obj.sponsorship_id_random;
@@ -140,8 +140,10 @@ onMount(() => {
</tbody>
<tfoot>
<tr>
<th colspan="7" class="">Total Count:</th>
<td>{$slct.sponsorship_obj_li.length}</td>
<th colspan="8" class="">
Total Count:
{$slct.sponsorship_obj_li.length}
</th>
</tr>
</tfoot>
</table>

View File

@@ -12,7 +12,7 @@ const dispatch = createEventDispatcher();
if ($slct.sponsorship_id) {
console.log(`Sponsorship ID selected: ${$slct.sponsorship_id}`);
console.log(`Sponsorship Object selected: ${$slct.sponsorship_obj}`)
console.log(`Sponsorship object selected:`, $slct.sponsorship_obj);
$slct_trigger = 'load__sponsorship_obj';
}

View File

@@ -17,7 +17,7 @@ export let parent: SvelteComponent;
if ($slct.sponsorship_id) {
console.log(`Sponsorship ID selected: ${$slct.sponsorship_id}`);
console.log(`Sponsorship Object selected: ${$slct.sponsorship_obj}`)
console.log(`Sponsorship object selected:`, $slct.sponsorship_obj);
$slct_trigger = 'load__sponsorship_obj';
}

View File

@@ -71,7 +71,7 @@ let ae_promises: key_val = {};
if ($slct.sponsorship_id && $slct.sponsorship_obj) {
console.log(`Sponsorship ID selected: ${$slct.sponsorship_id}`);
console.log(`Sponsorship Object selected: ${$slct.sponsorship_obj}`)
console.log(`Sponsorship object selected:`, $slct.sponsorship_obj);
// $slct_trigger = 'load__sponsorship_obj';
} else {

View File

@@ -9,7 +9,13 @@
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"moduleResolution": "bundler"
"moduleResolution": "bundler",
"plugins": [{
"name": "typescript-svelte-plugin",
// the following options can be set additionally; they are optional; their default values are listed here
"enabled": true, // enables this plugin
"assumeIsSvelteProject": false // if true, skip detection and always assume it's a Svelte project
}]
}
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
//