Compare commits
162 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7bc84cea75 | |||
| 27093bcd54 | |||
| 0ea1b98a1f | |||
| 107ef43a0e | |||
| 623b237826 | |||
| 84ab6bef2d | |||
| 6705293e50 | |||
| 01c908e919 | |||
| 6865d2d437 | |||
| e95ec68931 | |||
| 1861e10d6d | |||
| f2fa8e3c17 | |||
| c22b668bc5 | |||
| 0576677523 | |||
| c6d5a0265f | |||
| 6fea1f2be1 | |||
| c130f9bcdf | |||
| e2d9ae7541 | |||
| f4b1f7722e | |||
| 215a8f2e3f | |||
| 50680a323f | |||
| 9f9f326af9 | |||
| 668ee46ba6 | |||
| c984c14085 | |||
| f58ae2c5f7 | |||
| 21ebb9667b | |||
| 746868d720 | |||
| 4d1daa3910 | |||
| 248d73a619 | |||
| 5cefb4d161 | |||
| 8b0793c42f | |||
| b585d851dd | |||
| 7c42800245 | |||
| a3b8593133 | |||
| 3a679eb03c | |||
| cf575afc3f | |||
| a94d938131 | |||
| d230e88bd1 | |||
| 467fcbffb7 | |||
| 5c391f3dee | |||
| 7e06f7f63a | |||
| 35956d2849 | |||
| 7b3cfb5178 | |||
| 9ca29e13de | |||
| a58b0f7cdb | |||
| c340cd2eaf | |||
| b2a3e5d605 | |||
| 962201975b | |||
| 5053cbcf44 | |||
| e4240d3f02 | |||
| cdd8ccb0e5 | |||
| 72e9de96e4 | |||
| 91885d5ff5 | |||
| b8c8a1a45f | |||
| 74aa30636c | |||
| 07b83c7ae8 | |||
| 721bf65ed3 | |||
| 0505f0a641 | |||
| 5c936b2b53 | |||
| 29b1e92ea9 | |||
| a0a184236c | |||
| c02e7fb4b6 | |||
| 1da82489c6 | |||
| ce6f48f5a4 | |||
| ae529862e6 | |||
| 5011812385 | |||
| 33a665294c | |||
| be017ded2b | |||
| 9951904e6d | |||
| b4da98f40d | |||
| 5cbc7c1190 | |||
| c2476135ff | |||
| f7dab87c76 | |||
| d444bbb49a | |||
| 8253b53b6f | |||
| eaf3bd55f0 | |||
| ad6effd470 | |||
| 507d085093 | |||
| 9aa20b0da0 | |||
| 2a07aca10a | |||
| 3b52b90e5c | |||
| 861d281db4 | |||
| 278d152fc1 | |||
| 2532f69e74 | |||
| 17388229b4 | |||
| e53040d55f | |||
| f2f6397deb | |||
| 0560db4318 | |||
| f21e29dd2a | |||
| 4c81c904b1 | |||
| 6769af994f | |||
| f433386f6a | |||
| e6b2014783 | |||
| 0f8383f0a3 | |||
| 126f7b05f1 | |||
| ac2e0b75b2 | |||
| 637242021f | |||
| ae77418596 | |||
| 07c57999b3 | |||
| 6462d153e4 | |||
| 40c422c9e4 | |||
| f15aac5f17 | |||
| c83490d4c9 | |||
| dee52d9b0c | |||
| 160370eb93 | |||
| fa6a499de8 | |||
| 3e895307d9 | |||
| 0ce88f7961 | |||
| d77d46d358 | |||
| 7245e97034 | |||
| fa1e2ba5ff | |||
| 6304066cd6 | |||
| cf995f2e80 | |||
| 6e09f0a32c | |||
| ec1897f247 | |||
| 50aed702fa | |||
| 81039f5bcf | |||
| f6141b0047 | |||
| a2549ff7db | |||
| 664c95820f | |||
| 58a3275a49 | |||
| 797acae974 | |||
| 0fb4e0af5c | |||
| 537487924b | |||
| e47e495911 | |||
| b60e1044e1 | |||
| 169d1977b4 | |||
| d656f79bf2 | |||
| d019a24c3d | |||
| 681569e5b3 | |||
| 3208b58067 | |||
| c0634c0971 | |||
| a880d6bc8a | |||
| 8da66e71a9 | |||
| e74a75e3a4 | |||
| 70560553cc | |||
| aa627267cf | |||
| 75d827d912 | |||
| a8db026382 | |||
| eb203fe365 | |||
| 9302d65dcf | |||
| 2723aea2a3 | |||
| d44eb04a5a | |||
| 97d68cc5ba | |||
| 4db9d12743 | |||
| b940a47c0d | |||
| 72b5d0da7a | |||
| 95d2cbfccb | |||
| f2e1d0ea12 | |||
| 69b83e0e87 | |||
| 7148dcbe0b | |||
| 53e717fedc | |||
| 37d7563b69 | |||
| a0734d27c9 | |||
| 9400e3607e | |||
| 9faf973d03 | |||
| b3f940074f | |||
| 033addb7d8 | |||
| 759c4efeed | |||
| 34ec1f04a9 | |||
| 80126d1b36 | |||
| 82b0c8b0b0 |
65
.env.example
@ -1,49 +1,16 @@
|
||||
# ─── Square API ────────────────────────────────────────────────────────────────
|
||||
# Get these from https://developer.squareup.com/apps
|
||||
SQUARE_ACCESS_TOKEN=your_square_access_token_here
|
||||
SQUARE_LOCATION_ID=your_square_location_id_here
|
||||
# "sandbox" or "production"
|
||||
SQUARE_ENVIRONMENT=sandbox
|
||||
|
||||
# These are exposed to the browser — use your Square Application ID (not access token)
|
||||
# and the same location ID as above.
|
||||
NEXT_PUBLIC_SQUARE_APP_ID=sandbox-sq0idb-your_app_id_here
|
||||
NEXT_PUBLIC_SQUARE_LOCATION_ID=your_square_location_id_here
|
||||
# "sandbox" or "production" — controls which Square JS SDK URL is loaded
|
||||
NEXT_PUBLIC_SQUARE_ENVIRONMENT=sandbox
|
||||
# Optional: ID of a Square category (Items > Categories) whose items appear in the shop.
|
||||
# If set, only items in this category are shown. Otherwise falls back to src/config/shop-items.json.
|
||||
SQUARE_SHOP_CATEGORY_ID=
|
||||
|
||||
# ─── CalDAV (Nextcloud) ────────────────────────────────────────────────────────
|
||||
# Your Nextcloud CalDAV base URL — include trailing slash
|
||||
CALDAV_URL=https://your-nextcloud.example.com/remote.php/dav/calendars/username/
|
||||
CALDAV_USERNAME=your_nextcloud_username
|
||||
# Use an app password (Settings > Security > Devices & sessions > App passwords)
|
||||
CALDAV_PASSWORD=your_nextcloud_app_password
|
||||
# Display name of the calendar to check for Busy blocks
|
||||
CALDAV_CALENDAR_NAME=Deliveries
|
||||
|
||||
# ─── Email (SMTP — your mail server) ──────────────────────────────────────────
|
||||
SMTP_HOST=mail.beachpartyballoons.com
|
||||
SMTP_PORT=587
|
||||
SMTP_USER=shop@beachpartyballoons.com
|
||||
SMTP_PASS=your_email_password_here
|
||||
# Address that receives new-order & slot-conflict alerts (you/staff)
|
||||
ALERT_EMAIL_TO=you@beachpartyballoons.com
|
||||
# Sender shown on outgoing emails
|
||||
ALERT_EMAIL_FROM=shop@beachpartyballoons.com
|
||||
|
||||
# ─── Admin panel ───────────────────────────────────────────────────────────────
|
||||
# Password to access /admin — keep this secret
|
||||
ADMIN_PASSWORD=change_me_to_something_strong
|
||||
# Secret token for the cron cache-refresh endpoint (POST /api/cache/refresh)
|
||||
CACHE_REFRESH_SECRET=change_me_to_something_random
|
||||
|
||||
# ─── OSRM (self-hosted routing) ────────────────────────────────────────────────
|
||||
# Leave blank to use the public demo server (unreliable). Self-host for production:
|
||||
# https://hub.docker.com/r/osrm/osrm-backend
|
||||
OSRM_URL=http://localhost:5000
|
||||
|
||||
# ─── Site ──────────────────────────────────────────────────────────────────────
|
||||
NEXT_PUBLIC_SITE_URL=http://localhost:3000
|
||||
# ── Root .env (fallback for Docker Compose < v2.24) ───────────────────────────
|
||||
#
|
||||
# Docker Compose v2.24+ reads build env_file directly from estore/.env — you
|
||||
# should not need this file at all on a modern install.
|
||||
#
|
||||
# If your Compose is older and the shop shows "Online payment is not
|
||||
# configured", copy the four NEXT_PUBLIC_* lines from estore/.env into this
|
||||
# file so Compose can bake them into the Next.js build:
|
||||
#
|
||||
# NEXT_PUBLIC_SQUARE_APP_ID=
|
||||
# NEXT_PUBLIC_SQUARE_LOCATION_ID=
|
||||
# NEXT_PUBLIC_SQUARE_ENVIRONMENT=production
|
||||
# NEXT_PUBLIC_SITE_URL=https://shop.beachpartyballoons.com
|
||||
#
|
||||
# All other secrets (access tokens, passwords, etc.) belong only in estore/.env
|
||||
# — never put them here.
|
||||
|
||||
29
.gitignore
vendored
@ -1,18 +1,28 @@
|
||||
# dependencies
|
||||
# Dependencies
|
||||
node_modules/
|
||||
.pnp
|
||||
.pnp.js
|
||||
|
||||
# Next.js build output
|
||||
.next/
|
||||
out/
|
||||
# Next.js
|
||||
estore/.next/
|
||||
estore/out/
|
||||
|
||||
# Runtime data — cache and item overrides change at runtime, don't track them
|
||||
data/catalog-cache.json
|
||||
data/item-overrides.json
|
||||
# Runtime data
|
||||
estore/data/catalog-cache.json
|
||||
estore/data/item-overrides.json
|
||||
estore/data/hours.json
|
||||
estore/data/delivery-rates.json
|
||||
main-site/photo-gallery-app/backend/uploads/
|
||||
mongodb_data/
|
||||
osrm/data/*
|
||||
!osrm/data/.gitkeep
|
||||
|
||||
# Environment variables — never commit these
|
||||
# Environment variables — never commit
|
||||
.env
|
||||
.env.local
|
||||
.env*.local
|
||||
*/.env
|
||||
*/.env.local
|
||||
|
||||
# OS / editor
|
||||
.DS_Store
|
||||
@ -26,7 +36,4 @@ npm-debug.log*
|
||||
|
||||
# Misc
|
||||
.eslintcache
|
||||
|
||||
# Raw/duplicate image files — use public/images/ directly
|
||||
public/images/pics/
|
||||
*.heic
|
||||
|
||||
@ -1,26 +1,116 @@
|
||||
services:
|
||||
osrm:
|
||||
image: osrm/osrm-backend
|
||||
container_name: osrm
|
||||
restart: unless-stopped
|
||||
|
||||
# ── Nginx reverse proxy ───────────────────────────────────────────────────────
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
container_name: bpb-nginx
|
||||
ports:
|
||||
- "80:80"
|
||||
volumes:
|
||||
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
|
||||
depends_on:
|
||||
- main-site
|
||||
- estore
|
||||
restart: always
|
||||
|
||||
# ── Main website ─────────────────────────────────────────────────────────────
|
||||
main-site:
|
||||
build: ./main-site
|
||||
container_name: bpb-main
|
||||
expose:
|
||||
- "3050"
|
||||
environment:
|
||||
NODE_ENV: production
|
||||
ADMIN_PASSWORD: ${MAIN_ADMIN_PASSWORD}
|
||||
volumes:
|
||||
- ./main-site/update.json:/usr/src/app/update.json
|
||||
restart: always
|
||||
depends_on:
|
||||
- gallery-backend
|
||||
|
||||
# ── Photo gallery backend ─────────────────────────────────────────────────────
|
||||
gallery-backend:
|
||||
build: ./main-site/photo-gallery-app/backend
|
||||
container_name: bpb-gallery
|
||||
ports:
|
||||
- "5002:5000"
|
||||
environment:
|
||||
MONGO_URI: mongodb://mongodb:27017/photogallery
|
||||
WATERMARK_URL: http://watermarker:8000/watermark
|
||||
volumes:
|
||||
- ./docker/osrm/data:/data
|
||||
command: osrm-routed --algorithm mld /data/connecticut-latest.osrm
|
||||
- ./main-site/photo-gallery-app/backend/uploads:/usr/src/app/uploads
|
||||
depends_on:
|
||||
- mongodb
|
||||
- watermarker
|
||||
restart: always
|
||||
|
||||
balloons-shop:
|
||||
build: .
|
||||
container_name: balloons-shop
|
||||
# ── Watermarker ───────────────────────────────────────────────────────────────
|
||||
watermarker:
|
||||
build: ./main-site/photo-gallery-app/watermarker
|
||||
container_name: bpb-watermarker
|
||||
restart: always
|
||||
|
||||
# ── MongoDB ───────────────────────────────────────────────────────────────────
|
||||
mongodb:
|
||||
image: mongo:latest
|
||||
container_name: bpb-mongodb
|
||||
ports:
|
||||
- "3000:3000"
|
||||
env_file:
|
||||
- .env
|
||||
- "27017:27017"
|
||||
volumes:
|
||||
- ./mongodb_data:/data/db
|
||||
restart: always
|
||||
|
||||
# ── eStore (Next.js / Square) ─────────────────────────────────────────────────
|
||||
# NEXT_PUBLIC_* vars are baked into the JS bundle at build time.
|
||||
# They are resolved from the root .env file (same dir as this compose file).
|
||||
estore:
|
||||
build:
|
||||
context: ./estore
|
||||
args:
|
||||
NEXT_PUBLIC_SQUARE_APP_ID: ${NEXT_PUBLIC_SQUARE_APP_ID}
|
||||
NEXT_PUBLIC_SQUARE_LOCATION_ID: ${NEXT_PUBLIC_SQUARE_LOCATION_ID}
|
||||
NEXT_PUBLIC_SQUARE_ENVIRONMENT: ${NEXT_PUBLIC_SQUARE_ENVIRONMENT}
|
||||
NEXT_PUBLIC_SITE_URL: ${NEXT_PUBLIC_SITE_URL}
|
||||
container_name: bpb-estore
|
||||
expose:
|
||||
- "3000"
|
||||
env_file: ./estore/.env
|
||||
volumes:
|
||||
- ./estore/data:/app/data
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- osrm
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-qO-", "http://localhost:3000/api/catalog"]
|
||||
test: ["CMD", "node", "-e", "fetch('http://localhost:3000/shop/api/catalog').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
|
||||
# ── OSRM download (runs once, exits) ─────────────────────────────────────────
|
||||
# Downloads the PBF map file into the shared volume if not already present.
|
||||
osrm-download:
|
||||
build:
|
||||
context: ./osrm
|
||||
dockerfile: Dockerfile.download
|
||||
container_name: bpb-osrm-download
|
||||
volumes:
|
||||
- ./osrm/data:/data
|
||||
environment:
|
||||
OSRM_REGION: connecticut-latest
|
||||
restart: "no"
|
||||
|
||||
# ── OSRM (routing engine) ─────────────────────────────────────────────────────
|
||||
osrm:
|
||||
build: ./osrm
|
||||
container_name: bpb-osrm
|
||||
expose:
|
||||
- "5000"
|
||||
volumes:
|
||||
- ./osrm/data:/data
|
||||
environment:
|
||||
OSRM_REGION: connecticut-latest
|
||||
OSRM_PROFILE: /opt/car.lua
|
||||
depends_on:
|
||||
osrm-download:
|
||||
condition: service_completed_successfully
|
||||
restart: unless-stopped
|
||||
|
||||
49
estore/.env.example
Normal file
@ -0,0 +1,49 @@
|
||||
# ─── Square API ────────────────────────────────────────────────────────────────
|
||||
# Get these from https://developer.squareup.com/apps
|
||||
SQUARE_ACCESS_TOKEN=your_square_access_token_here
|
||||
SQUARE_LOCATION_ID=your_square_location_id_here
|
||||
# "sandbox" or "production"
|
||||
SQUARE_ENVIRONMENT=sandbox
|
||||
|
||||
# These are exposed to the browser — use your Square Application ID (not access token)
|
||||
# and the same location ID as above.
|
||||
NEXT_PUBLIC_SQUARE_APP_ID=sandbox-sq0idb-your_app_id_here
|
||||
NEXT_PUBLIC_SQUARE_LOCATION_ID=your_square_location_id_here
|
||||
# "sandbox" or "production" — controls which Square JS SDK URL is loaded
|
||||
NEXT_PUBLIC_SQUARE_ENVIRONMENT=sandbox
|
||||
# Optional: ID of a Square category (Items > Categories) whose items appear in the shop.
|
||||
# If set, only items in this category are shown. Otherwise falls back to src/config/shop-items.json.
|
||||
SQUARE_SHOP_CATEGORY_ID=
|
||||
|
||||
# ─── CalDAV (Nextcloud) ────────────────────────────────────────────────────────
|
||||
# Your Nextcloud CalDAV base URL — include trailing slash
|
||||
CALDAV_URL=https://your-nextcloud.example.com/remote.php/dav/calendars/username/
|
||||
CALDAV_USERNAME=your_nextcloud_username
|
||||
# Use an app password (Settings > Security > Devices & sessions > App passwords)
|
||||
CALDAV_PASSWORD=your_nextcloud_app_password
|
||||
# Display name of the calendar to check for Busy blocks
|
||||
CALDAV_CALENDAR_NAME=Deliveries
|
||||
|
||||
# ─── Email (SMTP — your mail server) ──────────────────────────────────────────
|
||||
SMTP_HOST=mail.beachpartyballoons.com
|
||||
SMTP_PORT=587
|
||||
SMTP_USER=shop@beachpartyballoons.com
|
||||
SMTP_PASS=your_email_password_here
|
||||
# Address that receives new-order & slot-conflict alerts (you/staff)
|
||||
ALERT_EMAIL_TO=you@beachpartyballoons.com
|
||||
# Sender shown on outgoing emails
|
||||
ALERT_EMAIL_FROM=shop@beachpartyballoons.com
|
||||
|
||||
# ─── Admin panel ───────────────────────────────────────────────────────────────
|
||||
# Password to access /admin — keep this secret
|
||||
ADMIN_PASSWORD=change_me_to_something_strong
|
||||
# Secret token for the cron cache-refresh endpoint (POST /api/cache/refresh)
|
||||
CACHE_REFRESH_SECRET=change_me_to_something_random
|
||||
|
||||
# ─── OSRM (self-hosted routing) ────────────────────────────────────────────────
|
||||
# Leave blank to use the public demo server (unreliable). Self-host for production:
|
||||
# https://hub.docker.com/r/osrm/osrm-backend
|
||||
OSRM_URL=http://localhost:5000
|
||||
|
||||
# ─── Site ──────────────────────────────────────────────────────────────────────
|
||||
NEXT_PUBLIC_SITE_URL=http://localhost:3000
|
||||
32
estore/.gitignore
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
# dependencies
|
||||
node_modules/
|
||||
|
||||
# Next.js build output
|
||||
.next/
|
||||
out/
|
||||
|
||||
# Runtime data — cache and item overrides change at runtime, don't track them
|
||||
data/catalog-cache.json
|
||||
data/item-overrides.json
|
||||
|
||||
# Environment variables — never commit these
|
||||
.env
|
||||
.env.local
|
||||
.env*.local
|
||||
|
||||
# OS / editor
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
.vscode/
|
||||
.idea/
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
|
||||
# Misc
|
||||
.eslintcache
|
||||
|
||||
# Raw/duplicate image files — use public/images/ directly
|
||||
public/images/pics/
|
||||
*.heic
|
||||
@ -10,6 +10,18 @@ WORKDIR /app
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
COPY . .
|
||||
ENV NEXT_TELEMETRY_DISABLED=1
|
||||
|
||||
# NEXT_PUBLIC_* vars are baked into the JS bundle at build time.
|
||||
# Pass them as build args from your .env so they're available here.
|
||||
ARG NEXT_PUBLIC_SQUARE_APP_ID
|
||||
ARG NEXT_PUBLIC_SQUARE_LOCATION_ID
|
||||
ARG NEXT_PUBLIC_SQUARE_ENVIRONMENT
|
||||
ARG NEXT_PUBLIC_SITE_URL
|
||||
ENV NEXT_PUBLIC_SQUARE_APP_ID=$NEXT_PUBLIC_SQUARE_APP_ID
|
||||
ENV NEXT_PUBLIC_SQUARE_LOCATION_ID=$NEXT_PUBLIC_SQUARE_LOCATION_ID
|
||||
ENV NEXT_PUBLIC_SQUARE_ENVIRONMENT=$NEXT_PUBLIC_SQUARE_ENVIRONMENT
|
||||
ENV NEXT_PUBLIC_SITE_URL=$NEXT_PUBLIC_SITE_URL
|
||||
|
||||
RUN npm run build
|
||||
|
||||
# ── Stage 3: Production runner ────────────────────────────────────────────────
|
||||
@ -26,6 +38,11 @@ COPY --from=builder /app/public ./public
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||
|
||||
# Ensure the data directory exists and is writable by the nextjs user.
|
||||
# For bind-mount deployments, the host directory must also be owned by uid 1001:
|
||||
# sudo chown -R 1001:1001 estore/data
|
||||
RUN mkdir -p /app/data && chown nextjs:nodejs /app/data
|
||||
|
||||
USER nextjs
|
||||
EXPOSE 3000
|
||||
ENV PORT=3000
|
||||
11
estore/data/categories-display.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"order": [
|
||||
"latex",
|
||||
"birthday",
|
||||
"mylar-bouquets",
|
||||
"graduation",
|
||||
"letters-and-numbers",
|
||||
"other"
|
||||
],
|
||||
"hidden": []
|
||||
}
|
||||
8
estore/data/occasions.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"mothers-day": {
|
||||
"windowStart": "04-10"
|
||||
},
|
||||
"graduation": {
|
||||
"windowStart": "04-01"
|
||||
}
|
||||
}
|
||||
26
estore/docker-compose.yml
Normal file
@ -0,0 +1,26 @@
|
||||
services:
|
||||
osrm:
|
||||
image: osrm/osrm-backend
|
||||
container_name: osrm
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "5002:5000"
|
||||
volumes:
|
||||
- ./docker/osrm/data:/data
|
||||
command: osrm-routed --algorithm mld /data/connecticut-latest.osrm
|
||||
|
||||
balloons-shop:
|
||||
build: .
|
||||
container_name: balloons-shop
|
||||
ports:
|
||||
- "3000:3000"
|
||||
env_file:
|
||||
- .env
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- osrm
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-qO-", "http://localhost:3000/api/catalog"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
0
next-env.d.ts → estore/next-env.d.ts
vendored
@ -3,6 +3,10 @@ const isDev = process.env.NODE_ENV === 'development'
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
output: 'standalone',
|
||||
basePath: '/shop',
|
||||
env: {
|
||||
NEXT_PUBLIC_BASE_PATH: '/shop',
|
||||
},
|
||||
images: {
|
||||
remotePatterns: [
|
||||
{ protocol: 'https', hostname: 'items-images-production.s3.us-west-2.amazonaws.com' },
|
||||
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 228 KiB After Width: | Height: | Size: 228 KiB |
|
Before Width: | Height: | Size: 149 KiB After Width: | Height: | Size: 149 KiB |
|
Before Width: | Height: | Size: 160 KiB After Width: | Height: | Size: 160 KiB |
|
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 136 KiB |
|
Before Width: | Height: | Size: 143 KiB After Width: | Height: | Size: 143 KiB |
|
Before Width: | Height: | Size: 2.4 MiB After Width: | Height: | Size: 2.4 MiB |
|
Before Width: | Height: | Size: 134 KiB After Width: | Height: | Size: 134 KiB |
|
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 114 KiB |
|
Before Width: | Height: | Size: 164 KiB After Width: | Height: | Size: 164 KiB |
|
Before Width: | Height: | Size: 130 KiB After Width: | Height: | Size: 130 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 180 KiB After Width: | Height: | Size: 180 KiB |
|
Before Width: | Height: | Size: 149 KiB After Width: | Height: | Size: 149 KiB |
|
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 85 KiB |
|
Before Width: | Height: | Size: 123 KiB After Width: | Height: | Size: 123 KiB |
|
Before Width: | Height: | Size: 146 KiB After Width: | Height: | Size: 146 KiB |
|
Before Width: | Height: | Size: 225 KiB After Width: | Height: | Size: 225 KiB |
|
Before Width: | Height: | Size: 521 KiB After Width: | Height: | Size: 521 KiB |
|
Before Width: | Height: | Size: 213 KiB After Width: | Height: | Size: 213 KiB |
|
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 126 KiB |
|
Before Width: | Height: | Size: 143 KiB After Width: | Height: | Size: 143 KiB |
|
Before Width: | Height: | Size: 137 KiB After Width: | Height: | Size: 137 KiB |
|
Before Width: | Height: | Size: 109 KiB After Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 515 B After Width: | Height: | Size: 515 B |
|
Before Width: | Height: | Size: 515 B After Width: | Height: | Size: 515 B |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 738 B After Width: | Height: | Size: 738 B |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 932 KiB After Width: | Height: | Size: 932 KiB |
|
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 1.5 MiB |
|
Before Width: | Height: | Size: 877 KiB After Width: | Height: | Size: 877 KiB |
|
Before Width: | Height: | Size: 2.2 MiB After Width: | Height: | Size: 2.2 MiB |
|
Before Width: | Height: | Size: 827 KiB After Width: | Height: | Size: 827 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 738 B After Width: | Height: | Size: 738 B |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 689 KiB After Width: | Height: | Size: 689 KiB |
|
Before Width: | Height: | Size: 2.8 MiB After Width: | Height: | Size: 2.8 MiB |
|
Before Width: | Height: | Size: 3.2 MiB After Width: | Height: | Size: 3.2 MiB |
|
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 1.7 MiB After Width: | Height: | Size: 1.7 MiB |
|
Before Width: | Height: | Size: 890 KiB After Width: | Height: | Size: 890 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 890 KiB After Width: | Height: | Size: 890 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 519 KiB After Width: | Height: | Size: 519 KiB |
|
Before Width: | Height: | Size: 739 KiB After Width: | Height: | Size: 739 KiB |
|
Before Width: | Height: | Size: 2.0 MiB After Width: | Height: | Size: 2.0 MiB |
|
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.3 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |