Change to just full name
This commit is contained in:
4
.github/styling.md
vendored
4
.github/styling.md
vendored
@@ -89,7 +89,7 @@ This document outlines the design system and styling conventions used in the app
|
||||
|
||||
### Container Pattern
|
||||
```html
|
||||
<div class="container mx-auto max-w-2xl bg-white p-4">
|
||||
<div class="container mx-auto max-w-5xl bg-white p-4">
|
||||
<!-- Content -->
|
||||
</div>
|
||||
```
|
||||
@@ -225,7 +225,7 @@ This document outlines the design system and styling conventions used in the app
|
||||
### Top Navigation
|
||||
```html
|
||||
<nav class="border-b border-gray-300 bg-gray-50 p-4 text-gray-900">
|
||||
<div class="container mx-auto max-w-2xl">
|
||||
<div class="container mx-auto max-w-5xl">
|
||||
<div class="flex items-center justify-between">
|
||||
<a href="/" class="text-lg font-bold">App Name</a>
|
||||
<ul class="flex space-x-4">
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
<div class="flex min-h-screen flex-col items-center justify-center bg-gray-100 p-4">
|
||||
<div
|
||||
class="container mx-auto max-w-4xl rounded-lg border border-gray-200 bg-white/90 p-10 text-center shadow-xl"
|
||||
class="container mx-auto max-w-5xl rounded-lg border border-gray-200 bg-white/90 p-10 text-center shadow-xl"
|
||||
>
|
||||
<div class="mb-10 flex flex-col items-center">
|
||||
<!-- Animated ESN Logo -->
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
</script>
|
||||
|
||||
<div class="bg-gray-100 min-h-screen p-4">
|
||||
<div class="container mx-auto max-w-4xl pb-10">
|
||||
<div class="container mx-auto max-w-5xl pb-10">
|
||||
{#if $currentStepName !== 'splash'}
|
||||
<!-- Progress indicator -->
|
||||
<div class="bg-white rounded-lg shadow-sm p-6 mb-6">
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
</script>
|
||||
|
||||
<div class="p-6">
|
||||
<div class="max-w-4xl mx-auto">
|
||||
<div class="max-w-5xl mx-auto">
|
||||
<div class="mb-6">
|
||||
<h2 class="text-xl font-semibold text-gray-900 mb-2">Select Card Type</h2>
|
||||
<p class="text-sm text-gray-700 mb-4">
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
let savedSheetInfo = $state<SheetInfoType | null>(null);
|
||||
let mappedIndices = $state<ColumnMappingType>({
|
||||
name: -1,
|
||||
surname: -1,
|
||||
nationality: -1,
|
||||
birthday: -1,
|
||||
pictureUrl: -1,
|
||||
@@ -27,8 +26,7 @@
|
||||
});
|
||||
|
||||
const requiredFields = [
|
||||
{ key: 'name', label: 'First Name', required: true },
|
||||
{ key: 'surname', label: 'Last Name', required: true },
|
||||
{ key: 'name', label: 'Full Name', required: true },
|
||||
{ key: 'nationality', label: 'Nationality', required: true },
|
||||
{ key: 'birthday', label: 'Birthday', required: true },
|
||||
{ key: 'pictureUrl', label: 'Photo URL', required: true },
|
||||
@@ -65,7 +63,6 @@
|
||||
// Set the mapped indices from saved data
|
||||
mappedIndices = {
|
||||
name: savedSheet.columnMapping.name,
|
||||
surname: savedSheet.columnMapping.surname,
|
||||
nationality: savedSheet.columnMapping.nationality,
|
||||
birthday: savedSheet.columnMapping.birthday,
|
||||
pictureUrl: savedSheet.columnMapping.pictureUrl,
|
||||
@@ -123,7 +120,6 @@
|
||||
previewData = [];
|
||||
mappedIndices = {
|
||||
name: -1,
|
||||
surname: -1,
|
||||
nationality: -1,
|
||||
birthday: -1,
|
||||
pictureUrl: -1,
|
||||
@@ -182,7 +178,6 @@
|
||||
// Reset mappings
|
||||
mappedIndices = {
|
||||
name: -1,
|
||||
surname: -1,
|
||||
nationality: -1,
|
||||
birthday: -1,
|
||||
pictureUrl: -1,
|
||||
@@ -192,8 +187,7 @@
|
||||
|
||||
// Auto-mapping patterns
|
||||
const patterns: Record<keyof Omit<ColumnMappingType, 'sheetName'>, RegExp> = {
|
||||
name: /first[\s_-]*name|name|given[\s_-]*name|vorname/i,
|
||||
surname: /last[\s_-]*name|surname|family[\s_-]*name|nachname/i,
|
||||
name: /full[\s_-]*name|name/i,
|
||||
nationality: /nationality|country|nation/i,
|
||||
birthday: /birth|date[\s_-]*of[\s_-]*birth|birthday|dob/i,
|
||||
pictureUrl: /photo|picture|image|url|avatar/i,
|
||||
@@ -262,8 +256,7 @@
|
||||
// Override auto-mapping with saved mapping
|
||||
mappedIndices = {
|
||||
name: savedSheet.columnMapping.name ?? -1,
|
||||
surname: savedSheet.columnMapping.surname ?? -1,
|
||||
nationality: savedSheet.columnMapping.nationality ?? -1,
|
||||
nationality: savedSheet.columnMappin.nationality ?? -1,
|
||||
birthday: savedSheet.columnMapping.birthday ?? -1,
|
||||
pictureUrl: savedSheet.columnMapping.pictureUrl ?? -1,
|
||||
alreadyPrinted: savedSheet.columnMapping.alreadyPrinted ?? -1,
|
||||
@@ -286,7 +279,6 @@
|
||||
if (!mappedIndices) {
|
||||
mappedIndices = {
|
||||
name: -1,
|
||||
surname: -1,
|
||||
nationality: -1,
|
||||
birthday: -1,
|
||||
pictureUrl: -1,
|
||||
@@ -306,7 +298,6 @@
|
||||
// Only check required fields for completion
|
||||
const requiredIndices = {
|
||||
name: mappedIndices.name,
|
||||
surname: mappedIndices.surname,
|
||||
nationality: mappedIndices.nationality,
|
||||
birthday: mappedIndices.birthday,
|
||||
pictureUrl: mappedIndices.pictureUrl,
|
||||
@@ -319,7 +310,6 @@
|
||||
// Update the column mapping store
|
||||
columnMapping.set({
|
||||
name: mappedIndices.name,
|
||||
surname: mappedIndices.surname,
|
||||
nationality: mappedIndices.nationality,
|
||||
birthday: mappedIndices.birthday,
|
||||
pictureUrl: mappedIndices.pictureUrl,
|
||||
@@ -343,7 +333,6 @@
|
||||
|
||||
const columnMappingData = {
|
||||
name: mappedIndices.name,
|
||||
surname: mappedIndices.surname,
|
||||
nationality: mappedIndices.nationality,
|
||||
birthday: mappedIndices.birthday,
|
||||
pictureUrl: mappedIndices.pictureUrl,
|
||||
@@ -434,7 +423,7 @@
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z"
|
||||
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zm-4 4a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@@ -140,7 +140,7 @@ async function createPreviewBlob(original: Blob, maxSide = 1200, quality = 0.85)
|
||||
console.log(`Found ${totalCount} unique photo URLs to process.`);
|
||||
|
||||
photos = Array.from(photoUrls).map((url) => ({
|
||||
name: photoMap.get(url)![0].name + ' ' + photoMap.get(url)![0].surname,
|
||||
name: photoMap.get(url)![0].name,
|
||||
url,
|
||||
status: 'loading' as const,
|
||||
retryCount: 0,
|
||||
|
||||
@@ -388,7 +388,6 @@
|
||||
|
||||
// Get field values
|
||||
const name = row.name;
|
||||
const surname = row.surname;
|
||||
const nationality = row.nationality;
|
||||
const birthday = row.birthday;
|
||||
const studiesAt = studiesAtAll;
|
||||
@@ -404,7 +403,7 @@
|
||||
PAGE_SETTINGS.pageHeight,
|
||||
card.textFields.name
|
||||
);
|
||||
page.drawText(`${name} ${surname}`, {
|
||||
page.drawText(`${name}`, {
|
||||
...namePos,
|
||||
font,
|
||||
color: rgb(TEXT_CONFIG.color.r, TEXT_CONFIG.color.g, TEXT_CONFIG.color.b)
|
||||
@@ -608,14 +607,13 @@
|
||||
|
||||
// Draw name
|
||||
const name = row.name;
|
||||
const surname = row.surname;
|
||||
const namePos = getAbsolutePositionPt(
|
||||
cellX_mm,
|
||||
cellY_mm,
|
||||
PAGE_SETTINGS.pageHeight,
|
||||
card.photoFields.name
|
||||
);
|
||||
page.drawText(`${name} ${surname}`, {
|
||||
page.drawText(`${name}`, {
|
||||
...namePos,
|
||||
font,
|
||||
color: rgb(TEXT_CONFIG.color.r, TEXT_CONFIG.color.g, TEXT_CONFIG.color.b)
|
||||
@@ -671,7 +669,7 @@
|
||||
</script>
|
||||
|
||||
<div class="p-6">
|
||||
<div class="max-w-4xl mx-auto">
|
||||
<div class="max-w-5xl mx-auto">
|
||||
<div class="mb-6">
|
||||
<h2 class="text-xl font-semibold text-gray-900 mb-2">Generating PDFs...</h2>
|
||||
<p class="text-sm text-gray-700 mb-4">
|
||||
|
||||
@@ -50,10 +50,9 @@
|
||||
const processedData = dataRows
|
||||
.map((row, index): RowData | null => {
|
||||
const name = mapping.name !== -1 ? row[mapping.name] || '' : '';
|
||||
const surname = mapping.surname !== -1 ? row[mapping.surname] || '' : '';
|
||||
const pictureUrl = mapping.pictureUrl !== -1 ? row[mapping.pictureUrl] || '' : '';
|
||||
|
||||
if (!name && !surname && !pictureUrl) {
|
||||
if (!name && !pictureUrl) {
|
||||
return null; // Skip entirely empty rows
|
||||
}
|
||||
|
||||
@@ -62,12 +61,11 @@
|
||||
? (row[mapping.alreadyPrinted] || '').toLowerCase() === 'true'
|
||||
: false;
|
||||
|
||||
const isValid = !!(name && surname && pictureUrl);
|
||||
const isValid = !!(name && pictureUrl);
|
||||
|
||||
return {
|
||||
id: uuid(),
|
||||
name,
|
||||
surname,
|
||||
nationality: mapping.nationality !== -1 ? row[mapping.nationality] || '' : '',
|
||||
birthday: mapping.birthday !== -1 ? row[mapping.birthday] || '' : '',
|
||||
pictureUrl,
|
||||
@@ -277,11 +275,7 @@
|
||||
>
|
||||
<th
|
||||
class="cursor-pointer px-4 py-3 text-left text-xs font-semibold uppercase tracking-wider text-gray-600 hover:bg-gray-100"
|
||||
onclick={() => sortBy('name')}>Name</th
|
||||
>
|
||||
<th
|
||||
class="cursor-pointer px-4 py-3 text-left text-xs font-semibold uppercase tracking-wider text-gray-600 hover:bg-gray-100"
|
||||
onclick={() => sortBy('surname')}>Surname</th
|
||||
onclick={() => sortBy('name')}>Full Name</th
|
||||
>
|
||||
<th
|
||||
class="cursor-pointer px-4 py-3 text-left text-xs font-semibold uppercase tracking-wider text-gray-600 hover:bg-gray-100"
|
||||
@@ -324,7 +318,6 @@
|
||||
</td>
|
||||
<td class="whitespace-nowrap px-4 py-3 text-sm">{row._rowIndex}</td>
|
||||
<td class="whitespace-nowrap px-4 py-3 text-sm">{row.name}</td>
|
||||
<td class="whitespace-nowrap px-4 py-3 text-sm">{row.surname}</td>
|
||||
<td class="whitespace-nowrap px-4 py-3 text-sm">{row.nationality}</td>
|
||||
<td class="whitespace-nowrap px-4 py-3 text-sm">{row.birthday}</td>
|
||||
<td class="whitespace-nowrap px-4 py-3 text-sm">
|
||||
|
||||
@@ -12,73 +12,69 @@ export const session = writable<{
|
||||
|
||||
// Data structure column mapping
|
||||
export interface ColumnMappingType {
|
||||
name: number;
|
||||
surname: number;
|
||||
nationality: number;
|
||||
birthday: number;
|
||||
pictureUrl: number;
|
||||
alreadyPrinted: number;
|
||||
sheetName: string;
|
||||
name: number;
|
||||
nationality: number;
|
||||
birthday: number;
|
||||
pictureUrl: number;
|
||||
alreadyPrinted: number;
|
||||
sheetName: string;
|
||||
}
|
||||
|
||||
// Data structure for a row in the sheet
|
||||
export interface RowData {
|
||||
id: string; // Unique identifier
|
||||
name: string;
|
||||
surname: string;
|
||||
nationality: string;
|
||||
birthday: string;
|
||||
pictureUrl: string;
|
||||
alreadyPrinted: boolean;
|
||||
_rowIndex: number;
|
||||
_checked: boolean;
|
||||
_valid: boolean;
|
||||
id: string; // Unique identifier
|
||||
name: string;
|
||||
nationality: string;
|
||||
birthday: string;
|
||||
pictureUrl: string;
|
||||
alreadyPrinted: boolean;
|
||||
_rowIndex: number;
|
||||
_checked: boolean;
|
||||
_valid: boolean;
|
||||
}
|
||||
|
||||
// Picture storage and metadata
|
||||
export interface PictureBlobInfoType {
|
||||
id: string;
|
||||
url: string;
|
||||
downloaded: boolean;
|
||||
faceDetected: boolean;
|
||||
faceCount: number;
|
||||
id: string;
|
||||
url: string;
|
||||
downloaded: boolean;
|
||||
faceDetected: boolean;
|
||||
faceCount: number;
|
||||
}
|
||||
|
||||
// CropType rectangles for each photo
|
||||
export interface CropType {
|
||||
x: number;
|
||||
y: number;
|
||||
width: number;
|
||||
height: number;
|
||||
x: number;
|
||||
y: number;
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
||||
// Google Sheets list for search
|
||||
export interface SheetInfoType {
|
||||
id: string;
|
||||
name: string;
|
||||
webViewLink: string;
|
||||
id: string;
|
||||
name: string;
|
||||
webViewLink: string;
|
||||
}
|
||||
|
||||
// Card details type
|
||||
export interface CardDetailsType {
|
||||
esnSection: string;
|
||||
studiesAt: string;
|
||||
validityStart: string;
|
||||
esnSection: string;
|
||||
studiesAt: string;
|
||||
validityStart: string;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Column mapping configuration
|
||||
export const columnMapping = writable<ColumnMappingType>(
|
||||
{
|
||||
name: -1,
|
||||
surname: -1,
|
||||
nationality: -1,
|
||||
birthday: -1,
|
||||
pictureUrl: -1,
|
||||
alreadyPrinted: -1,
|
||||
sheetName: ''
|
||||
});
|
||||
export const columnMapping = writable<ColumnMappingType>({
|
||||
name: -1,
|
||||
nationality: -1,
|
||||
birthday: -1,
|
||||
pictureUrl: -1,
|
||||
alreadyPrinted: -1,
|
||||
sheetName: ''
|
||||
});
|
||||
|
||||
// Store to hold the processed sheet data
|
||||
export const sheetData = writable<RowData[]>([]);
|
||||
@@ -103,35 +99,35 @@ export const selectedCard = writable<Card | null>(null);
|
||||
export const currentStep = writable<number>(0);
|
||||
|
||||
export const steps = [
|
||||
'splash',
|
||||
'auth',
|
||||
'search',
|
||||
'mapping',
|
||||
'validation',
|
||||
'card-details',
|
||||
'card-select',
|
||||
'gallery',
|
||||
'generate'
|
||||
'splash',
|
||||
'auth',
|
||||
'search',
|
||||
'mapping',
|
||||
'validation',
|
||||
'card-details',
|
||||
'card-select',
|
||||
'gallery',
|
||||
'generate'
|
||||
] as const;
|
||||
|
||||
export type WizardStep = typeof steps[number];
|
||||
|
||||
export const currentStepName = derived(
|
||||
currentStep,
|
||||
($currentStep) => steps[$currentStep]
|
||||
currentStep,
|
||||
($currentStep) => steps[$currentStep]
|
||||
);
|
||||
|
||||
// Progress tracking
|
||||
export interface ProgressState {
|
||||
stage: string;
|
||||
current: number;
|
||||
total: number;
|
||||
message: string;
|
||||
stage: string;
|
||||
current: number;
|
||||
total: number;
|
||||
message: string;
|
||||
}
|
||||
|
||||
export const progress = writable<ProgressState>({
|
||||
stage: '',
|
||||
current: 0,
|
||||
total: 0,
|
||||
message: ''
|
||||
stage: '',
|
||||
current: 0,
|
||||
total: 0,
|
||||
message: ''
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user