Work on badge printing and the actual badge layout.
This commit is contained in:
@@ -34,6 +34,7 @@ import {
|
||||
|
||||
import {
|
||||
generate_qr_code,
|
||||
js_generate_qr_code,
|
||||
} from "$lib/ae_core/core__qr_code";
|
||||
|
||||
import {
|
||||
@@ -697,6 +698,7 @@ let export_obj = {
|
||||
handle_update_ae_obj_id_crud: handle_update_ae_obj_id_crud,
|
||||
update_ae_obj_id_crud_v2: update_ae_obj_id_crud_v2,
|
||||
handle_download_export__obj_type: handle_download_export__obj_type,
|
||||
generate_qr_code: generate_qr_code
|
||||
generate_qr_code: generate_qr_code,
|
||||
js_generate_qr_code: js_generate_qr_code,
|
||||
};
|
||||
export let core_func = export_obj;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import QRCode from 'qrcode'
|
||||
|
||||
import type { key_val } from '$lib/ae_stores';
|
||||
import { api } from '$lib/api';
|
||||
|
||||
@@ -136,4 +138,103 @@ export async function generate_qr_code(
|
||||
|
||||
// If not returning a blob, return the raw API response
|
||||
return ae_promises.generate_qr_code;
|
||||
}
|
||||
|
||||
|
||||
// Updated 2025-10-09
|
||||
/**
|
||||
* Generates a QR code image as a Base64 data URL based on provided parameters.
|
||||
*
|
||||
* NOTE: This function handles the data formatting and QR generation,
|
||||
* but does NOT handle server-side logic like file saving, disk path checks,
|
||||
* or database lookups (like redis_lookup_id_random).
|
||||
*
|
||||
* @param {string} qr_type - The type of data format ('mecard', 'vcard', 'obj', 'kv', 'js', 'str').
|
||||
* @param {Object} params - An object containing all necessary query parameters (n, fn, url, email, etc.).
|
||||
* @param {string} qr_id - A unique ID (unused in pure client-side generation, but kept for context).
|
||||
* @returns {Promise<string>} A promise that resolves to a Base64 data URL of the QR code image.
|
||||
* @throws {Error} If the qr_type is unknown or data is missing.
|
||||
*/
|
||||
export async function js_generate_qr_code(qr_type, params = {}) {
|
||||
const {
|
||||
n = '', fn = '', org = '', url = '', email = '', tel = '',
|
||||
adr_poa = '', adr_ext = '', adr_str = '', adr_loc = '', adr_reg = '', adr_postal = '', adr_country = '',
|
||||
obj_type, obj_id, key, val, js, str
|
||||
} = params;
|
||||
|
||||
console.log(`*** js_generate_qr_code() *** qr_type=${qr_type}`, params);
|
||||
|
||||
let qrData = null;
|
||||
|
||||
// --- 1. Replicate Data Formatting Logic ---
|
||||
switch (qr_type) {
|
||||
case 'mecard':
|
||||
// Format: MECARD:N:name;EMAIL:email;ADR:address;;
|
||||
// Note: The original Python code had adr, but we'll use n and email as a minimum.
|
||||
qrData = `MECARD:N:${n};EMAIL:${email};;`;
|
||||
// You can enhance this with other MeCard fields if needed.
|
||||
break;
|
||||
|
||||
case 'vcard':
|
||||
// Format: BEGIN:VCARD...END:VCARD
|
||||
qrData = `BEGIN:VCARD\nVERSION:3.0\nN:${n}\nFN:${fn}\nORG:${org}\nEMAIL:${email}\n`;
|
||||
|
||||
if (url) { qrData += `URL:${url}\n`; }
|
||||
if (tel) { qrData += `TEL:${tel}\n`; }
|
||||
if (adr_loc) {
|
||||
// ADR format: TYPE=postal:Po box;Ext;Street;Locality;Region;Postal code;Country
|
||||
qrData += `ADR:${adr_poa};${adr_ext};${adr_str};${adr_loc};${adr_reg};${adr_postal};${adr_country}\n`;
|
||||
}
|
||||
qrData += 'END:VCARD';
|
||||
break;
|
||||
|
||||
case 'obj':
|
||||
// Custom format: OBJ:ot:obj_type,oi:obj_id
|
||||
if (!obj_type || !obj_id) throw new Error('Missing obj_type or obj_id for type "obj".');
|
||||
qrData = `OBJ:ot:${obj_type},oi:${obj_id}`;
|
||||
break;
|
||||
|
||||
case 'kv':
|
||||
// Custom format: KV:k:"key",v:"val"
|
||||
if (!key || !val) throw new Error('Missing key or val for type "kv".');
|
||||
qrData = `KV:k:"${key}",v:"${val}"`;
|
||||
break;
|
||||
|
||||
case 'js':
|
||||
// Assumes 'js' is a stringified JSON object
|
||||
if (!js) throw new Error('Missing js string for type "js".');
|
||||
qrData = `JS:${js}`;
|
||||
break;
|
||||
|
||||
case 'str':
|
||||
// Raw string data
|
||||
if (!str) throw new Error('Missing raw string data for type "str".');
|
||||
qrData = str;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error(`Unknown QR type: ${qr_type}`);
|
||||
}
|
||||
|
||||
if (!qrData) {
|
||||
throw new Error('Failed to create QR code data string.');
|
||||
}
|
||||
|
||||
// --- 2. Generate QR Code Image ---
|
||||
try {
|
||||
// Options match the Python 'qrcode' library defaults closely:
|
||||
// error_correction = qrcode.constants.ERROR_CORRECT_M
|
||||
// box_size = 10, border = 1
|
||||
const dataUrl = await QRCode.toDataURL(qrData, {
|
||||
errorCorrectionLevel: 'M',
|
||||
margin: 1, // Corresponds to border
|
||||
scale: 10, // Corresponds to box_size
|
||||
type: 'image/png',
|
||||
});
|
||||
console.log('Generated QR code data URL:', dataUrl);
|
||||
return dataUrl;
|
||||
} catch (error) {
|
||||
console.error('Error generating QR code:', error);
|
||||
throw new Error('Could not generate QR code image.');
|
||||
}
|
||||
}
|
||||
@@ -18,14 +18,55 @@ export const properties_to_save = [
|
||||
'name',
|
||||
'description',
|
||||
|
||||
'template_code',
|
||||
'template_type',
|
||||
'template_json',
|
||||
'template_svg',
|
||||
'template_css',
|
||||
'template_html',
|
||||
// 'template_code',
|
||||
// 'template_type',
|
||||
// 'template_json',
|
||||
// 'template_svg',
|
||||
// 'template_css',
|
||||
// 'template_html',
|
||||
|
||||
'default',
|
||||
'logo_filename',
|
||||
'logo_path',
|
||||
|
||||
'header_path',
|
||||
'secondary_header_path',
|
||||
'footer_path',
|
||||
|
||||
'header_row_1',
|
||||
'header_row_2',
|
||||
|
||||
// 'footer_title',
|
||||
// 'footer_left',
|
||||
// 'footer_right',
|
||||
// 'header_background',
|
||||
// 'footer_background',
|
||||
|
||||
'badge_type_list',
|
||||
'ticket_list',
|
||||
|
||||
'ticket_1_text',
|
||||
'ticket_2_text',
|
||||
'ticket_3_text',
|
||||
'ticket_4_text',
|
||||
'ticket_5_text',
|
||||
'ticket_6_text',
|
||||
'ticket_7_text',
|
||||
'ticket_8_text',
|
||||
// 'ticket_9_text',
|
||||
// 'ticket_10_text',
|
||||
|
||||
'wireless_ssid',
|
||||
'wireless_password',
|
||||
|
||||
'show_qr_front',
|
||||
'show_qr_back',
|
||||
|
||||
'layout',
|
||||
'style_filename',
|
||||
// 'style_href',
|
||||
|
||||
|
||||
// 'default',
|
||||
'enable',
|
||||
'hide',
|
||||
'priority',
|
||||
@@ -70,14 +111,38 @@ export async function process_ae_obj__event_badge_template_props({
|
||||
name: obj.name,
|
||||
description: obj.description,
|
||||
|
||||
template_code: obj.template_code,
|
||||
template_type: obj.template_type,
|
||||
template_json: obj.template_json,
|
||||
template_svg: obj.template_svg,
|
||||
template_css: obj.template_css,
|
||||
template_html: obj.template_html,
|
||||
logo_filename: obj.logo_filename,
|
||||
logo_path: obj.logo_path,
|
||||
|
||||
default: obj.default,
|
||||
header_path: obj.header_path,
|
||||
secondary_header_path: obj.secondary_header_path,
|
||||
footer_path: obj.footer_path,
|
||||
|
||||
header_row_1: obj.header_row_1,
|
||||
header_row_2: obj.header_row_2,
|
||||
|
||||
badge_type_list: obj.badge_type_list,
|
||||
ticket_list: obj.ticket_list,
|
||||
|
||||
ticket_1_text: obj.ticket_1_text,
|
||||
ticket_2_text: obj.ticket_2_text,
|
||||
ticket_3_text: obj.ticket_3_text,
|
||||
ticket_4_text: obj.ticket_4_text,
|
||||
ticket_5_text: obj.ticket_5_text,
|
||||
ticket_6_text: obj.ticket_6_text,
|
||||
ticket_7_text: obj.ticket_7_text,
|
||||
ticket_8_text: obj.ticket_8_text,
|
||||
|
||||
wireless_ssid: obj.wireless_ssid,
|
||||
wireless_password: obj.wireless_password,
|
||||
|
||||
show_qr_front: obj.show_qr_front,
|
||||
show_qr_back: obj.show_qr_back,
|
||||
|
||||
layout: obj.layout,
|
||||
style_filename: obj.style_filename,
|
||||
|
||||
// default: obj.default,
|
||||
enable: obj.enable,
|
||||
hide: obj.hide,
|
||||
priority: obj.priority,
|
||||
|
||||
@@ -198,7 +198,55 @@ export interface Badge_template {
|
||||
event_id: string;
|
||||
event_id_random: string;
|
||||
|
||||
name: string;
|
||||
description?: null|string;
|
||||
|
||||
logo_filename?: null|string;
|
||||
logo_path?: null|string;
|
||||
|
||||
header_path?: null|string;
|
||||
secondary_header_path?: null|string;
|
||||
footer_path?: null|string;
|
||||
|
||||
header_row_1?: null|string;
|
||||
header_row_2?: null|string;
|
||||
|
||||
badge_type_list?: any; // This is an array of objects with code and name
|
||||
badge_type_info_kv?: any; // This is a key value list with code as the key and name as the value. Use this for exhibitor, presenter, attendee, staff, vip, etc.
|
||||
other_info_kv?: any; // This is a key value list with code as the key and name as the value. Use this for other custom fields.
|
||||
|
||||
ticket_list?: any; // This is an array of objects with num, code, and name
|
||||
|
||||
ticket_1_text?: null|string;
|
||||
ticket_2_text?: null|string;
|
||||
ticket_3_text?: null|string;
|
||||
ticket_4_text?: null|string;
|
||||
ticket_5_text?: null|string;
|
||||
ticket_6_text?: null|string;
|
||||
ticket_7_text?: null|string;
|
||||
ticket_8_text?: null|string;
|
||||
|
||||
wireless_ssid?: null|string;
|
||||
wireless_password?: null|string;
|
||||
|
||||
show_qr_front: boolean;
|
||||
show_qr_back: boolean;
|
||||
|
||||
layout?: null|string;
|
||||
style_filename?: null|string;
|
||||
|
||||
enable: null|boolean;
|
||||
hide?: null|boolean;
|
||||
priority?: null|boolean
|
||||
sort?: null|number;
|
||||
group?: null|string;
|
||||
notes?: null|string;
|
||||
created_on: Date;
|
||||
updated_on?: null|Date;
|
||||
|
||||
// Generated fields for sorting locally only
|
||||
|
||||
// Additional fields for convenience (database views)
|
||||
}
|
||||
|
||||
// Updated 2024-10-16
|
||||
|
||||
@@ -18,33 +18,34 @@ let {
|
||||
}: Props = $props();
|
||||
|
||||
// *** Import Svelte specific
|
||||
// import { browser } from '$app/environment';
|
||||
import { browser } from '$app/environment';
|
||||
|
||||
// *** Import other supporting libraries
|
||||
import { liveQuery } from "dexie";
|
||||
|
||||
import {
|
||||
ArrowDown01, ArrowDown10, ArrowDownUp,
|
||||
BetweenVerticalEnd, BetweenVerticalStart,
|
||||
BookHeart, BookImage, Bookmark, BookOpenText, BriefcaseBusiness,
|
||||
Check, Copy,
|
||||
Expand, Eye, EyeOff,
|
||||
Flag, FlagOff, FilePlus, Fingerprint,
|
||||
Globe,
|
||||
Library,
|
||||
MessageSquareWarning, Minus,
|
||||
Notebook,
|
||||
Pencil, Plus,
|
||||
RemoveFormatting,
|
||||
SquareLibrary,
|
||||
Shapes, Share2, ShieldCheck, ShieldMinus, Siren, Skull,
|
||||
Tags, Target, ToggleLeft, ToggleRight, Trash2, TypeOutline,
|
||||
X
|
||||
} from '@lucide/svelte';
|
||||
// import {
|
||||
// ArrowDown01, ArrowDown10, ArrowDownUp,
|
||||
// BetweenVerticalEnd, BetweenVerticalStart,
|
||||
// BookHeart, BookImage, Bookmark, BookOpenText, BriefcaseBusiness,
|
||||
// Check, Copy,
|
||||
// Expand, Eye, EyeOff,
|
||||
// Flag, FlagOff, FilePlus, Fingerprint,
|
||||
// Globe,
|
||||
// Library,
|
||||
// MessageSquareWarning, Minus,
|
||||
// Notebook,
|
||||
// Pencil, Plus,
|
||||
// RemoveFormatting,
|
||||
// SquareLibrary,
|
||||
// Shapes, Share2, ShieldCheck, ShieldMinus, Siren, Skull,
|
||||
// Tags, Target, ToggleLeft, ToggleRight, Trash2, TypeOutline,
|
||||
// X
|
||||
// } from '@lucide/svelte';
|
||||
|
||||
|
||||
import type { key_val } from '$lib/ae_stores';
|
||||
// import { ae_util } from '$lib/ae_utils/ae_utils';
|
||||
import { core_func } from '$lib/ae_core/ae_core_functions';
|
||||
import { ae_snip, ae_loc, ae_sess, ae_api, ae_trig, slct, slct_trigger } from '$lib/ae_stores';
|
||||
import { db_events } from "$lib/ae_events/db_events";
|
||||
import { events_loc, events_sess, events_slct, events_trigger } from '$lib/ae_events_stores';
|
||||
@@ -147,9 +148,9 @@ let option_ticket_3_override: any = $state(null);
|
||||
|
||||
let slct_badge_type = '';
|
||||
|
||||
let qr_type = 'mecard';
|
||||
let qr_img_src = $state(null);
|
||||
let img_obj_url = $state(null);
|
||||
// let qr_type = 'mecard';
|
||||
// let qr_img_src = $state(null);
|
||||
// let img_obj_url = $state(null);
|
||||
|
||||
|
||||
/* *** BEGIN *** This should be moved out */
|
||||
@@ -199,6 +200,36 @@ let lq__event_badge_template_obj = $derived(liveQuery(async () => {
|
||||
|
||||
full_name_override = $lq__event_badge_obj?.full_name_override ?? $lq__event_badge_obj?.full_name;
|
||||
|
||||
// if (full_name_override) {
|
||||
// let name_parts = full_name_override.trim().split(' ');
|
||||
// longest_full_name_override_part = 0;
|
||||
// for (let part of name_parts) {
|
||||
// if (part.length > longest_full_name_override_part) {
|
||||
// longest_full_name_override_part = part.length;
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// longest_full_name_override_part = 0;
|
||||
// }
|
||||
|
||||
professional_title_override = $lq__event_badge_obj?.professional_title_override ?? $lq__event_badge_obj?.professional_title;
|
||||
|
||||
affiliations_override = $lq__event_badge_obj?.affiliations_override ?? $lq__event_badge_obj?.affiliations;
|
||||
|
||||
location_override = $lq__event_badge_obj?.location_override ?? $lq__event_badge_obj?.location;
|
||||
|
||||
option_other_1_override = $lq__event_badge_obj?.option_other_1_override ?? $lq__event_badge_obj?.option_other_1;
|
||||
option_other_2_override = $lq__event_badge_obj?.option_other_2_override ?? $lq__event_badge_obj?.option_other_2;
|
||||
|
||||
option_ticket_1_override = $lq__event_badge_obj?.option_ticket_1_override ?? $lq__event_badge_obj?.option_ticket_1;
|
||||
option_ticket_2_override = $lq__event_badge_obj?.option_ticket_2_override ?? $lq__event_badge_obj?.option_ticket_2;
|
||||
option_ticket_3_override = $lq__event_badge_obj?.option_ticket_3_override ?? $lq__event_badge_obj?.option_ticket_3;
|
||||
// option_ticket_4_override = $lq__event_badge_obj?.option_ticket_4_override ?? $lq__event_badge_obj?.option_ticket_4;
|
||||
// option_ticket_5_override = $lq__event_badge_obj?.option_ticket_5_override ?? $lq__event_badge_obj?.option_ticket_5;
|
||||
// option_ticket_6_override = $lq__event_badge_obj?.option_ticket_6_override ?? $lq__event_badge_obj?.option_ticket_6;
|
||||
// option_ticket_7_override = $lq__event_badge_obj?.option_ticket_7_override ?? $lq__event_badge_obj?.option_ticket_7;
|
||||
// option_ticket_8_override = $lq__event_badge_obj?.option_ticket_8_override ?? $lq__event_badge_obj?.option_ticket_8;
|
||||
|
||||
return results;
|
||||
}));
|
||||
|
||||
@@ -211,6 +242,11 @@ function preventDefault(fn) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
let qr_data_url: any = $state('');
|
||||
let qr_error_message = $state('');
|
||||
|
||||
// Trigger doing a update for event badge
|
||||
$effect(() => {
|
||||
if (ae_triggers.event_badge_update) {
|
||||
@@ -219,16 +255,69 @@ if (ae_triggers.event_badge_update) {
|
||||
update_complete = false;
|
||||
}
|
||||
});
|
||||
|
||||
$effect(async () => {
|
||||
if (browser && $lq__event_badge_obj?.event_badge_id) {
|
||||
console.log('Generating QR code...');
|
||||
qr_error_message = '';
|
||||
qr_data_url = '';
|
||||
|
||||
let params: any = {};
|
||||
params.obj_type = 'event_badge';
|
||||
params.obj_id = $lq__event_badge_obj?.event_badge_id;
|
||||
|
||||
try {
|
||||
// Use 'vcard' as the qr_type, passing all required params
|
||||
// const data_url = await core_func.js_generate_qr_code('obj', params);
|
||||
qr_data_url = core_func.js_generate_qr_code('obj', params);
|
||||
} catch (error) {
|
||||
qr_error_message = error.message;
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Example VCard data
|
||||
const qrParams = {
|
||||
n: 'Doe, John',
|
||||
fn: 'John Doe',
|
||||
org: 'Acme Corp',
|
||||
email: 'john.doe@example.com',
|
||||
tel: '+15551234567',
|
||||
adr_loc: 'Springfield', // Must be present to include address block
|
||||
adr_country: 'USA'
|
||||
// ... include all other necessary parameters
|
||||
};
|
||||
|
||||
/**
|
||||
* Function to call the QR generation logic
|
||||
*/
|
||||
async function get_qr_code() {
|
||||
console.log('Generating QR code...');
|
||||
qr_error_message = '';
|
||||
qr_data_url = '';
|
||||
try {
|
||||
// Use 'vcard' as the qr_type, passing all required params
|
||||
const dataUrl = await core_func.js_generate_qr_code('vcard', qrParams);
|
||||
qr_data_url = dataUrl;
|
||||
} catch (error) {
|
||||
qr_error_message = error.message;
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
<pre class="whitespace-pre-wrap break-words text-xs">
|
||||
{JSON.stringify($lq__event_badge_obj, null, 2)}
|
||||
</pre>
|
||||
|
||||
|
||||
|
||||
<!--
|
||||
onclick={() => {
|
||||
@@ -242,19 +331,119 @@ onkeypress={() => {
|
||||
// slct_this_badge = true
|
||||
}} -->
|
||||
|
||||
|
||||
<!-- <button class="btn btn-sm preset-outlined-surface-200-800" onclick={get_qr_code}>Generate VCard QR Code</button> -->
|
||||
<!-- {#if qr_error_message}
|
||||
<p style="color: red;">Error: {qr_error_message}</p>
|
||||
{:else if qr_data_url}
|
||||
<h2>Generated QR Code:</h2>
|
||||
<img src={qr_data_url} alt="QR Code" />
|
||||
{:else}
|
||||
<p>Click the button to generate the QR code.</p>
|
||||
{/if} -->
|
||||
|
||||
<section
|
||||
class="event_badge_wrapper event_badge print_area outline"
|
||||
id="event_badge_{$lq__event_badge_obj?.event_badge_id}"
|
||||
class="event_badge_wrapper event_badge print_area
|
||||
flex flex-row flex-wrap gap-4
|
||||
items-stretch justify-center
|
||||
p-2 m-0
|
||||
outline-2 outline-dashed outline-blue-500
|
||||
"
|
||||
>
|
||||
{#if $lq__event_badge_obj && $lq__event_badge_template_obj}
|
||||
|
||||
<!-- *** badge_front section start *** -->
|
||||
<section class="badge_front badge_type__{use_badge_type_code.toLowerCase()}">
|
||||
<section
|
||||
class="badge_front badge_type__{use_badge_type_code.toLowerCase()}
|
||||
max-w-lg
|
||||
p-0 m-0
|
||||
text-center
|
||||
relative
|
||||
outline-2 outline-red-500/50 hover:outline-red-700/75
|
||||
group
|
||||
"
|
||||
>
|
||||
<span
|
||||
class="
|
||||
print:hidden absolute top-1 left-4
|
||||
text-xs italic
|
||||
text-gray-500 group-hover:text-red-800
|
||||
transition-all
|
||||
"
|
||||
>
|
||||
Front of badge
|
||||
</span>
|
||||
|
||||
|
||||
<div
|
||||
class="
|
||||
print:hidden absolute top-1 right-4
|
||||
hover:preset-tonal-secondary
|
||||
transition-all group
|
||||
flex flex-col gap-1 items-center justify-center
|
||||
"
|
||||
class:preset-outlined-warning-200-800={$ae_loc.edit_mode}
|
||||
class:preset-tonal-warning={$ae_loc.edit_mode}
|
||||
>
|
||||
<button
|
||||
class="
|
||||
btn btn-sm text-xs
|
||||
preset-tonal-warning preset-outlined-warning-100-900 hover:preset-filled-secondary-500
|
||||
transition-all group
|
||||
"
|
||||
onclick={() => {
|
||||
show_event_badge_tools_modal = true;
|
||||
$ae_loc.edit_mode = !$ae_loc.edit_mode;
|
||||
}}
|
||||
title="Edit Badge Information"
|
||||
>
|
||||
{#if $ae_loc.edit_mode}
|
||||
<span class="fas fa-times m-1"></span>
|
||||
{:else}
|
||||
<span class="fas fa-edit m-1"></span>
|
||||
{/if}
|
||||
<span
|
||||
class="
|
||||
hidden
|
||||
group-hover:inline-block
|
||||
text-xs
|
||||
"
|
||||
>
|
||||
{#if $ae_loc.edit_mode}
|
||||
Close Edit
|
||||
{:else}
|
||||
Edit Badge Information
|
||||
{/if}
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<div
|
||||
class="w-md max-w-lg m-1 p-1"
|
||||
class:hidden={!$ae_loc.edit_mode}>
|
||||
<p class="text-xs italic text-gray-500">
|
||||
Show list of fields that they can edit here. This may need to broken down in to sections that can be collapsed.
|
||||
</p>
|
||||
<ul class="text-left list-disc list-inside text-sm">
|
||||
<li>Full Name</li>
|
||||
<li>Professional Title</li>
|
||||
<li>Affiliations</li>
|
||||
<li>Location</li>
|
||||
<li>Option Ticket 1</li>
|
||||
<li>Option Ticket 2</li>
|
||||
<li>Option Ticket 3</li>
|
||||
<li>Option Other 1</li>
|
||||
<li>Option Other 2</li>
|
||||
<li>Badge Type</li>
|
||||
<li>Allow Tracking</li>
|
||||
<li>Show Print Message</li>
|
||||
<li>Hide QR Code</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{#if $lq__event_badge_template_obj.header_path}
|
||||
<div class="badge_header image">
|
||||
<div class="badge_header image max-w-xl">
|
||||
<img class="header_image" src="{$lq__event_badge_template_obj.header_path}" alt="check header path">
|
||||
</div>
|
||||
{:else}
|
||||
@@ -267,13 +456,13 @@ onkeypress={() => {
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="badge_body">
|
||||
<div class="badge_body space-y-1">
|
||||
<div class="person_name"
|
||||
>
|
||||
<!-- NOTE: Need to add some logic if any part of the name is 9 characters or more to reduce the font size OR if the total length is more than 15ish to reduce the font size :NOTE -->
|
||||
<!-- Examples: mSC-tTzL_OA, QLddtYl8sfo -->
|
||||
|
||||
<div class="full_name_override_all"
|
||||
<div class="full_name_override_all text-6xl"
|
||||
class:str_05={longest_full_name_override_part==5}
|
||||
class:str_06={longest_full_name_override_part==6}
|
||||
class:str_07={longest_full_name_override_part==7}
|
||||
@@ -303,7 +492,7 @@ onkeypress={() => {
|
||||
</div>
|
||||
|
||||
{#if professional_title_override}
|
||||
<div class="professional_title"
|
||||
<div class="professional_title text-2xl"
|
||||
class:str_05={professional_title_override.length==5}
|
||||
class:str_06={professional_title_override.length==6}
|
||||
class:str_07={professional_title_override.length==7}
|
||||
@@ -340,7 +529,7 @@ onkeypress={() => {
|
||||
{#if affiliations_override || location_override}
|
||||
<div class="affiliations_location">
|
||||
{#if affiliations_override}
|
||||
<div class="affiliations"
|
||||
<div class="affiliations text-4xl"
|
||||
class:str_05={affiliations_override.length==5}
|
||||
class:str_06={affiliations_override.length==6}
|
||||
class:str_07={affiliations_override.length==7}
|
||||
@@ -363,7 +552,7 @@ onkeypress={() => {
|
||||
{/if}
|
||||
|
||||
{#if location_override}
|
||||
<div class="location"
|
||||
<div class="location text-2xl"
|
||||
class:str_15={location_override.length>=15}
|
||||
class:str_20={location_override.length>=20}
|
||||
class:str_25={location_override.length>=25}
|
||||
@@ -393,11 +582,11 @@ onkeypress={() => {
|
||||
{/if}
|
||||
</span>
|
||||
{#if $lq__event_badge_template_obj.show_qr_front}
|
||||
{#await initial_loading_promise}
|
||||
{#await qr_data_url}
|
||||
Generating...
|
||||
{:then result}
|
||||
{#if initial_loading_promise}
|
||||
<img class="qr_code mecard_qr" style="" src="/event/qr_image/event_badge_mecard_{$lq__event_badge_obj.event_badge_id_random}?qr_filename=attendee_qr.png" alt="missing QR code">
|
||||
{#if qr_data_url}
|
||||
<img class="qr_code mecard_qr" style="" src={qr_data_url} alt="missing QR code">
|
||||
{/if}
|
||||
{/await}
|
||||
{/if}
|
||||
@@ -458,7 +647,7 @@ onkeypress={() => {
|
||||
class:v_hide_print={hide_qr}
|
||||
|
||||
|
||||
src={qr_img_src}
|
||||
src={qr_data_url}
|
||||
alt="missing QR code"
|
||||
|
||||
ondblclick={() => {
|
||||
@@ -477,14 +666,33 @@ onkeypress={() => {
|
||||
|
||||
|
||||
<!-- *** badge_back (fold under) section start *** -->
|
||||
<section class="badge_back">
|
||||
<section
|
||||
class="badge_back
|
||||
max-w-lg
|
||||
p-0 m-0
|
||||
text-left
|
||||
relative
|
||||
outline-2 outline-green-500/50 hover:outline-green-700/75
|
||||
group
|
||||
"
|
||||
>
|
||||
|
||||
<span
|
||||
class="
|
||||
print:hidden absolute top-1 right-4
|
||||
text-xs italic
|
||||
text-gray-500 group-hover:text-green-800
|
||||
"
|
||||
>
|
||||
Back of badge
|
||||
</span>
|
||||
|
||||
{#if $lq__event_badge_template_obj.secondary_header_path}
|
||||
<div class="badge_back_header image">
|
||||
<div class="badge_back_header image max-w-xl">
|
||||
<img class="header_image" src="{$lq__event_badge_template_obj.secondary_header_path}" alt="check secondary header path">
|
||||
</div>
|
||||
{:else if $lq__event_badge_template_obj.header_path}
|
||||
<div class="badge_back_header image">
|
||||
<div class="badge_back_header image max-w-xl">
|
||||
<img class="header_image" src="{$lq__event_badge_template_obj.header_path}" alt="check primary header path">
|
||||
</div>
|
||||
{:else}
|
||||
@@ -533,24 +741,25 @@ onkeypress={() => {
|
||||
{$lq__event_badge_obj.given_name}'s
|
||||
QR Code and Badge ID:
|
||||
</div>
|
||||
{#await event_badge_qr_id_get_promise}
|
||||
{#await qr_data_url}
|
||||
<!-- Must use this await when the image is generated. It either happens here or on the $effect with async -->
|
||||
Generating...
|
||||
{:then result}
|
||||
{#if event_badge_qr_id_get_promise}
|
||||
<div class="qr_badge_id_part_1">
|
||||
{#if result}
|
||||
<div class="qr_badge_id_part_1 flex flex-row items-center justify-between">
|
||||
|
||||
|
||||
<img
|
||||
class="qr_code mecard_qr"
|
||||
class="qr_code mecard_qr max-w-48 hover:scale-200 transition-transform duration-200 ease-in-out hover:p-4 hover:border-2 hover:border-red-500 hover:bg-white"
|
||||
class:v_hide_print={hide_qr}
|
||||
src={qr_img_src}
|
||||
src={result}
|
||||
alt="badge QR code"
|
||||
ondblclick={() => {
|
||||
// (hide_qr) ? hide_qr = !hide_qr : hide_qr;
|
||||
(hide_qr) ? hide_qr = false : hide_qr = true;
|
||||
}}
|
||||
/>
|
||||
<div class="qr_badge_id_agreement fs_xs f_align_justify">
|
||||
<div class="qr_badge_id_agreement fs_xs f_align_justify text-xs">
|
||||
{#if allow_tracking}
|
||||
<p>This was <strong>allowed</strong> at the time your badge was printed. You may opt-out at anytime.</p>
|
||||
<p>By allowing this QR code to be scanned by an exhibitor and/or industry supporter, you understand and agree that they may use your personal information.</p>
|
||||
@@ -570,7 +779,7 @@ onkeypress={() => {
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="container app_information">
|
||||
<div class="container app_information text-xs">
|
||||
<strong>Download Meeting App:</strong>
|
||||
<!-- <img style="width: .75in; float: right;" src="/event/qr_image/testing123" alt="missing person information QR code"> -->
|
||||
<ol style="margin: 0; padding-top: 0; padding-bottom: 0;">
|
||||
@@ -664,7 +873,8 @@ onkeypress={() => {
|
||||
|
||||
</div>
|
||||
|
||||
<div class="badge_back_footer">
|
||||
<div class="badge_back_footer text-xxs italic text-gray-500">
|
||||
<!-- This will need to be rotated with CSS for printing on the fanfold badges. -->
|
||||
Fold in half here
|
||||
<!-- <ol>
|
||||
<li>Fold this section under the badge.</li>
|
||||
@@ -678,10 +888,10 @@ onkeypress={() => {
|
||||
|
||||
|
||||
<!-- *** receipt section start *** -->
|
||||
<section class="receipt"> <!-- receipt class div start -->
|
||||
<section class="receipt hidden"> <!-- receipt class div start -->
|
||||
|
||||
<div class="receipt_header">
|
||||
<img class="badge_logo" src="{$lq__event_badge_template_obj.logo_path}" alt="check badge logo">
|
||||
<img class="badge_logo max-w-sm" src="{$lq__event_badge_template_obj.logo_path}" alt="check badge logo">
|
||||
<div class="banner_text">
|
||||
<div class="row_one">{$lq__event_badge_template_obj.header_row_1}</div>
|
||||
<div class="row_two">{$lq__event_badge_template_obj.header_row_2}</div>
|
||||
@@ -731,7 +941,7 @@ onkeypress={() => {
|
||||
|
||||
|
||||
<!-- *** ticket section start *** -->
|
||||
<section class="tickets_left_container">
|
||||
<section class="tickets_left_container hidden">
|
||||
<div class="tickets"> <!-- Fold class div start -->
|
||||
|
||||
<div class="ticket_container ticket_1">
|
||||
@@ -761,7 +971,7 @@ onkeypress={() => {
|
||||
|
||||
|
||||
<!-- *** ticket section start *** -->
|
||||
<section class="tickets_right_container">
|
||||
<section class="tickets_right_container hidden">
|
||||
<div class="tickets"> <!-- Fold class div start -->
|
||||
|
||||
<div class="ticket_container ticket_5">
|
||||
@@ -793,3 +1003,11 @@ onkeypress={() => {
|
||||
{/if} <!-- End if for lq__event_badge_template_obj -->
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
<pre class="whitespace-pre-wrap break-words text-xs max-h-24 overflow-auto p-2 bg-surface-200 border border-surface-300 rounded">
|
||||
{JSON.stringify($lq__event_badge_obj, null, 2)}
|
||||
</pre>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user