From 394b9187b35d877ca12d00da54c94fa07f7d5556 Mon Sep 17 00:00:00 2001 From: Greg Konush <12027037+gregkonush@users.noreply.github.com> Date: Mon, 23 Dec 2024 18:46:19 -0800 Subject: [PATCH] feat: add map with locations and deployment (#636) * feat: add map with locations and deployment * add build scripts * update output * add secret --- .github/workflows/docker-build-push.yaml | 17 +- .github/workflows/pull-request.yml | 35 +- apps/findbobastore/Dockerfile | 39 ++ apps/findbobastore/next.config.ts | 3 +- apps/findbobastore/package.json | 14 +- apps/findbobastore/src/app/layout.tsx | 4 +- apps/findbobastore/src/app/page.tsx | 11 +- .../src/components/map-container.tsx | 16 + .../findbobastore/src/components/map-view.tsx | 381 ++++++++++++++++++ apps/findbobastore/src/lib/utils.ts | 6 + apps/proompteng/Dockerfile | 2 +- .../findbobastore/deployment.yaml | 34 ++ .../applications/findbobastore/ingress.yaml | 17 + .../findbobastore/kustomization.yaml | 10 + .../applications/findbobastore/secrets.yaml | 32 ++ .../applications/findbobastore/service.yaml | 11 + package.json | 12 +- pnpm-lock.yaml | 226 +++++++++++ scripts/build-findbobastore.sh | 29 ++ 19 files changed, 877 insertions(+), 22 deletions(-) create mode 100644 apps/findbobastore/Dockerfile create mode 100644 apps/findbobastore/src/components/map-container.tsx create mode 100644 apps/findbobastore/src/components/map-view.tsx create mode 100644 apps/findbobastore/src/lib/utils.ts create mode 100644 argocd/applications/findbobastore/deployment.yaml create mode 100644 argocd/applications/findbobastore/ingress.yaml create mode 100644 argocd/applications/findbobastore/kustomization.yaml create mode 100644 argocd/applications/findbobastore/secrets.yaml create mode 100644 argocd/applications/findbobastore/service.yaml create mode 100755 scripts/build-findbobastore.sh diff --git a/.github/workflows/docker-build-push.yaml b/.github/workflows/docker-build-push.yaml index ac50133..4897bdb 100644 --- a/.github/workflows/docker-build-push.yaml +++ b/.github/workflows/docker-build-push.yaml @@ -3,9 +3,10 @@ name: Docker Build and Push on: push: branches: - - "main" + - 'main' paths: - - "apps/proompteng/**" + - 'apps/proompteng/**' + - 'apps/findbobastore/**' jobs: version: @@ -41,3 +42,15 @@ jobs: secrets: REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }} REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }} + + build-findbobastore: + needs: version + uses: ./.github/workflows/docker-build-common.yaml + with: + image_name: findbobastore + dockerfile: ./apps/findbobastore/Dockerfile + context: . + new_tag: ${{ needs.version.outputs.new_tag }} + secrets: + REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }} + REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }} diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 76de617..1cd7281 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -11,7 +11,7 @@ concurrency: cancel-in-progress: true jobs: - main: + proompteng: runs-on: arc-arm64 steps: - uses: actions/checkout@v4 @@ -26,12 +26,39 @@ jobs: cache: 'pnpm' - run: pnpm install --frozen-lockfile + - uses: actions/cache@v4 with: path: | ${{ github.workspace }}/apps/proompteng/.next/cache - key: ${{ runner.os }}-nextjs-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }} + key: ${{ runner.os }}-nextjs-proompteng-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }} + restore-keys: | + ${{ runner.os }}-nextjs-proompteng-${{ hashFiles('**/pnpm-lock.yaml') }}- + + - run: pnpm --filter proompteng build + + findbobastore: + runs-on: arc-arm64 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - uses: pnpm/action-setup@v4 + + - uses: actions/setup-node@v4 + with: + node-version: 22.12.0 + cache: 'pnpm' + + - run: pnpm install --frozen-lockfile + + - uses: actions/cache@v4 + with: + path: | + ${{ github.workspace }}/apps/findbobastore/.next/cache + key: ${{ runner.os }}-nextjs-findbobastore-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }} restore-keys: | - ${{ runner.os }}-nextjs-${{ hashFiles('**/pnpm-lock.yaml') }}- + ${{ runner.os }}-nextjs-findbobastore-${{ hashFiles('**/pnpm-lock.yaml') }}- - - run: pnpm build + - run: pnpm --filter findbobastore build diff --git a/apps/findbobastore/Dockerfile b/apps/findbobastore/Dockerfile new file mode 100644 index 0000000..cdf288d --- /dev/null +++ b/apps/findbobastore/Dockerfile @@ -0,0 +1,39 @@ +FROM node:lts-alpine AS deps +WORKDIR /app +COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc ./ +COPY apps/findbobastore/package.json ./apps/findbobastore/ +ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0 +RUN corepack enable +RUN pnpm install --frozen-lockfile + +FROM node:lts-alpine AS builder +WORKDIR /app +ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0 +RUN corepack enable +COPY --from=deps /app/node_modules ./node_modules +COPY --from=deps /app/apps/findbobastore/node_modules ./apps/findbobastore/node_modules +COPY . . +RUN pnpm build:findbobastore + +FROM node:lts-alpine AS runner +WORKDIR /app + +ENV NODE_ENV=production +ENV NEXT_TELEMETRY_DISABLED=1 + +RUN addgroup --system --gid 1001 nodejs && \ + adduser --system --uid 1001 nextjs + +COPY --from=builder --chown=nextjs:nodejs /app/apps/findbobastore/.next/standalone /app +COPY --from=builder --chown=nextjs:nodejs /app/apps/findbobastore/.next/static /app/apps/findbobastore/.next/static +COPY --from=builder --chown=nextjs:nodejs /app/apps/findbobastore/public /app/apps/findbobastore/public + +USER nextjs + +EXPOSE 3000 + +ENV PORT=3000 +ENV HOSTNAME="0.0.0.0" + +WORKDIR /app/apps/findbobastore +CMD ["node", "server.js"] diff --git a/apps/findbobastore/next.config.ts b/apps/findbobastore/next.config.ts index 7329063..6fa33f5 100644 --- a/apps/findbobastore/next.config.ts +++ b/apps/findbobastore/next.config.ts @@ -1,7 +1,8 @@ import type { NextConfig } from 'next' const nextConfig: NextConfig = { - /* config options here */ + output: 'standalone', + poweredByHeader: false, } export default nextConfig diff --git a/apps/findbobastore/package.json b/apps/findbobastore/package.json index 6544fb3..8ee59ed 100644 --- a/apps/findbobastore/package.json +++ b/apps/findbobastore/package.json @@ -9,19 +9,23 @@ "lint": "next lint" }, "dependencies": { + "clsx": "^2.1.1", + "framer-motion": "^11.15.0", + "mapbox-gl": "^3.9.1", + "next": "15.1.2", "react": "^19.0.0", "react-dom": "^19.0.0", - "next": "15.1.2" + "tailwind-merge": "^2.5.5" }, "devDependencies": { - "typescript": "^5", + "@eslint/eslintrc": "^3", "@types/node": "^20", "@types/react": "^19", "@types/react-dom": "^19", - "postcss": "^8", - "tailwindcss": "^3.4.1", "eslint": "^9", "eslint-config-next": "15.1.2", - "@eslint/eslintrc": "^3" + "postcss": "^8", + "tailwindcss": "^3.4.1", + "typescript": "^5" } } diff --git a/apps/findbobastore/src/app/layout.tsx b/apps/findbobastore/src/app/layout.tsx index b0626eb..32800f1 100644 --- a/apps/findbobastore/src/app/layout.tsx +++ b/apps/findbobastore/src/app/layout.tsx @@ -13,8 +13,8 @@ const geistMono = Geist_Mono({ }) export const metadata: Metadata = { - title: 'Create Next App', - description: 'Generated by create next app', + title: 'Find Boba Store', + description: 'Find Boba Store', } export default function RootLayout({ diff --git a/apps/findbobastore/src/app/page.tsx b/apps/findbobastore/src/app/page.tsx index 44f7610..49310b4 100644 --- a/apps/findbobastore/src/app/page.tsx +++ b/apps/findbobastore/src/app/page.tsx @@ -1,7 +1,12 @@ +import { MapContainer } from '@/components/map-container' + export default function Home() { return ( -
-
Find Boba Store
-
+
+
+

Find Boba Store

+
+ +
) } diff --git a/apps/findbobastore/src/components/map-container.tsx b/apps/findbobastore/src/components/map-container.tsx new file mode 100644 index 0000000..65e96cc --- /dev/null +++ b/apps/findbobastore/src/components/map-container.tsx @@ -0,0 +1,16 @@ +'use client' + +import dynamic from 'next/dynamic' + +const MapView = dynamic(() => import('./map-view'), { + ssr: false, + loading: () => ( +
+
Loading map...
+
+ ), +}) + +export function MapContainer() { + return +} diff --git a/apps/findbobastore/src/components/map-view.tsx b/apps/findbobastore/src/components/map-view.tsx new file mode 100644 index 0000000..061f263 --- /dev/null +++ b/apps/findbobastore/src/components/map-view.tsx @@ -0,0 +1,381 @@ +import { useCallback, useEffect, useRef, memo, useState } from 'react' +import mapboxgl from 'mapbox-gl' +import { motion, AnimatePresence } from 'framer-motion' +import { cn } from '../lib/utils' +import 'mapbox-gl/dist/mapbox-gl.css' + +const MAPBOX_ACCESS_TOKEN = process.env.NEXT_PUBLIC_MAPBOX_ACCESS_TOKEN + +if (!MAPBOX_ACCESS_TOKEN) { + throw new Error('Missing NEXT_PUBLIC_MAPBOX_ACCESS_TOKEN') +} + +mapboxgl.accessToken = MAPBOX_ACCESS_TOKEN + +interface BobaStore { + id: string + name: string + coordinates: [number, number] + rating: number + address: string +} + +const mockBobaStores: BobaStore[] = [ + { + id: '1', + name: 'Urban Ritual', + coordinates: [-122.426, 37.553], + rating: 4.8, + address: '140 South B St, San Mateo, CA 94401', + }, + { + id: '2', + name: 'Tea Hut', + coordinates: [-122.4862, 37.7324], + rating: 4.5, + address: '1541 Sloat Blvd, San Francisco, CA 94132', + }, + { + id: '3', + name: 'District Tea', + coordinates: [-122.4194, 37.7749], + rating: 4.3, + address: '2154 Mission St, San Francisco, CA 94110', + }, + { + id: '4', + name: 'Plentea', + coordinates: [-122.4044, 37.7946], + rating: 4.7, + address: '341 Kearny St, San Francisco, CA 94108', + }, + { + id: '5', + name: 'Boba Guys', + coordinates: [-122.4194, 37.7649], + rating: 4.0, + address: '3491 19th St, San Francisco, CA 94110', + }, + { + id: '6', + name: 'Purple Kow', + coordinates: [-122.4862, 37.7857], + rating: 4.5, + address: '3620 Balboa St, San Francisco, CA 94121', + }, + { + id: '7', + name: 'Little Sweet', + coordinates: [-122.475, 37.779], + rating: 4.2, + address: '3836 Geary Blvd, San Francisco, CA', + }, + { + id: '8', + name: 'Honeybear Boba', + coordinates: [-122.4194, 37.7749], + rating: 4.2, + address: '801 22nd St, San Francisco, CA 94107', + }, + { + id: '9', + name: 'Yi Fang Taiwan Fruit Tea', + coordinates: [-122.4194, 37.7849], + rating: 4.5, + address: '950 E 3rd St Unit 2A, Los Angeles, CA 90013', + }, + { + id: '10', + name: 'Lady Luck Cafe', + coordinates: [-122.4064, 37.7946], + rating: 4.5, + address: '956 Grant Ave, San Francisco, CA 94108', + }, + { + id: '11', + name: 'Boba Bliss', + coordinates: [-122.1089, 37.4006], + rating: 4.6, + address: '685 San Antonio Rd Suite 15, Mountain View, CA 94040', + }, + { + id: '12', + name: 'Ume Tea', + coordinates: [-122.075, 37.3894], + rating: 4.4, + address: '220 Castro St, Mountain View, CA 94041', + }, + { + id: '13', + name: 'Tea Era', + coordinates: [-122.075, 37.3894], + rating: 4.3, + address: '271 Castro St, Mountain View, CA 94041', + }, + { + id: '14', + name: 'Teaspoon', + coordinates: [-122.075, 37.3894], + rating: 4.2, + address: '134A Castro St, Mountain View, CA 94041', + }, + { + id: '15', + name: 'FENG CHA', + coordinates: [-122.0891, 37.3894], + rating: 4.8, + address: '1040 Grant Rd Suite #350, Mountain View, CA 94040', + }, + { + id: '16', + name: 'Happy Lemon', + coordinates: [-122.075, 37.3894], + rating: 4.0, + address: '742 Villa St, Mountain View, CA 94041', + }, + { + id: '17', + name: 'Alma Dessert', + coordinates: [-122.0307, 37.3774], + rating: 4.8, + address: '165 S Murphy Ave Suite D, Sunnyvale, CA 94086', + }, + { + id: '18', + name: 'Molly Tea', + coordinates: [-122.0317, 37.3784], + rating: 4.6, + address: '605 E El Camino Real Suite 1, Sunnyvale, CA 94087', + }, + { + id: '19', + name: 'TP TEA Sunnyvale', + coordinates: [-122.0297, 37.3764], + rating: 4.7, + address: '567b E El Camino Real, Sunnyvale, CA 94087', + }, + { + id: '20', + name: 'R&B Tea Sunnyvale', + coordinates: [-122.0327, 37.3794], + rating: 4.1, + address: '568 E El Camino Real ste a, Sunnyvale, CA 94087', + }, + { + id: '21', + name: 'Teazzi Tea Shop', + coordinates: [-122.0287, 37.3754], + rating: 4.2, + address: '200 W McKinley Ave #105, Sunnyvale, CA 94086', + }, + { + id: '22', + name: 'MOOMO TEA', + coordinates: [-122.0337, 37.3804], + rating: 4.6, + address: '715 Sunnyvale Saratoga Rd, Sunnyvale, CA 94087', + }, + { + id: '23', + name: 'Chun Yang Tea', + coordinates: [-122.0277, 37.3744], + rating: 4.0, + address: '1120 Kifer Rd Suite C, Sunnyvale, CA 94086', + }, + { + id: '24', + name: 'Sunright Tea Studio', + coordinates: [-122.0347, 37.3814], + rating: 4.4, + address: '795 E El Camino Real, Sunnyvale, CA 94087', + }, + { + id: '25', + name: 'Boba Drive', + coordinates: [-122.0267, 37.3734], + rating: 4.5, + address: '677 Tasman Dr, Sunnyvale, CA 94089', + }, +] + +function MapOverlay({ store }: { store: BobaStore | null }) { + if (!store) return null + + return ( + + +

{store.name}

+
+

Rating: {store.rating.toFixed(1)} ⭐️

+

{store.address}

+
+
+
+ ) +} + +export function MapView() { + const mapContainer = useRef(null) + const map = useRef(null) + const [selectedStore, setSelectedStore] = useState(null) + const markersRef = useRef([]) + const [locationError, setLocationError] = useState(null) + + const clearMarkers = useCallback(() => { + for (const marker of markersRef.current) { + marker.remove() + } + markersRef.current = [] + }, []) + + const addUserLocationMarker = useCallback((location: [number, number]) => { + if (!map.current) return + + const el = document.createElement('div') + el.className = 'user-location-marker' + el.innerHTML = '📍' + el.style.fontSize = '2rem' + el.setAttribute('aria-label', 'Your location') + + const marker = new mapboxgl.Marker({ element: el }).setLngLat(location).addTo(map.current) + markersRef.current.push(marker) + }, []) + + const addBobaMarkers = useCallback(() => { + if (!map.current) return + + for (const store of mockBobaStores) { + const el = document.createElement('div') + el.className = 'boba-marker' + el.innerHTML = '🧋' + el.style.fontSize = '2rem' + el.style.cursor = 'pointer' + el.setAttribute('aria-label', `${store.name} location marker`) + + const marker = new mapboxgl.Marker({ element: el }).setLngLat(store.coordinates).addTo(map.current) + + el.addEventListener('click', () => { + setSelectedStore(store) + map.current?.flyTo({ + center: store.coordinates, + zoom: 15, + duration: 1500, + essential: true, + }) + }) + + markersRef.current.push(marker) + } + }, []) + + const getUserLocation = useCallback(() => { + return new Promise<[number, number]>((resolve, reject) => { + if (!navigator.geolocation) { + reject(new Error('Geolocation is not supported by your browser')) + return + } + + navigator.geolocation.getCurrentPosition( + (position) => { + resolve([position.coords.longitude, position.coords.latitude]) + }, + (error) => { + reject(error) + }, + { + enableHighAccuracy: true, + timeout: 5000, + maximumAge: 0, + }, + ) + }) + }, []) + + const initializeMap = useCallback(async () => { + if (!mapContainer.current) return + + try { + // Try to get user location first + const location = await getUserLocation() + + map.current = new mapboxgl.Map({ + container: mapContainer.current, + style: 'mapbox://styles/mapbox/dark-v11', + center: location, + zoom: 12, + maxZoom: 15, + }) + + map.current.on('load', () => { + clearMarkers() + addUserLocationMarker(location) + addBobaMarkers() + }) + } catch (error) { + setLocationError(error instanceof Error ? error.message : 'Failed to get location') + + // Fall back to showing all stores if location access fails + const bounds = new mapboxgl.LngLatBounds() + for (const store of mockBobaStores) { + bounds.extend(store.coordinates) + } + + map.current = new mapboxgl.Map({ + container: mapContainer.current, + style: 'mapbox://styles/mapbox/dark-v11', + bounds: bounds, + fitBoundsOptions: { padding: 50 }, + maxZoom: 15, + }) + + map.current.on('load', () => { + clearMarkers() + addBobaMarkers() + }) + } + + map.current.addControl(new mapboxgl.NavigationControl(), 'top-right') + map.current.addControl( + new mapboxgl.GeolocateControl({ + positionOptions: { + enableHighAccuracy: true, + }, + trackUserLocation: true, + }), + ) + }, [getUserLocation, clearMarkers, addUserLocationMarker, addBobaMarkers]) + + useEffect(() => { + if (!map.current) { + initializeMap() + } + + return () => { + if (map.current) { + clearMarkers() + map.current.remove() + map.current = null + } + } + }, [initializeMap, clearMarkers]) + + return ( +
+
+ + {locationError &&
{locationError}
} +
+ ) +} + +export default memo(MapView) diff --git a/apps/findbobastore/src/lib/utils.ts b/apps/findbobastore/src/lib/utils.ts new file mode 100644 index 0000000..d32b0fe --- /dev/null +++ b/apps/findbobastore/src/lib/utils.ts @@ -0,0 +1,6 @@ +import { type ClassValue, clsx } from 'clsx' +import { twMerge } from 'tailwind-merge' + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)) +} diff --git a/apps/proompteng/Dockerfile b/apps/proompteng/Dockerfile index 5af5bcb..803e189 100644 --- a/apps/proompteng/Dockerfile +++ b/apps/proompteng/Dockerfile @@ -13,7 +13,7 @@ RUN corepack enable COPY --from=deps /app/node_modules ./node_modules COPY --from=deps /app/apps/proompteng/node_modules ./apps/proompteng/node_modules COPY . . -RUN pnpm build +RUN pnpm build:proompteng FROM node:lts-alpine AS runner WORKDIR /app diff --git a/argocd/applications/findbobastore/deployment.yaml b/argocd/applications/findbobastore/deployment.yaml new file mode 100644 index 0000000..421a8d9 --- /dev/null +++ b/argocd/applications/findbobastore/deployment.yaml @@ -0,0 +1,34 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: findbobastore + namespace: findbobastore +spec: + selector: + matchLabels: + app: findbobastore + template: + metadata: + labels: + app: findbobastore + spec: + imagePullSecrets: + - name: kalmyk-registry + containers: + - name: findbobastore + image: kalmyk.duckdns.org/lab/findbobastore + resources: + limits: + cpu: '1' + memory: '512Mi' + requests: + cpu: '200m' + memory: '256Mi' + ports: + - containerPort: 3000 + env: + - name: NEXT_PUBLIC_MAPBOX_ACCESS_TOKEN + valueFrom: + secretKeyRef: + name: mapbox-token + key: token diff --git a/argocd/applications/findbobastore/ingress.yaml b/argocd/applications/findbobastore/ingress.yaml new file mode 100644 index 0000000..4e826a4 --- /dev/null +++ b/argocd/applications/findbobastore/ingress.yaml @@ -0,0 +1,17 @@ +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRoute +metadata: + name: findbobastore + namespace: findbobastore +spec: + entryPoints: + - web + - websecure + routes: + - kind: Rule + match: Host(`findboba.store`) + services: + - name: findbobastore + port: 80 + tls: + certResolver: default diff --git a/argocd/applications/findbobastore/kustomization.yaml b/argocd/applications/findbobastore/kustomization.yaml new file mode 100644 index 0000000..99bf3fb --- /dev/null +++ b/argocd/applications/findbobastore/kustomization.yaml @@ -0,0 +1,10 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - secrets.yaml + - deployment.yaml + - service.yaml + - ingress.yaml +images: + - name: kalmyk.duckdns.org/lab/findbobastore + newTag: 0.128.0 diff --git a/argocd/applications/findbobastore/secrets.yaml b/argocd/applications/findbobastore/secrets.yaml new file mode 100644 index 0000000..a6ba8b9 --- /dev/null +++ b/argocd/applications/findbobastore/secrets.yaml @@ -0,0 +1,32 @@ +--- +apiVersion: bitnami.com/v1alpha1 +kind: SealedSecret +metadata: + creationTimestamp: null + name: kalmyk-registry + namespace: findbobastore +spec: + encryptedData: + .dockerconfigjson: AgCftxmKCiQmjua8NJ30RqWmBMEMKBeSE/dZMQc/aLCz/ugyzNvVML6IJoYqqglnexgg3GyEg03YyPkU4hNDQyP1wW3QvW27VIV2qkSKD2LvNxU42Otpb+Qla8JvtljTzUdMmxHYPiPimGaEInc5xEbB0TzFmHqDWUWaS7Hh7f5DDObX7gTsP3WD10zR3pZ4t5X9ND6D7hjO+zt60Aulb0Cgjo84SvsmLafbs/UWT6qPUjIim8MjQlG1I/jwt4eQhXVHqRh+8HQ4BLsEro1+JWNoT/bDb+YC5ElasiN4JREqu9aVNmtS9i3wcAFqcaw0wRfxUXUb2JvS7+vICsSMoNrDHbN+WP/15RzjiIbAGRhRP0tG2bec46/lgzpJHrcVAqG/D30YmegdO54OtM0Wa2ofgooZSaGr7EhOuCmTgK1CUYFKncQtmDfY/yHiqSIBH78vam123iPRJ4AEHetCH+6PYx95iDykdHygQB2QnsPq4ZXgKXoCvunXH3uuk7kddFPYOvqdAmYL8CFbWXjK52GaYZx6z1hjDiGnp1LffuyyPBQZ990+Cdkl1svdvQ4wesQjH3uw1CYWLLBFztpxJ2UmspaaUj6DoamD9nLsTQjuoukNxuw/mMsTTDqDX3Qfx+MVrm3Gmhq8+sYDTqy8qVx2/x69EoKeFe7gEjuvI7SFy5r/lUhJqlBs3iVsucHkRKTFtKTOnsp+aMzT1EzPCF85Dkvb/FNDJCR6oV9U5/JXHe5nZU6numKsfq8B1dkg3Z/LmqXvc0ttv7WU1zP/WKn4j6SK9/27EKzbh7Vu5qKBUNixmbs4CjX9SpbESpXffW2fjUhA+JhsLXIqpj2vfWCb0Xp53MtoN/ufA3VYcYQ= + template: + metadata: + creationTimestamp: null + name: kalmyk-registry + namespace: findbobastore + type: kubernetes.io/dockerconfigjson +--- +apiVersion: bitnami.com/v1alpha1 +kind: SealedSecret +metadata: + creationTimestamp: null + name: mapbox-token + namespace: findbobastore +spec: + encryptedData: + token: AgBwjlO2Fi+HvOASLbj9MCY53DCgSXqULiSjGEAdH+k+J27QjPOgIgilghw5IZ51zeiR6V+/WQ4KA2oCHpuFYBqTTNg6Zr+qbw/944zTbIKVIeAXtPeLkXW5c+GCL7Rdlpc9C0hcDDp3tfOUfO7E0k9C/tqAMankNarxLUzroa+CNSTke/goFQy+CwUhtqp+gaT63HN0sXTIGBKNeqce5fKz3+/vDNRkVyV72UdgyZWEfKqYN9L9Dbh4SfPYFoNqN14bu+KSj1piWYc1XCynb9K35JQIYvsvf68AzgRPfWq+uKzIhYC/mcwuZ6OqCQewgm6NuDwm/pURP2o7n14y9yrUJ6uAtIcBWkSVbjTKN+gwyb61/yLAAu5ar0jUNU5OLWvfZ+gK8XQjn8ZnAm7WuemyY8Yz1KU5txImZXHyjdqqftifF14jIsEtcr/BKjUlOVTXbpudwDWJ/PavaJIGc1HiGyDwd/gPP0AKFG1z/42SeCK+Nqv+nDcNqhd0HrbZO/dEP7++TUdCUTMB/RoNzZW3KQjp9Yycx4/b3cb5EeS3kJ770EMQglkUuJxBGMgC1VLX0NUrgdru4k3WqmI+Xk1vM3bNuseLa2+FqyA7AV5V3XqfRnoDL2lR4RK//wz7EFdnb72GHFcQyrc9RO8cFH+rddCnrB6V9HaSQFE4diTtf5KcWw1XnFAkvH1wTNxVf30mcTwPMcfpncs8P6cN+Mg20v898mdXpYj3WgEh5UHqXde85ButdV4XaCyYgYqMt3koRo709i+dAwQMjjhH+YepcM8IpblMUt1aWef2wE8MdryeX9TjDnAX + template: + metadata: + creationTimestamp: null + name: mapbox-token + namespace: findbobastore + type: Opaque diff --git a/argocd/applications/findbobastore/service.yaml b/argocd/applications/findbobastore/service.yaml new file mode 100644 index 0000000..cbcc28d --- /dev/null +++ b/argocd/applications/findbobastore/service.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Service +metadata: + name: findbobastore + namespace: findbobastore +spec: + selector: + app: findbobastore + ports: + - port: 80 + targetPort: 3000 diff --git a/package.json b/package.json index a28be4d..35acdd8 100644 --- a/package.json +++ b/package.json @@ -6,10 +6,14 @@ "node": "22.12.0" }, "scripts": { - "dev": "pnpm --filter proompteng dev", - "build": "pnpm --filter proompteng build", - "start": "pnpm --filter proompteng start", - "lint": "pnpm --filter proompteng lint", + "dev:proompteng": "pnpm --filter proompteng dev", + "dev:findbobastore": "pnpm --filter findbobastore dev", + "build:proompteng": "pnpm --filter proompteng build", + "build:findbobastore": "pnpm --filter findbobastore build", + "start:proompteng": "pnpm --filter proompteng start", + "start:findbobastore": "pnpm --filter findbobastore start", + "lint:proompteng": "pnpm --filter proompteng lint", + "lint:findbobastore": "pnpm --filter findbobastore lint", "clean": "pnpm -r exec rm -rf node_modules && rm -rf node_modules", "format": "prettier --write \"**/*.{ts,tsx,js,jsx,css,md,json}\"", "tf:plan": "tofu -chdir='./tofu/harvester' plan", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dccfc12..c80a8fb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,6 +20,15 @@ importers: apps/findbobastore: dependencies: + clsx: + specifier: ^2.1.1 + version: 2.1.1 + framer-motion: + specifier: ^11.15.0 + version: 11.15.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + mapbox-gl: + specifier: ^3.9.1 + version: 3.9.1 next: specifier: 15.1.2 version: 15.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) @@ -29,6 +38,9 @@ importers: react-dom: specifier: ^19.0.0 version: 19.0.0(react@19.0.0) + tailwind-merge: + specifier: ^2.5.5 + version: 2.5.5 devDependencies: '@eslint/eslintrc': specifier: ^3 @@ -312,6 +324,29 @@ packages: '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@mapbox/jsonlint-lines-primitives@2.0.2': + resolution: {integrity: sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ==} + engines: {node: '>= 0.6'} + + '@mapbox/mapbox-gl-supported@3.0.0': + resolution: {integrity: sha512-2XghOwu16ZwPJLOFVuIOaLbN0iKMn867evzXFyf0P22dqugezfJwLmdanAgU25ITvz1TvOfVP4jsDImlDJzcWg==} + + '@mapbox/point-geometry@0.1.0': + resolution: {integrity: sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ==} + + '@mapbox/tiny-sdf@2.0.6': + resolution: {integrity: sha512-qMqa27TLw+ZQz5Jk+RcwZGH7BQf5G/TrutJhspsca/3SHwmgKQ1iq+d3Jxz5oysPVYTGP6aXxCo5Lk9Er6YBAA==} + + '@mapbox/unitbezier@0.0.1': + resolution: {integrity: sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw==} + + '@mapbox/vector-tile@1.3.1': + resolution: {integrity: sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw==} + + '@mapbox/whoots-js@3.1.0': + resolution: {integrity: sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q==} + engines: {node: '>=6.0.0'} + '@next/env@15.1.2': resolution: {integrity: sha512-Hm3jIGsoUl6RLB1vzY+dZeqb+/kWPZ+h34yiWxW0dV87l8Im/eMOwpOA+a0L78U0HM04syEjXuRlCozqpwuojQ==} @@ -424,15 +459,30 @@ packages: '@types/estree@1.0.6': resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + '@types/geojson-vt@3.2.5': + resolution: {integrity: sha512-qDO7wqtprzlpe8FfQ//ClPV9xiuoh2nkIgiouIptON9w5jvD/fA4szvP9GBlDVdJ5dldAl0kX/sy3URbWwLx0g==} + + '@types/geojson@7946.0.15': + resolution: {integrity: sha512-9oSxFzDCT2Rj6DfcHF8G++jxBKS7mBqXl5xrRW+Kbvjry6Uduya2iiwqHPhVXpasAVMBYKkEPGgKhd3+/HZ6xA==} + '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + '@types/mapbox__point-geometry@0.1.4': + resolution: {integrity: sha512-mUWlSxAmYLfwnRBmgYV86tgYmMIICX4kza8YnE/eIlywGe2XoOxlpVnXWwir92xRLjwyarqwpu2EJKD2pk0IUA==} + + '@types/mapbox__vector-tile@1.3.4': + resolution: {integrity: sha512-bpd8dRn9pr6xKvuEBQup8pwQfD4VUyqO/2deGjfpe6AwC8YRlyEipvefyRJUSiCJTZuCb8Pl1ciVV5ekqJ96Bg==} + '@types/node@20.17.10': resolution: {integrity: sha512-/jrvh5h6NXhEauFFexRin69nA0uHJ5gwk4iDivp/DeoEua3uwCUto6PC86IpRITBOs4+6i2I56K5x5b6WYGXHA==} + '@types/pbf@3.0.5': + resolution: {integrity: sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA==} + '@types/react-dom@19.0.2': resolution: {integrity: sha512-c1s+7TKFaDRRxr1TxccIX2u7sfCnc3RxkVyBIUA2lCpyqCF+QoAwQ/CBg7bsMdVwP120HEH143VQezKtef5nCg==} peerDependencies: @@ -441,6 +491,9 @@ packages: '@types/react@19.0.2': resolution: {integrity: sha512-USU8ZI/xyKJwFTpjSVIrSeHBVAGagkHQKPNbxeWwql/vDmnTIBgx+TJnhFnj1NXgz8XfprU0egV2dROLGpsBEg==} + '@types/supercluster@7.1.3': + resolution: {integrity: sha512-Z0pOY34GDFl3Q6hUFYf3HkTwKEE02e7QgtJppBt+beEAxnyOpJua+voGFvxINBHa06GwLFFym7gRPY2SiKIfIA==} + '@typescript-eslint/eslint-plugin@8.18.1': resolution: {integrity: sha512-Ncvsq5CT3Gvh+uJG0Lwlho6suwDfUXH0HztslDf5I+F2wAFAZMRwYLEorumpKLzmO2suAXZ/td1tBg4NZIi9CQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -629,6 +682,9 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} + cheap-ruler@4.0.0: + resolution: {integrity: sha512-0BJa8f4t141BYKQyn9NSQt1PguFQXMXwZiA5shfoaBYHAb2fFk2RAX+tiWMoQU+Agtzt3mdt0JtuyshAXqZ+Vw==} + chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} @@ -668,6 +724,9 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + csscolorparser@1.0.3: + resolution: {integrity: sha512-umPSgYwZkdFoUrH5hIq5kf0wPSXiro51nPw0j2K/c83KflkPSTBGMz6NJvMB+07VlL0y7VPo6QJcDjcgKTTm3w==} + cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} @@ -737,6 +796,9 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} + earcut@3.0.1: + resolution: {integrity: sha512-0l1/0gOjESMeQyYaK5IDiPNvFeu93Z/cO0TjZh9eZ1vyCtZnA7KMZ8rQggpsJHIbGSdrqYq9OhuveadOVHCshw==} + eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} @@ -976,6 +1038,9 @@ packages: functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + geojson-vt@4.0.2: + resolution: {integrity: sha512-AV9ROqlNqoZEIJGfm1ncNjEXfkz2hdFlZf0qkVfmkwdKa8vj7H16YUOT81rJw1rdFhyEDlN2Tds91p/glzbl5A==} + get-intrinsic@1.2.6: resolution: {integrity: sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==} engines: {node: '>= 0.4'} @@ -987,6 +1052,9 @@ packages: get-tsconfig@4.8.1: resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==} + gl-matrix@3.4.3: + resolution: {integrity: sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA==} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -1017,6 +1085,9 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + grid-index@1.1.0: + resolution: {integrity: sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA==} + has-bigints@1.1.0: resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} engines: {node: '>= 0.4'} @@ -1049,6 +1120,9 @@ packages: engines: {node: '>=18'} hasBin: true + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} @@ -1216,6 +1290,9 @@ packages: resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} engines: {node: '>=4.0'} + kdbush@4.0.2: + resolution: {integrity: sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==} + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -1262,6 +1339,9 @@ packages: peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + mapbox-gl@3.9.1: + resolution: {integrity: sha512-KGgS07MOoGSrewRrw0zqPG/2zkUNWYVGhI4+OEGnUGnUR5GV+k6rgKBEZei3U8z9VIrhrO5Qfbh3Da9o7GhX/Q==} + math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} @@ -1297,6 +1377,9 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + murmurhash-js@1.0.0: + resolution: {integrity: sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw==} + mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} @@ -1403,6 +1486,10 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} + pbf@3.3.0: + resolution: {integrity: sha512-XDF38WCH3z5OV/OVa8GKUNtLAyneuzbCisx7QUCF8Q6Nutx0WnJrQe5O+kOtBlLfRNUws98Y58Lblp+NJG5T4Q==} + hasBin: true + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -1471,6 +1558,9 @@ packages: resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==} engines: {node: ^10 || ^12 || >=14} + potpack@2.0.0: + resolution: {integrity: sha512-Q+/tYsFU9r7xoOJ+y/ZTtdVQwTWfzjbiXBDMM/JKUux3+QPP02iUuIoeBQ+Ot6oEDlC+/PGjB/5A3K7KKb7hcw==} + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -1483,6 +1573,9 @@ packages: prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + protocol-buffers-schema@3.6.0: + resolution: {integrity: sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -1490,6 +1583,9 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + quickselect@3.0.0: + resolution: {integrity: sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==} + react-dom@19.0.0: resolution: {integrity: sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==} peerDependencies: @@ -1524,6 +1620,9 @@ packages: resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + resolve-protobuf-schema@2.1.0: + resolution: {integrity: sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==} + resolve@1.22.10: resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} engines: {node: '>= 0.4'} @@ -1560,6 +1659,10 @@ packages: engines: {node: '>=10'} hasBin: true + serialize-to-js@3.1.2: + resolution: {integrity: sha512-owllqNuDDEimQat7EPG0tH7JjO090xKNzUtYz6X+Sk2BXDnOCilDdNLwjWeFywG9xkJul1ULvtUQa9O4pUaY0w==} + engines: {node: '>=4.0.0'} + set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} @@ -1679,6 +1782,9 @@ packages: engines: {node: '>=16 || 14 >=14.17'} hasBin: true + supercluster@8.0.1: + resolution: {integrity: sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==} + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -1711,6 +1817,9 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + tinyqueue@3.0.0: + resolution: {integrity: sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -1768,6 +1877,9 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + vt-pbf@3.1.3: + resolution: {integrity: sha512-2LzDFzt0mZKZ9IpVF2r69G9bXaP2Q2sArJCmcCgvfTdCCZzSyz4aCLoQyUilu37Ll56tCblIZrXFIjNUpGIlmA==} + which-boxed-primitive@1.1.1: resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} engines: {node: '>= 0.4'} @@ -1974,6 +2086,22 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 + '@mapbox/jsonlint-lines-primitives@2.0.2': {} + + '@mapbox/mapbox-gl-supported@3.0.0': {} + + '@mapbox/point-geometry@0.1.0': {} + + '@mapbox/tiny-sdf@2.0.6': {} + + '@mapbox/unitbezier@0.0.1': {} + + '@mapbox/vector-tile@1.3.1': + dependencies: + '@mapbox/point-geometry': 0.1.0 + + '@mapbox/whoots-js@3.1.0': {} + '@next/env@15.1.2': {} '@next/eslint-plugin-next@15.1.2': @@ -2054,14 +2182,30 @@ snapshots: '@types/estree@1.0.6': {} + '@types/geojson-vt@3.2.5': + dependencies: + '@types/geojson': 7946.0.15 + + '@types/geojson@7946.0.15': {} + '@types/json-schema@7.0.15': {} '@types/json5@0.0.29': {} + '@types/mapbox__point-geometry@0.1.4': {} + + '@types/mapbox__vector-tile@1.3.4': + dependencies: + '@types/geojson': 7946.0.15 + '@types/mapbox__point-geometry': 0.1.4 + '@types/pbf': 3.0.5 + '@types/node@20.17.10': dependencies: undici-types: 6.19.8 + '@types/pbf@3.0.5': {} + '@types/react-dom@19.0.2(@types/react@19.0.2)': dependencies: '@types/react': 19.0.2 @@ -2070,6 +2214,10 @@ snapshots: dependencies: csstype: 3.1.3 + '@types/supercluster@7.1.3': + dependencies: + '@types/geojson': 7946.0.15 + '@typescript-eslint/eslint-plugin@8.18.1(@typescript-eslint/parser@8.18.1(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.2))(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.2)': dependencies: '@eslint-community/regexpp': 4.12.1 @@ -2306,6 +2454,8 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 + cheap-ruler@4.0.0: {} + chokidar@3.6.0: dependencies: anymatch: 3.1.3 @@ -2354,6 +2504,8 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + csscolorparser@1.0.3: {} + cssesc@3.0.0: {} csstype@3.1.3: {} @@ -2417,6 +2569,8 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 + earcut@3.0.1: {} + eastasianwidth@0.2.0: {} emoji-regex@8.0.0: {} @@ -2800,6 +2954,8 @@ snapshots: functions-have-names@1.2.3: {} + geojson-vt@4.0.2: {} + get-intrinsic@1.2.6: dependencies: call-bind-apply-helpers: 1.0.1 @@ -2823,6 +2979,8 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 + gl-matrix@3.4.3: {} + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -2853,6 +3011,8 @@ snapshots: graphemer@1.4.0: {} + grid-index@1.1.0: {} + has-bigints@1.1.0: {} has-flag@4.0.0: {} @@ -2877,6 +3037,8 @@ snapshots: husky@9.1.7: {} + ieee754@1.2.1: {} + ignore@5.3.2: {} import-fresh@3.3.0: @@ -3047,6 +3209,8 @@ snapshots: object.assign: 4.1.7 object.values: 1.2.1 + kdbush@4.0.2: {} + keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -3086,6 +3250,37 @@ snapshots: dependencies: react: 19.0.0 + mapbox-gl@3.9.1: + dependencies: + '@mapbox/jsonlint-lines-primitives': 2.0.2 + '@mapbox/mapbox-gl-supported': 3.0.0 + '@mapbox/point-geometry': 0.1.0 + '@mapbox/tiny-sdf': 2.0.6 + '@mapbox/unitbezier': 0.0.1 + '@mapbox/vector-tile': 1.3.1 + '@mapbox/whoots-js': 3.1.0 + '@types/geojson': 7946.0.15 + '@types/geojson-vt': 3.2.5 + '@types/mapbox__point-geometry': 0.1.4 + '@types/mapbox__vector-tile': 1.3.4 + '@types/pbf': 3.0.5 + '@types/supercluster': 7.1.3 + cheap-ruler: 4.0.0 + csscolorparser: 1.0.3 + earcut: 3.0.1 + geojson-vt: 4.0.2 + gl-matrix: 3.4.3 + grid-index: 1.1.0 + kdbush: 4.0.2 + murmurhash-js: 1.0.0 + pbf: 3.3.0 + potpack: 2.0.0 + quickselect: 3.0.0 + serialize-to-js: 3.1.2 + supercluster: 8.0.1 + tinyqueue: 3.0.0 + vt-pbf: 3.1.3 + math-intrinsics@1.1.0: {} merge2@1.4.1: {} @@ -3113,6 +3308,8 @@ snapshots: ms@2.1.3: {} + murmurhash-js@1.0.0: {} + mz@2.7.0: dependencies: any-promise: 1.3.0 @@ -3227,6 +3424,11 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.2 + pbf@3.3.0: + dependencies: + ieee754: 1.2.1 + resolve-protobuf-schema: 2.1.0 + picocolors@1.1.1: {} picomatch@2.3.1: {} @@ -3285,6 +3487,8 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 + potpack@2.0.0: {} + prelude-ls@1.2.1: {} prettier@3.4.2: {} @@ -3295,10 +3499,14 @@ snapshots: object-assign: 4.1.1 react-is: 16.13.1 + protocol-buffers-schema@3.6.0: {} + punycode@2.3.1: {} queue-microtask@1.2.3: {} + quickselect@3.0.0: {} + react-dom@19.0.0(react@19.0.0): dependencies: react: 19.0.0 @@ -3338,6 +3546,10 @@ snapshots: resolve-pkg-maps@1.0.0: {} + resolve-protobuf-schema@2.1.0: + dependencies: + protocol-buffers-schema: 3.6.0 + resolve@1.22.10: dependencies: is-core-module: 2.16.1 @@ -3376,6 +3588,8 @@ snapshots: semver@7.6.3: {} + serialize-to-js@3.1.2: {} + set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 @@ -3555,6 +3769,10 @@ snapshots: pirates: 4.0.6 ts-interface-checker: 0.1.13 + supercluster@8.0.1: + dependencies: + kdbush: 4.0.2 + supports-color@7.2.0: dependencies: has-flag: 4.0.0 @@ -3604,6 +3822,8 @@ snapshots: dependencies: any-promise: 1.3.0 + tinyqueue@3.0.0: {} + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 @@ -3677,6 +3897,12 @@ snapshots: util-deprecate@1.0.2: {} + vt-pbf@3.1.3: + dependencies: + '@mapbox/point-geometry': 0.1.0 + '@mapbox/vector-tile': 1.3.1 + pbf: 3.3.0 + which-boxed-primitive@1.1.1: dependencies: is-bigint: 1.1.0 diff --git a/scripts/build-findbobastore.sh b/scripts/build-findbobastore.sh new file mode 100755 index 0000000..a476e58 --- /dev/null +++ b/scripts/build-findbobastore.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +# Set variables +IMAGE_NAME="kalmyk.duckdns.org/lab/findbobastore" +DOCKERFILE="apps/findbobastore/Dockerfile" +CONTEXT_PATH="." + +# Check if a tag is provided as an argument +if [ $# -eq 1 ]; then + TAG=$1 +else + # If no tag is provided, use the current date and time + TAG=$(date +"%Y%m%d_%H%M%S") +fi + +# Full image name with tag +FULL_IMAGE_NAME="${IMAGE_NAME}:${TAG}" + +# Build the Docker image +echo "Building Docker image: ${FULL_IMAGE_NAME}" +docker buildx build --platform linux/arm64 -t ${FULL_IMAGE_NAME} -f ${DOCKERFILE} ${CONTEXT_PATH} --push + +# Check if the build was successful +if [ $? -eq 0 ]; then + echo "Docker image built and pushed successfully: ${FULL_IMAGE_NAME}" +else + echo "Docker image build or push failed" + exit 1 +fi