FeaturesTemplatesShowcaseTownie
AI
BlogDocsPricing
Log inSign up
devto
devtoadportal
Unlisted
Like
adportal
Home
Code
9
api
4
controllers
2
models
2
public
5
services
5
utils
2
views
2
README.md
H
index.ts
Branches
2
Pull requests
Remixes
History
Environment variables
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in miliseconds.
Sign up now
Code
/
README.md
Code
/
README.md
Search
…
Viewing readonly version: 206
View latest version
README.md@206

LauraMepson Landing Page

A landing page application that collects company information and allows users to add additional details through email links.

Features

  • Simple landing page with LauraMepson branding
  • Form to collect company name and email
  • SQLite database storage for submissions
  • Email functionality to send users a unique link
  • Continuation page for adding more information
  • Image upload and storage using Uploadcare

Uploadcare Group Fix

This project includes solutions for handling Uploadcare image uploads, specifically addressing the issue where multi-file uploads create groups instead of individual files.

The Problem

When using Uploadcare's multi-file uploader, files are grouped together with a UUID like: cb08730c-9c8b-46bb-a79e-9ab0f228939e~1

To access individual files, you need to use the /nth/0/ syntax, which can be cumbersome and doesn't give you direct access to individual file UUIDs.

Solutions

Two solutions are provided:

  1. Use Single File Uploaders: Configure Uploadcare widgets to upload one file at a time
  2. Extract Individual Files from Groups: Use the multi-file uploader but extract individual file UUIDs

Demo Pages

  • /public/uploadcare-demo.html - A comprehensive demo showing both problems and solutions
  • /public/uploadcare-fix.html - A focused solution with implementation guide
  • /public/single-file-demo.html - A demo of the single file uploader solution

Implementation

The single file uploader solution has been implemented in the main application:

  1. Changed UPLOADCARE_MULTIPLE to false in the global configuration
  2. Replaced the multi-file uploader with multiple single file uploaders
  3. Updated the JavaScript to handle individual file uploads
  4. Added a helper script (/public/js/uploadcare-helper.js) with utility functions

Project Structure

├── api/                  # API route handlers
│   ├── images.ts         # Image-related API endpoints
│   ├── submissions.ts    # Submission-related API endpoints
│   └── index.ts          # API routes configuration
├── controllers/          # Request handling logic
│   ├── imageController.ts # Image upload/retrieval logic
│   └── submissionController.ts # Submission handling logic
├── models/               # Data models and types
│   ├── image.ts          # Image-related types
│   └── submission.ts     # Submission-related types
├── services/             # Business logic
│   ├── imageService.ts   # Image metadata operations
│   ├── uploadcareService.ts # Uploadcare integration
│   ├── databaseService.ts # Database operations
│   ├── emailService.ts   # Email sending functionality
│   └── templateService.ts # HTML template rendering
├── utils/                # Utility functions
│   ├── helpers.ts        # Helper functions
│   └── responseUtils.ts  # Standardized API responses
├── views/                # HTML templates
│   ├── landing.html      # Main landing page
│   └── continue.html     # Continuation page
├── public/               # Static assets and client-side JS
│   ├── css/              # Stylesheets
│   │   └── styles.css    # Common styles
│   └── js/               # Client-side JavaScript
│       ├── landing.js    # Landing page script
│       └── continue.js   # Continuation page script
└── index.ts              # Main entry point

Database Schema

The application uses a SQLite database with the following schemas:

Submissions Table

CREATE TABLE IF NOT EXISTS laura_mepson_submissions_v1 ( id TEXT PRIMARY KEY, company_name TEXT NOT NULL, email TEXT NOT NULL, created_at TEXT NOT NULL, additional_fields TEXT )

Images Table

CREATE TABLE IF NOT EXISTS laura_mepson_images_v1 ( id TEXT PRIMARY KEY, original_name TEXT NOT NULL, content_type TEXT NOT NULL, size INTEGER NOT NULL, uploaded_at TEXT NOT NULL, submission_id TEXT NOT NULL, cdn_url TEXT NOT NULL )

User Flow

  1. User visits the landing page
  2. User submits company name and email
  3. Data is saved to SQLite database
  4. User receives an email with a unique link
  5. User can click the link to add more information
  6. Additional information is saved to the database
  7. User can upload and manage images related to their submission

URL Structure

  • Main landing page: https://[username].web.val.run
  • Continuation page: https://[username].web.val.run?action=continue&id=[unique_id]

Image Storage

Images are stored using Uploadcare:

  • Uploadcare handles file uploads, storage, and CDN delivery
  • Uploadcare's built-in image preview and cropping tools are used
  • Image metadata is stored in our SQLite database
  • Users can upload, view, and delete images
  • Images are associated with a specific submission

Environment Variables

  • UPLOADCARE_SECRET_KEY: Secret key for Uploadcare API authentication

Development Notes

  • When modifying the database schema, create a new table with a new version number
  • Email templates are defined in emailService.ts
  • The unique ID generation is handled in utils/helpers.ts
  • Val Town HTTP vals use query parameters instead of path parameters for routing

Database Schema

The application uses a SQLite database with the following schema:

CREATE TABLE IF NOT EXISTS laura_mepson_submissions_v1 ( id TEXT PRIMARY KEY, company_name TEXT NOT NULL, email TEXT NOT NULL, created_at TEXT NOT NULL, additional_fields TEXT )

User Flow

  1. User visits the landing page
  2. User submits company name and email
  3. Data is saved to SQLite database
  4. User receives an email with a unique link
  5. User can click the link to add more information
  6. Additional information is saved to the database
  7. User can upload and manage images related to their submission

URL Structure

  • Main landing page: https://[username].web.val.run
  • Continuation page: https://[username].web.val.run?action=continue&id=[unique_id]

Image Storage

Images are stored using Val Town's blob storage:

  • Images are stored with a unique ID
  • Metadata is stored alongside each image
  • Users can upload, view, and delete images
  • Images are associated with a specific submission

Development Notes

  • When modifying the database schema, create a new table with a new version number
  • Email templates are defined in email.ts
  • The unique ID generation is handled in utils.ts
  • Val Town HTTP vals use query parameters instead of path parameters for routing
Go to top
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Product
FeaturesPricing
Developers
DocsStatusAPI ExamplesNPM Package Examples
Explore
ShowcaseTemplatesNewest ValsTrending ValsNewsletter
Company
AboutBlogCareersBrandhi@val.town
Terms of usePrivacy policyAbuse contact
© 2025 Val Town, Inc.