Files
OSIT-AE-App-Svelte/src/routes/events/[event_id]/+page.svelte
2025-07-23 13:31:30 -04:00

738 lines
27 KiB
Svelte
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script lang="ts">
interface Props {
/** @type {import('./$types').PageData} */
data: any;
log_lvl?: number;
}
let {
data,
log_lvl = 0
}: Props = $props();
// *** Import Svelte specific
import { browser } from '$app/environment';
// import { goto, invalidate, pushState, replaceState } from '$app/navigation';
import type { key_val } from '$lib/ae_stores';
import { ae_util } from '$lib/ae_utils/ae_utils';
// import Element_data_store from '$lib/element_data_store_v2.svelte';
// import Comp_event_session_obj_li from '../ae_comp__event_session_obj_li.svelte';
import Comp_event_session_obj_li_wrapper from '../ae_comp__event_session_obj_li_wrapper.svelte';
import { liveQuery } from "dexie";
// import { core_func } from '$lib/ae_core_functions';
import { db_events } from "$lib/ae_events/db_events";
import { ae_snip, ae_loc, ae_sess, ae_api, ae_trig, slct, slct_trigger } from '$lib/ae_stores';
import { events_loc, events_sess, events_slct, events_trigger } from '$lib/ae_events_stores';
import { events_func } from '$lib/ae_events_functions';
import Comp_event_files_upload from '../ae_comp__event_files_upload.svelte';
import Element_manage_event_file_li_wrap from '$lib/element_manage_event_file_li_direct.svelte';
import Event_page_menu from './event_page_menu.svelte';
// Quickly save the data passed from the parent(s) to the Svelte stores, localStorage, and other.
// $slct.account_id = data.account_id;
// console.log(`$slct.account_id = `, $slct.account_id);
let ae_acct = data[$slct.account_id];
if (log_lvl) {
console.log(`ae_acct = `, ae_acct);
}
if (log_lvl) {
console.log(`event_id layout A: ${data.params.event_id}`);
console.log(`event_id layout B: ${ae_acct.slct.event_id}`);
console.log(`event_id layout C: ${$events_slct.event_id}`);
}
let event_id = data.params.event_id;
$events_slct.event_id = ae_acct.slct.event_id;
// $events_slct.event_device_id = null;
// $events_slct.event_location_id = null;
// $events_slct.event_session_id = null;
let lq__event_obj = $derived(liveQuery(async () => {
if (log_lvl) {
console.log(`*** LiveQuery: lq__event_obj *** event_id=${$events_slct.event_id}`);
}
let results = await db_events.events
.get($events_slct?.event_id ?? '');
return results;
}));
// JSON formatted configuration options for an event, and specifically for the presentation management module.
$effect(() => {
if ($lq__event_obj?.mod_pres_mgmt_json) {
// if (log_lvl) {
// console.log(`*** Event Pres Mgmt JSON *** pres_mgmt_cfg_local`, $events_loc.pres_mgmt);
// }
// $events_loc.pres_mgmt =
events_func.sync_config__event_pres_mgmt({
pres_mgmt_cfg_remote: $lq__event_obj.mod_pres_mgmt_json,
pres_mgmt_cfg_local: $events_loc.pres_mgmt,
log_lvl: log_lvl,
});
}
});
let event_session_id_random_li: Array<string> = $state([]);
// OMG THIS WORKS!!! 2024-09-17
// Using the $: seems to have fixed it along with the async await?
// let lq__event_session_obj_li = $derived(liveQuery(async () => {
// // console.log(`*** LiveQuery: lq__event_session_obj_li *** event_session_id_random_li`, $state.snapshot(event_session_id_random_li));
// // if (!event_session_id_random_li) {
// // // return [];
// // return;
// // }
// if (event_session_id_random_li.length) {
// console.log(`*** LiveQuery: lq__event_session_obj_li *** time to bulkGet`, $state.snapshot(event_session_id_random_li));
// let results = await db_events.sessions
// .bulkGet(event_session_id_random_li);
// return results;
// } else {
// let results = await db_events.sessions
// .where('event_id')
// .equals($events_slct?.event_id ?? '') // null or undefined does not reset things like '' does
// .reverse()
// .sortBy('name');
// return results;
// }
// }));
let lq__event_location_obj_li = $derived(liveQuery(async () => {
let results = await db_events.locations
.where('event_id')
.equals($events_slct.event_id)
.sortBy('name')
;
return results;
}));
// let load_obj_li_results: Promise<any>|key_val;
let search_submit_results: Promise<any>|key_val;
let ae_tmp: key_val = {};
let ae_triggers: key_val = {};
if ($events_loc.pres_mgmt?.save_search_text && $events_loc.pres_mgmt?.saved_search__session) {
$events_sess.pres_mgmt.fulltext_search_qry_str = $events_loc.pres_mgmt.saved_search__session;
}
if ($events_loc.pres_mgmt?.save_search_text && $events_loc.pres_mgmt?.saved_search__session_location_name) {
$events_sess.pres_mgmt.location_name_qry_str = $events_loc.pres_mgmt.saved_search__session_location_name;
}
// *** Functions and Logic
if (browser) {
// console.log('Events Event [event_id]: +page.svelte');
$events_trigger = 'load__event_session_obj_li';
}
function preventDefault(fn) {
return function (event) {
event.preventDefault();
fn.call(this, event);
};
}
// Updated 2024-06-12 late
$effect(() => {
if ($events_trigger == 'load__event_session_obj_li' && $events_slct.event_id) {
console.log(`load__event_session_obj_li() $events_slct.event_id=${$events_slct.event_id}`);
$events_trigger = null;
if ($events_loc.pres_mgmt.save_search_text) {
if (log_lvl) {
console.log(`*** Save search text *** ${$events_loc.pres_mgmt.save_search_text}`);
}
$events_loc.pres_mgmt.saved_search__session = $events_sess.pres_mgmt.fulltext_search_qry_str;
$events_loc.pres_mgmt.saved_search__session_location_name = $events_sess.pres_mgmt.location_name_qry_str;
}
if ( $events_sess.pres_mgmt.fulltext_search_qry_str?.length > 2 ) {
console.log('*** Search string is valid ***');
process_search_string($events_sess.pres_mgmt.fulltext_search_qry_str);
} else if ( $ae_loc.authenticated_access ) {
console.log('*** Administrator Access or Trusted Access ***');
process_search_string($events_sess.pres_mgmt.fulltext_search_qry_str);
} else {
console.log('*** Check permissions and or search string. Not allowed or too short. ***');
$events_slct.event_session_obj_li = [];
event_session_id_random_li = [];
}
}
// if ($events_sess.pres_mgmt.status_qry__search == 'done' && $events_slct?.event_session_obj_li) {
if ($events_trigger == 'search_done') {
$events_trigger = null;
$events_sess.pres_mgmt.status_qry__search = null;
if (log_lvl) {
console.log('TEST SEARCH - Search done. Pulling out the event_session_id_randoms...');
}
// We need to loop through the array of objects and get the event_session_id_random from each object a new list of event_session_id_randoms. Then we can use this list to get the full objects from the database.
let tmp_li = []; // This is to prevent the array from constantly updating and triggering the liveQuery.
if ($events_slct.event_session_obj_li && $events_slct.event_session_obj_li.length) {
event_session_id_random_li = [];
// console.log(`TEST SEARCH - Get ids:`, $events_slct.event_session_obj_li);
for (let i = 0; i < $events_slct.event_session_obj_li.length; i++) {
tmp_li.push($events_slct.event_session_obj_li[i].event_session_id_random);
}
}
event_session_id_random_li = tmp_li;
// console.log(`TEST search: event_session_id_random_li`, $state.snapshot(event_session_id_random_li));
}
});
function process_search_string(search_str: string) {
if (log_lvl) {
console.log(`process_search_string() search_str=${search_str}`);
}
if (search_str?.length) {
// console.log(`*** Search string length: ${search_str.length} ***`);
} else {
// console.log(`*** Search string is empty ***`);
}
// let type_code = $events_sess.pres_mgmt.search_badge_type_code;
// let search_str = $events_sess.pres_mgmt.fulltext_search_qry_str.trim();
let search_method = 'lk'; // 'ft', 'lk', 'eq'
let ft_search_str_new = '';
let lk_search_str_new = '';
if (search_method == 'ft') {
// Add quotes around the search string to make it an exact match.
ft_search_str_new = `${search_str}`;
// ft_search_str_new = `"${search_str}"`;
} else if (search_method == 'lk') {
if (search_str == null) {
search_str = '';
}
// Add a wildcard to the search string to make it a like match.
lk_search_str_new = search_str.trim().replace(',', ' ').replace(';', ' ').replaceAll(' ', '%').replaceAll(' ', '%');
lk_search_str_new = `%${lk_search_str_new}%`;
}
if (log_lvl) {
// console.log(`*** Search method: ${search_method} ***`);
console.log(`*** Search string: ${search_str} ***`);
// console.log(`*** Fulltext search string: ${ft_search_str_new} ***`);
// console.log(`*** Like search string: ${lk_search_str_new} ***`);
}
let location_name = '';
if ($events_sess.pres_mgmt.location_name_qry_str?.length) {
location_name = $events_sess.pres_mgmt.location_name_qry_str;
console.log(`Location name: ${location_name}`);
}
handle_search__event_session({
ft_search_str: ft_search_str_new,
lk_search_str: lk_search_str_new,
and_lk_location_name: location_name,
// fulltext_search_qry_str: ft_search_str_new,
// ft_presenter_search_qry_str: null,
// like_search_qry_str: lk_search_str_new,
// like_presentation_search_qry_str: lk_search_str_new,
// like_presenter_search_qry_str: lk_search_str_new,
// params: params,
try_cache: true,
log_lvl: log_lvl,
});
}
async function handle_search__event_session(
{
ft_search_str = '',
lk_search_str = '',
and_lk_location_name = '',
search_delay = 0,
max_tries = 5,
params = {
'qry__enabled': $events_loc.pres_mgmt.qry_enabled ?? 'enabled',
'qry__hidden': $events_loc.pres_mgmt.qry_hidden ?? 'not_hidden',
'qry__limit': $events_loc.pres_mgmt.qry_limit__sessions ?? 35,
},
try_cache = true,
log_lvl = 0,
}: {
ft_search_str?: string,
lk_search_str?: string,
and_lk_location_name?: string,
search_delay?: number, // In milliseconds
max_tries?: number,
params?: key_val,
try_cache?: boolean,
log_lvl?: number,
}
) {
if (log_lvl) {
console.log('handle_search__event_session()');
}
if ($events_sess.pres_mgmt?.status_qry__search != null && $events_sess.pres_mgmt?.status_qry__search != 'done') {
// console.log('*** TEST SEARCH - $events_sess.pres_mgmt.status_qry__search != done ***');
// WARNING: This is a temporary fix for the search string. It needs to be fixed in the future. Using lk_search_str for now.
$events_sess.pres_mgmt.status_qry__last_request_str = lk_search_str;
// We want to delay the initial search request to give the previous search request to finish.
let random_delay = Math.floor(Math.random() * 50);
search_delay += 50+random_delay;
}
// log_lvl = 1;
let count = 0;
let request_loop = setInterval(() => {
count++;
if (log_lvl) {
console.log(`*** TEST SEARCH - Search delay: ${search_delay} *** loop count=${count}`);
}
if (count >= max_tries) {
console.log('*** TEST SEARCH - Max tries reached ***');
clearInterval(request_loop);
}
if ($events_sess.pres_mgmt?.status_qry__search != null && $events_sess.pres_mgmt?.status_qry__search != 'done') {
let random_delay = Math.floor(Math.random() * 25);
search_delay += 25+random_delay;
console.log(`*** TEST SEARCH - $events_sess.pres_mgmt.status_qry__search == loading wait *** search_delay=${search_delay}`);
// $events_sess.status_qry__last_request_str = lk_search_str;
} else {
// console.log('*** TEST SEARCH - $events_sess.pres_mgmt.status_qry__search != loading ***');
$events_trigger = 'loading_search_results';
$events_sess.pres_mgmt.status_qry__search = 'loading';
event_session_id_random_li = []; // Resetting this seems to help trigger the new results to show correctly???
search_submit_results = events_func.search__event_session({
api_cfg: $ae_api,
event_id: $events_slct.event_id,
// type_code: type_code,
fulltext_search_qry_str: ft_search_str,
ft_presenter_search_qry_str: null,
like_search_qry_str: lk_search_str,
like_presentation_search_qry_str: lk_search_str,
like_presenter_search_qry_str: lk_search_str,
like_poc_name_qry_str: lk_search_str,
// external_event_id: $events_loc.pres_mgmt.default__external_registration_id,
location_name: and_lk_location_name,
params: params,
try_cache: try_cache,
log_lvl: log_lvl,
})
.then(function (search_results) {
// Processing the results from the search.
$events_trigger = 'process_search_results';
$events_sess.pres_mgmt.status_qry__search = 'processing';
$events_slct.event_session_obj_li = search_results;
// console.log(search_results);
// $events_sess.pres_mgmt.status_qry__search = 'done';
// if (log_lvl) {
// console.log('TEST SEARCH - Search done. Pulling out the event_session_id_randoms...');
// }
// console.log(`TEST search: ${$lq_kv__event_session_obj_li}`);
// event_session_id_random_li = [];
// // We need to loop through the array of objects and get the event_session_id_random from each object a new list of event_session_id_randoms. Then we can use this list to get the full objects from the database.
// let tmp_li = []; // This is to prevent the array from constantly updating and triggering the liveQuery.
// if (search_results && search_results.length) {
// for (let i = 0; i < search_results.length; i++) {
// tmp_li.push($events_slct.event_session_obj_li[i].event_session_id_random);
// }
// }
// event_session_id_random_li = tmp_li;
})
.finally(() => {
// event_session_id_random_li = $events_slct.event_session_obj_li.map(session_obj => session_obj.event_session_id_random);
// Finally done with the search.
$events_trigger = 'search_done';
$events_sess.pres_mgmt.status_qry__search = 'done';
// if (log_lvl > 1) {
// console.log(`TEST SEARCH - event_session_id_random_li:`, event_session_id_random_li);
// // console.log(`TEST SEARCH - search live query: ${$lq_kv__event_session_obj_li}`);
// }
});
clearInterval(request_loop);
}
}, search_delay);
}
</script>
<svelte:head>
<title>
Event: {ae_util.shorten_string({string: $lq__event_obj?.name, max_length: 12})}
({$lq__event_obj?.event_id}) - Pres Mgmt - {$events_loc?.title}
</title>
</svelte:head>
<!-- container h-full mx-auto
flex flex-col gap-1
py-1 px-2 pb-16
items-center
min-w-full
max-w-max -->
<section
class="
ae_events_pres_mgmt_event
md:container
flex flex-col gap-1
items-center
justify-start
mx-auto
py-1 px-2 pb-16
h-full
min-w-full
max-w-max
"
>
<!-- lg:bg-green-100
xl:bg-green-200 -->
<Event_page_menu
data={data}
lq__event_obj={lq__event_obj}
/>
{#if !$lq__event_obj}
<div>
<span class="fas fa-spinner fa-spin mx-1"></span>
<span>Loading event information...</span>
</div>
{:else if $lq__event_obj?.enable || $ae_loc.trusted_access}
<!-- <header> -->
<h2 class="ae_module_header h3">
<span
class="flex flex-row gap-1 items-center"
>
<span class="fas fa-calendar-day m-1 text-neutral-800/80"></span>
<!-- Button to toggle between the regular event view and managing event files -->
<button
type="button"
onclick={() => {
if ($events_loc.pres_mgmt.show_content__event_view == 'manage_files') {
$events_loc.pres_mgmt.show_content__event_view = null;
} else {
$events_loc.pres_mgmt.show_content__event_view = 'manage_files';
}
}}
class="btn ae_btn_secondary"
class:preset-filled-secondary-500={$events_loc.pres_mgmt.show_content__event_view == 'manage_files'}
class:preset-filled-tertiary-500={$events_loc.pres_mgmt.show_content__event_view != 'manage_files'}
class:hidden={!$ae_loc.administrator_access}
title="View event search or manage files for the event"
>
{#if $events_loc.pres_mgmt.show_content__event_view == 'manage_files'}
<!-- <span class="fas fa-info m-1"></span> -->
<span class="fas fa-search m-1"></span>
Event Search?
{:else}
<span class="fas fa-file-archive m-1"></span>
Event Files?
<span
class="badge preset-tonal-success"
class:hidden={!$lq__event_obj?.file_count}
>
<!-- absolute -top-1.5 -right-1.5 z-10 -->
<span class="fas fa-file-alt m-1"></span>
{$lq__event_obj?.file_count}×
</span>
{/if}
</button>
</span>
<span class="sm:inline-block md:hidden">
{$lq__event_obj.cfg_json?.short_name ?? $lq__event_obj?.name}
</span>
<span class="hidden md:inline-block lg:hidden">
{$lq__event_obj.cfg_json?.med_name ?? $lq__event_obj?.name}
</span>
<span class="hidden lg:inline-block">
{$lq__event_obj.cfg_json?.long_name ?? $lq__event_obj?.name}
</span>
</h2>
<!-- <h3 class="h4 text-center">Presentations - Session Lookup</h3> -->
<!-- </header> -->
{#if !$events_loc.pres_mgmt.show_content__event_view || $events_loc.pres_mgmt.show_content__event_view == 'default'}
<!-- This session search section should be moved to a separate Svelte component -->
<div class="ae_container_actions">
<form
onsubmit={preventDefault(() => {
$events_trigger = 'load__event_session_obj_li';
})}
autocomplete="off"
class="form grow flex flex-row flex-wrap gap-1 justify-center items-center w-full"
>
<!-- Show/Hide session location name search button -->
<button
type="button"
class="btn btn-sm mx-1 ae_btn_warning"
class:hidden={!$ae_loc.authenticated_access}
onclick={() => {
$events_sess.pres_mgmt.location_name_qry_str = '';
$events_loc.pres_mgmt.show_content__session_search_room_name = !$events_loc.pres_mgmt.show_content__session_search_room_name;
}}
title="Search by location name"
>
<span class="fas fa-search-location"></span>
<span class="hidden">Search on location</span>
</button>
<select
name="location_name_list"
id="session_location_name_list"
bind:value={$events_sess.pres_mgmt.location_name_qry_str}
class="input text-xs font-bold font-mono min-w-fit w-min max-w-40 transition-all mx-1"
class:hidden={!$ae_loc.authenticated_access || !$events_loc.pres_mgmt.show_content__session_search_room_name}
onchange={() => {
$events_trigger = 'load__event_session_obj_li';
}}
>
{#if $lq__event_location_obj_li}
<option value="">Location?</option>
{#each $lq__event_location_obj_li as event_location_obj}
<option value={event_location_obj?.name}>{event_location_obj.name}</option>
{/each}
{/if}
</select>
<button
type="button"
onclick={() => {
$events_sess.pres_mgmt.fulltext_search_qry_str = '';
$events_trigger = 'load__event_session_obj_li';
}}
class:hidden={!$events_sess.pres_mgmt.fulltext_search_qry_str || $events_sess.pres_mgmt.fulltext_search_qry_str.length == 0}
class="btn btn-sm mx-1 ae_btn_warning"
title="Clear search text"
>
<!-- <span class="fas fa-backspace"></span> -->
<!-- <span class="fas fa-broom"></span> -->
<span class="fas fa-remove-format"></span>
<!-- Clear text -->
</button>
<!-- svelte-ignore a11y_autofocus -->
<input
type="search"
placeholder="Search for a session"
id="session_fulltext_search_qry_str"
bind:value={$events_sess.pres_mgmt.fulltext_search_qry_str}
class="input text-1xl hover:text-2xl font-bold font-mono w-80 transition-all mx-1 ae_btn_info"
onkeyup={() => {
if ($events_sess.pres_mgmt?.fulltext_search_qry_str && $events_sess.pres_mgmt.fulltext_search_qry_str.length >= 3) {
$events_trigger = 'load__event_session_obj_li';
}
}}
autofocus
data-ignore="true"
/>
<button
type="submit"
class="btn btn-lg text-2xl font-bold w-48 mx-1 ae_btn_primary"
onclick={() => {
}}
title="Search for a session"
>
{#if $events_sess.pres_mgmt.status_qry__search == 'loading'}
<span class="fas fa-spinner fa-spin mx-1 text-success-800-200"></span>
{:else }
<span class="fas fa-search mx-1 text-neutral-800/80"></span>
{/if}
Search
</button>
</form>
</div>
<!-- {#if $lq__event_session_obj_li && $lq__event_session_obj_li?.length > 0 && event_session_id_random_li && event_session_id_random_li?.length > 0} -->
<!-- {#if event_session_id_random_li && $lq__event_session_obj_li && $lq__event_session_obj_li?.length} -->
{#if event_session_id_random_li}
<!-- <Comp_event_session_obj_li
lq__event_session_obj_li={lq__event_session_obj_li}
hide__session_location={$events_loc.pres_mgmt.hide__session_location}
hide__session_poc={$events_loc.pres_mgmt.hide__session_poc || $events_loc.pres_mgmt.hide__session_li_poc_field}
show__launcher_link={$ae_loc.administrator_access && $events_loc.pres_mgmt.show__launcher_link}
show__launcher_link_legacy={$ae_loc.trusted_access && $events_loc.pres_mgmt.show__launcher_link_legacy}
show__location_link={$events_loc.pres_mgmt.show__location_link}
log_lvl={log_lvl}
/> -->
<!-- link_to_type={'event'} -->
<!-- link_to_id={$lq__event_obj?.event_id_random} -->
<Comp_event_session_obj_li_wrapper
event_session_id_random_li={event_session_id_random_li}
log_lvl={1}
/>
{:else}
<section class="text-center text-2xl bg-yellow-100 p-4 rounded-md lg:max-w-lg space-y-2">
<div>
<span class="fas fa-exclamation-triangle text-2xl text-yellow-500"></span>
<strong>No results to show</strong>
<span class="fas fa-exclamation-triangle text-2xl text-yellow-500"></span>
<br>
<div class="text-lg">
Please use the search above to find your session.
</div>
</div>
<div>
<strong>Search by:</strong>
<ul
class="list-disc list-inside text-lg text-left"
>
<li>Session name</li>
<li>Session description</li>
<li>Presentation name</li>
<li>Presenter names</li>
<li>Presenter ID (member ID)</li>
</ul>
</div>
</section>
{/if}
{:else if $events_loc.pres_mgmt.show_content__event_view == 'manage_files' && $ae_loc.trusted_access}
{#if $lq__event_obj}
<header>
<h2 class="h3 text-center">{$lq__event_obj?.name}</h2>
<h3 class="h4 text-center">Event - Manage Files</h3>
</header>
{/if}
<div>
<h3 class="h5 text-center">
<span class="fas fa-tasks m-1 text-neutral-800/80"></span>
<span class="fas fa-mail-bulk m-1 text-neutral-800/80"></span>
Manage and Upload Event Files:
</h3>
<Comp_event_files_upload
class_li="border border-gray-300 rounded-md p-2 bg-gray-100 hover:bg-gray-200"
link_to_type="event"
link_to_id={$lq__event_obj?.event_id}
>
<span slot="label">
<div class="text-lg">
<span class="fas fa-upload"></span>
<strong class="">Upload global event files only!</strong>
</div>
<div class="text-sm text-gray-600 dark:text-gray-400 italic">
<strong>Global event files only</strong><br>
Recommended: PowerPoint (pptx) or Keynote (key)<br>
Media: Audio and videos files should be directly embedded in PowerPoint (PPTX) files<br>
Supplemental files: mp4, PDF, Word Doc, Excel, txt, etc
</div>
</span>
</Comp_event_files_upload>
<div class="overflow-x-auto w-max max-w-full">
<Element_manage_event_file_li_wrap
link_to_type={'event'}
link_to_id={$lq__event_obj?.event_id_random}
allow_basic={$events_loc.auth__kv.session[$lq__event_obj?.event_id_random] || $events_loc.auth__kv.session[$lq__event_obj?.event_id_random]}
allow_moderator={$events_loc.auth__kv.session[$lq__event_obj?.event_id_random]}
container_class_li={''}
/>
</div>
</div>
{/if}
{:else}
<div class="bg-red-100 p-4 border border-red-200 rounded-md">
<h2 class="h3">
<span class="fas fa-exclamation-triangle text-red-500 m-1"></span>
Event Disabled
</h2>
<p>
This event is currently disabled. Please contact the event organizer for more information.
</p>
</div>
{/if}
</section>
<style lang="postcss">
/* Use the div.ae_quick_modal_container to block background clicks when using the section.ae_quick_popover. */
/* div.ae_quick_modal_container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 100;
background-color: hsla(0, 0%, 0%, .5);
} */
/* The section.ae_quick_popover should be above the rest of the content and centered on the page. */
/* section.ae_quick_popover {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 100;
background-color: hsla(0, 0%, 100%, .95);
padding: 1rem;
border-radius: .5rem;
box-shadow: 0 0 1rem hsla(0, 0%, 0%, .5);
min-height: 30%;
min-width: 80%;
} */
</style>