Compare commits
2 Commits
979516b681
...
706953e3ea
| Author | SHA1 | Date | |
|---|---|---|---|
| 706953e3ea | |||
| 1cbee8ceaf |
8
.env.example
Normal file
8
.env.example
Normal file
@ -0,0 +1,8 @@
|
||||
# AR Test — Environment Variables
|
||||
# Copy this to .env on the droplet and fill in the values
|
||||
|
||||
# PocketBase public URL (the Traefik-routed domain)
|
||||
VITE_POCKETBASE_URL=https://pb.thob.studio
|
||||
|
||||
# Frontend public URL
|
||||
VITE_FRONTEND_URL=https://ar.thob.studio
|
||||
8
.gitignore
vendored
8
.gitignore
vendored
@ -5,3 +5,11 @@
|
||||
# React Router
|
||||
/.react-router/
|
||||
/build/
|
||||
|
||||
# Local PocketBase dev data — never commit to production
|
||||
/pocketbase/pb_data/
|
||||
/pocketbase/pb_migrations/
|
||||
/pocketbase/pocketbase
|
||||
|
||||
# Keep the root pb_migrations folder tracked (empty placeholder for production)
|
||||
!/pb_migrations/.gitkeep
|
||||
|
||||
@ -12,6 +12,11 @@ FROM node:20-alpine AS build-env
|
||||
COPY . /app/
|
||||
COPY --from=development-dependencies-env /app/node_modules /app/node_modules
|
||||
WORKDIR /app
|
||||
# VITE_ vars are baked into the bundle at build time — must be passed as ARGs
|
||||
ARG VITE_POCKETBASE_URL
|
||||
ARG VITE_FRONTEND_URL
|
||||
ENV VITE_POCKETBASE_URL=$VITE_POCKETBASE_URL
|
||||
ENV VITE_FRONTEND_URL=$VITE_FRONTEND_URL
|
||||
RUN npm run build
|
||||
|
||||
FROM node:20-alpine
|
||||
|
||||
@ -69,8 +69,10 @@ export default function ARViewer() {
|
||||
useEffect(() => {
|
||||
if (!id) return;
|
||||
const loadAsset = async () => {
|
||||
// const response = await fetch(`https://thobapi.bopconsultancy.com/v2/ar-assets/${id}`);
|
||||
const data = await pb.collection('ar_assets').getOne(id);
|
||||
if (data) setAsset(data);
|
||||
// const data = await response.json();
|
||||
setAsset(data);
|
||||
};
|
||||
loadAsset();
|
||||
}, [id]);
|
||||
@ -177,12 +179,12 @@ export default function ARViewer() {
|
||||
|
||||
<div className="absolute top-0 left-0 right-0 flex items-start justify-between px-5 pt-5 pb-5 pointer-events-none">
|
||||
{asset?.name && (
|
||||
<span className="text-white text-sm font-bold tracking-widest uppercase">
|
||||
<span className="text-black text-sm font-bold tracking-widest uppercase">
|
||||
{asset.name}
|
||||
</span>
|
||||
)}
|
||||
<div className="pointer-events-auto w-9 h-9 bg-black border border-orange-500 rounded-lg flex items-center justify-center shrink-0 ml-3">
|
||||
<span className="text-orange-500 font-black text-sm leading-none">t.</span>
|
||||
<div className="pointer-events-auto w-9 h-9 bg-black border rounded-lg flex items-center justify-center shrink-0 ml-3">
|
||||
<span className="text-orange-500 font-semibold text-2xl pl-1">t.</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -11,6 +11,7 @@ import type { Route } from "./+types/root";
|
||||
import "./app.css";
|
||||
|
||||
export const links: Route.LinksFunction = () => [
|
||||
{ rel: "icon", href: "/favicon.svg", type: "image/svg+xml" },
|
||||
{ rel: "preconnect", href: "https://fonts.googleapis.com" },
|
||||
{
|
||||
rel: "preconnect",
|
||||
|
||||
@ -142,7 +142,7 @@ export default function Dashboard() {
|
||||
{assets.map((asset) => (
|
||||
<div
|
||||
key={asset.id}
|
||||
className='rounded-2xl bg-white p-5 shadow-sm transition hover:shadow-md'
|
||||
className='rounded-2xl bg-white p-5 shadow-sm transition hover:shadow-md bg-radial-[at_0%_0%] to-70% from-black/20 to-transparent '
|
||||
>
|
||||
<h3 className='mb-3 text-base font-semibold text-gray-900'>
|
||||
{asset?.name}
|
||||
@ -155,7 +155,13 @@ export default function Dashboard() {
|
||||
className='mx-auto w-40 rounded-lg'
|
||||
/>
|
||||
) : (
|
||||
<div className='mx-auto flex h-40 w-40 flex-col items-center justify-center space-y-2 rounded-lg bg-gray-50 text-gray-400'>
|
||||
asset?.qr_file ? (
|
||||
<img
|
||||
src={pb.files.getURL(asset, asset.qr_file)}
|
||||
alt={asset?.name}
|
||||
className='mx-auto w-40 rounded-lg'
|
||||
/>
|
||||
) : <div className='mx-auto flex h-40 w-40 flex-col items-center justify-center space-y-2 rounded-lg bg-gray-50 text-gray-400'>
|
||||
<ImageOff size={32} strokeWidth={1.5} />
|
||||
<span className='text-xs font-medium'>No QR Image</span>
|
||||
</div>
|
||||
|
||||
72
docker-compose.yml
Normal file
72
docker-compose.yml
Normal file
@ -0,0 +1,72 @@
|
||||
# =============================================================================
|
||||
# AR TEST — Application services
|
||||
# Deploy path on droplet: /projects/ar-test/
|
||||
#
|
||||
# Traefik runs in a separate compose (shared infra project) and owns ports 80/443.
|
||||
# This project only joins the shared external network `traefik_public`.
|
||||
# =============================================================================
|
||||
|
||||
services:
|
||||
app:
|
||||
container_name: ar-test-app
|
||||
image: registry.digitalocean.com/bop/ar-test:latest
|
||||
pull_policy: always
|
||||
restart: unless-stopped
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
args:
|
||||
- VITE_POCKETBASE_URL=${VITE_POCKETBASE_URL:-https://pb.thob.studio}
|
||||
expose:
|
||||
- "3000"
|
||||
environment:
|
||||
- VITE_POCKETBASE_URL=${VITE_POCKETBASE_URL:-https://pb.thob.studio}
|
||||
- VITE_FRONTEND_URL=${VITE_FRONTEND_URL:-https://ar.thob.studio}
|
||||
depends_on:
|
||||
- pocketbase
|
||||
networks:
|
||||
- traefik_public
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.docker.network=traefik_public"
|
||||
- "traefik.http.routers.ar-test-app.rule=Host(`ar.thob.studio`)"
|
||||
- "traefik.http.routers.ar-test-app.entrypoints=websecure"
|
||||
- "traefik.http.routers.ar-test-app.tls.certresolver=defaultresolver"
|
||||
- "traefik.http.services.ar-test-app.loadbalancer.server.port=3000"
|
||||
- "traefik.http.routers.ar-test-app-http.rule=Host(`ar.thob.studio`)"
|
||||
- "traefik.http.routers.ar-test-app-http.entrypoints=web"
|
||||
- "traefik.http.routers.ar-test-app-http.middlewares=ar-test-app-https-redirect"
|
||||
- "traefik.http.middlewares.ar-test-app-https-redirect.redirectscheme.scheme=https"
|
||||
|
||||
pocketbase:
|
||||
container_name: ar-test-pb
|
||||
image: ghcr.io/muchobien/pocketbase:latest
|
||||
restart: unless-stopped
|
||||
command:
|
||||
- serve
|
||||
- --http=0.0.0.0:8090
|
||||
- --dir=/pb_data
|
||||
- --migrationsDir=/pb_migrations
|
||||
volumes:
|
||||
- pb_data:/pb_data
|
||||
- ./pb_migrations:/pb_migrations
|
||||
networks:
|
||||
- traefik_public
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.docker.network=traefik_public"
|
||||
- "traefik.http.routers.ar-test-pb.rule=Host(`pb.thob.studio`)"
|
||||
- "traefik.http.routers.ar-test-pb.entrypoints=websecure"
|
||||
- "traefik.http.routers.ar-test-pb.tls.certresolver=defaultresolver"
|
||||
- "traefik.http.services.ar-test-pb.loadbalancer.server.port=8090"
|
||||
- "traefik.http.routers.ar-test-pb-http.rule=Host(`pb.thob.studio`)"
|
||||
- "traefik.http.routers.ar-test-pb-http.entrypoints=web"
|
||||
- "traefik.http.routers.ar-test-pb-http.middlewares=ar-test-pb-https-redirect"
|
||||
- "traefik.http.middlewares.ar-test-pb-https-redirect.redirectscheme.scheme=https"
|
||||
|
||||
networks:
|
||||
traefik_public:
|
||||
external: true
|
||||
|
||||
volumes:
|
||||
pb_data:
|
||||
0
pb_migrations/.gitkeep
Normal file
0
pb_migrations/.gitkeep
Normal file
9
public/favicon.svg
Normal file
9
public/favicon.svg
Normal file
@ -0,0 +1,9 @@
|
||||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="32*32">
|
||||
<rect width="32" height="32" fill="#0D0D0D"/>
|
||||
<g id="t.">
|
||||
<path id="Vector" d="M22.1119 23.8783C21.5338 23.8783 21.0663 23.7068 20.7093 23.3637C20.3692 23.0207 20.1992 22.5797 20.1992 22.0406C20.1992 21.5179 20.3692 21.0932 20.7093 20.7665C21.0663 20.4235 21.5338 20.252 22.1119 20.252C22.707 20.252 23.166 20.4235 23.489 20.7665C23.8291 21.0932 23.9991 21.5179 23.9991 22.0406C23.9991 22.5797 23.8291 23.0207 23.489 23.3637C23.166 23.7068 22.707 23.8783 22.1119 23.8783Z" fill="#FF6900"/>
|
||||
<path id="Vector_2" d="M15.5487 24C14.4436 24 13.517 23.8203 12.769 23.4609C12.0379 23.1016 11.4938 22.5789 11.1368 21.8928C10.7798 21.1904 10.6013 20.3247 10.6013 19.2956V14.0766H9.27513C8.86709 14.0766 8.55255 13.9786 8.33153 13.7825C8.11051 13.5702 8 13.2843 8 12.925C8 12.5493 8.11051 12.2634 8.33153 12.0674C8.55255 11.8714 8.86709 11.7734 9.27513 11.7734H10.6013V9.54364C10.6013 9.03726 10.7373 8.65339 11.0093 8.39204C11.2983 8.13068 11.6979 8 12.2079 8C12.718 8 13.109 8.13068 13.381 8.39204C13.6531 8.65339 13.7891 9.03726 13.7891 9.54364V11.7734H16.4923C16.9004 11.7734 17.2149 11.8714 17.4359 12.0674C17.6569 12.2634 17.7675 12.5493 17.7675 12.925C17.7675 13.2843 17.6569 13.5702 17.4359 13.7825C17.2149 13.9786 16.9004 14.0766 16.4923 14.0766H13.7891V19.124C13.7891 19.9081 13.9676 20.4962 14.3246 20.8882C14.6817 21.2802 15.2597 21.4763 16.0588 21.4763C16.3478 21.4763 16.6028 21.4518 16.8239 21.4028C17.0449 21.3538 17.2404 21.3211 17.4104 21.3047C17.6144 21.2884 17.7845 21.3538 17.9205 21.5008C18.0565 21.6314 18.1245 21.9091 18.1245 22.3338C18.1245 22.6605 18.065 22.9546 17.946 23.2159C17.844 23.461 17.6484 23.6325 17.3594 23.7305C17.1384 23.7958 16.8494 23.853 16.4923 23.902C16.1353 23.9673 15.8208 24 15.5487 24Z" fill="#FF6900"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
@ -5,4 +5,8 @@ import tsconfigPaths from "vite-tsconfig-paths";
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [tailwindcss(), reactRouter(), tsconfigPaths()],
|
||||
server: {
|
||||
port: 5173,
|
||||
host: true, // allow external access (local dev only)
|
||||
},
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user