feat: add photo booth functionality with shooting, uploading, and printing steps

- Implemented PrintStepView for displaying countdown and photo results.
- Created SelectSourceView for choosing between shooting new photos or uploading existing ones.
- Developed ShootingView for capturing photos using the device camera.
- Added UploadView for selecting and previewing uploaded photos.
- Configured TypeScript settings with tsconfig files for app and node environments.
- Set up Vite configuration with PWA support for the application.
This commit is contained in:
mrkad@rpi
2026-01-17 11:41:46 +07:00
commit e90c06230b
44 changed files with 10189 additions and 0 deletions

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

5
public/frame-classic.svg Normal file
View File

@@ -0,0 +1,5 @@
<svg width="200" height="300" xmlns="http://www.w3.org/2000/svg">
<rect width="200" height="300" fill="#ffffff" stroke="#dee2e6" stroke-width="2" rx="8"/>
<rect x="10" y="10" width="180" height="40" fill="#f8f9fa" rx="4"/>
<text x="100" y="35" font-family="Arial" font-size="14" fill="#666" text-anchor="middle">Classic Frame</text>
</svg>

After

Width:  |  Height:  |  Size: 345 B

11
public/frame-colorful.svg Normal file
View File

@@ -0,0 +1,11 @@
<svg width="200" height="300" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="colorful" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#4facfe"/>
<stop offset="100%" style="stop-color:#00f2fe"/>
</linearGradient>
</defs>
<rect width="200" height="300" fill="url(#colorful)" rx="8"/>
<rect x="10" y="10" width="180" height="40" fill="rgba(255,255,255,0.2)" rx="4"/>
<text x="100" y="35" font-family="Arial" font-size="14" fill="white" text-anchor="middle">Colorful Frame</text>
</svg>

After

Width:  |  Height:  |  Size: 554 B

5
public/frame-minimal.svg Normal file
View File

@@ -0,0 +1,5 @@
<svg width="200" height="300" xmlns="http://www.w3.org/2000/svg">
<rect width="200" height="300" fill="#f8f9fa" stroke="#dee2e6" stroke-width="2" rx="8"/>
<rect x="10" y="10" width="180" height="40" fill="#ffffff" stroke="#dee2e6" stroke-width="1" rx="4"/>
<text x="100" y="35" font-family="Arial" font-size="14" fill="#666" text-anchor="middle">Minimal Frame</text>
</svg>

After

Width:  |  Height:  |  Size: 379 B

11
public/frame-modern.svg Normal file
View File

@@ -0,0 +1,11 @@
<svg width="200" height="300" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="modern" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#667eea"/>
<stop offset="100%" style="stop-color:#764ba2"/>
</linearGradient>
</defs>
<rect width="200" height="300" fill="url(#modern)" rx="8"/>
<rect x="10" y="10" width="180" height="40" fill="rgba(255,255,255,0.2)" rx="4"/>
<text x="100" y="35" font-family="Arial" font-size="14" fill="white" text-anchor="middle">Modern Frame</text>
</svg>

After

Width:  |  Height:  |  Size: 548 B

11
public/frame-vintage.svg Normal file
View File

@@ -0,0 +1,11 @@
<svg width="200" height="300" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="vintage" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#f093fb"/>
<stop offset="100%" style="stop-color:#f5576c"/>
</linearGradient>
</defs>
<rect width="200" height="300" fill="url(#vintage)" rx="8"/>
<rect x="10" y="10" width="180" height="40" fill="rgba(255,255,255,0.2)" rx="4"/>
<text x="100" y="35" font-family="Arial" font-size="14" fill="white" text-anchor="middle">Vintage Frame</text>
</svg>

After

Width:  |  Height:  |  Size: 551 B

4
public/icon-192x192.svg Normal file
View File

@@ -0,0 +1,4 @@
<svg width="192" height="192" xmlns="http://www.w3.org/2000/svg">
<rect width="192" height="192" fill="#667eea" rx="24"/>
<text x="96" y="120" font-family="Arial" font-size="72" fill="white" text-anchor="middle">📷</text>
</svg>

After

Width:  |  Height:  |  Size: 234 B

View File

@@ -0,0 +1,7 @@
<svg width="360" height="480" xmlns="http://www.w3.org/2000/svg">
<rect width="360" height="480" fill="#f8f9fa" rx="8"/>
<circle cx="180" cy="160" r="60" fill="#dee2e6"/>
<rect x="120" y="240" width="120" height="20" fill="#dee2e6" rx="4"/>
<rect x="140" y="270" width="80" height="16" fill="#dee2e6" rx="4"/>
<text x="180" y="400" font-family="Arial" font-size="16" fill="#666" text-anchor="middle">ตัวอย่างรูปถ่าย</text>
</svg>

After

Width:  |  Height:  |  Size: 469 B

View File

@@ -0,0 +1,13 @@
<svg width="360" height="480" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#667eea"/>
<stop offset="100%" style="stop-color:#764ba2"/>
</linearGradient>
</defs>
<rect width="360" height="480" fill="url(#grad1)" rx="8"/>
<circle cx="180" cy="160" r="60" fill="rgba(255,255,255,0.3)"/>
<rect x="120" y="240" width="120" height="20" fill="rgba(255,255,255,0.3)" rx="4"/>
<rect x="140" y="270" width="80" height="16" fill="rgba(255,255,255,0.3)" rx="4"/>
<text x="180" y="400" font-family="Arial" font-size="16" fill="white" text-anchor="middle">รูปถ่ายตัวอย่าง 2</text>
</svg>

After

Width:  |  Height:  |  Size: 735 B

View File

@@ -0,0 +1,7 @@
<svg width="360" height="480" xmlns="http://www.w3.org/2000/svg">
<rect width="360" height="480" fill="#ff6b6b" rx="8"/>
<circle cx="180" cy="160" r="60" fill="rgba(255,255,255,0.8)"/>
<rect x="120" y="240" width="120" height="20" fill="rgba(255,255,255,0.8)" rx="4"/>
<rect x="140" y="270" width="80" height="16" fill="rgba(255,255,255,0.8)" rx="4"/>
<text x="180" y="400" font-family="Arial" font-size="16" fill="white" text-anchor="middle">รูปถ่ายตัวอย่าง 3</text>
</svg>

After

Width:  |  Height:  |  Size: 514 B

View File

@@ -0,0 +1,7 @@
<svg width="360" height="480" xmlns="http://www.w3.org/2000/svg">
<rect width="360" height="480" fill="#4ecdc4" rx="8"/>
<circle cx="180" cy="160" r="60" fill="rgba(255,255,255,0.8)"/>
<rect x="120" y="240" width="120" height="20" fill="rgba(255,255,255,0.8)" rx="4"/>
<rect x="140" y="270" width="80" height="16" fill="rgba(255,255,255,0.8)" rx="4"/>
<text x="180" y="400" font-family="Arial" font-size="16" fill="white" text-anchor="middle">รูปถ่ายตัวอย่าง 4</text>
</svg>

After

Width:  |  Height:  |  Size: 514 B