Skip to content

Commit 35e8f85

Browse files
Giovanni GargiuloGiovanni Gargiulo
authored andcommitted
chore: replayed changes
1 parent 0fad6ff commit 35e8f85

File tree

13 files changed

+195
-30
lines changed

13 files changed

+195
-30
lines changed

frontend/.dockerignore

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
node_modules
2+
.next
3+
out
4+
.git
5+
.gitignore
6+
README.md
7+
.env
8+
.env.local
9+
.env.development
10+
.env.production
11+
npm-debug.log*
12+
yarn-debug.log*
13+
yarn-error.log*
14+
.DS_Store
15+
*.pem
16+
.idea
17+
.vscode

frontend/.env

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
NEXT_PUBLIC_BLOCKFROST_API_KEY=previewzwnjcGmHgYLFmLppEWCrmbhapNtCq4H7
1+
NEXT_PUBLIC_BLOCKFROST_API_KEY=preview6rf9Lym3f9XQrTDnxSBbAGwvz5mNafdz
22
NETWORK=Preview

frontend/.env.development

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
NEXT_PUBLIC_BLOCKFROST_API_KEY=preview6rf9Lym3f9XQrTDnxSBbAGwvz5mNafdz
2+
NETWORK=Preview
3+
# Leave empty in development to use Next.js rewrites (proxies to backend)
4+
NEXT_PUBLIC_API_URL=

frontend/.env.production

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
NEXT_PUBLIC_BLOCKFROST_API_KEY=preview6rf9Lym3f9XQrTDnxSBbAGwvz5mNafdz
2+
NETWORK=Preview
3+
# Production: Set this to your public API endpoint (e.g., https://api.programmabletokens.xyz)
4+
# This should be the publicly accessible URL for your backend API
5+
NEXT_PUBLIC_API_URL=https://preview-api.programmabletokens.xyz

frontend/Dockerfile

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Build stage
2+
FROM node:20-alpine AS builder
3+
4+
WORKDIR /app
5+
6+
# Copy package files
7+
COPY package*.json ./
8+
9+
# Install dependencies
10+
RUN npm ci
11+
12+
# Copy source files
13+
COPY . .
14+
15+
# Accept build arguments
16+
ARG NEXT_PUBLIC_API_URL
17+
ARG NEXT_PUBLIC_BLOCKFROST_API_KEY
18+
ARG NETWORK=Preview
19+
20+
# Set environment variables for build
21+
ENV NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL}
22+
ENV NEXT_PUBLIC_BLOCKFROST_API_KEY=${NEXT_PUBLIC_BLOCKFROST_API_KEY}
23+
ENV NETWORK=${NETWORK}
24+
25+
# Build the Next.js app (static export)
26+
RUN npm run build
27+
28+
# Production stage - serve with nginx
29+
FROM nginx:alpine
30+
31+
# Copy custom nginx config
32+
COPY nginx.conf /etc/nginx/nginx.conf
33+
34+
# Copy built static files from builder stage
35+
COPY --from=builder /app/out /usr/share/nginx/html
36+
37+
# Expose port 80
38+
EXPOSE 80
39+
40+
# Start nginx
41+
CMD ["nginx", "-g", "daemon off;"]

frontend/build.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/usr/bin/env bash
2+
3+
set -x
4+
5+
VERSION=$(git describe --tags --always --dirty)
6+
7+
echo "Building version: ${VERSION}"
8+
9+
DOCKER_IMAGE_NAME=easy1staking/programmable-tokens-ui
10+
DOCKER_IMAGE="${DOCKER_IMAGE_NAME}:${VERSION}"
11+
DOCKER_IMAGE_LATEST="${DOCKER_IMAGE_NAME}:latest"
12+
13+
docker build -t "${DOCKER_IMAGE}" \
14+
-t "${DOCKER_IMAGE_LATEST}" \
15+
--build-arg NEXT_PUBLIC_API_URL=https://preview-api.programmabletokens.xyz \
16+
--build-arg NEXT_PUBLIC_BLOCKFROST_API_KEY=preview6rf9Lym3f9XQrTDnxSBbAGwvz5mNafdz \
17+
--build-arg NETWORK=Preview \
18+
--push \
19+
.

frontend/docker-compose.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
version: '3.8'
2+
3+
services:
4+
frontend:
5+
build:
6+
context: .
7+
dockerfile: Dockerfile
8+
args:
9+
- NEXT_PUBLIC_API_URL=http://localhost:8080
10+
- NEXT_PUBLIC_BLOCKFROST_API_KEY=preview63R2hq5OToB1PRYyxDQ1NpmS23rbyS88
11+
- NETWORK=Preview
12+
ports:
13+
- "3000:80"
14+
environment:
15+
- NODE_ENV=production

frontend/next.config.js

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -52,22 +52,23 @@ module.exports = (phase, {defaultConfig}) => {
5252
]
5353
},
5454
async rewrites() {
55+
const apiUrl = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8080';
5556
return [
5657
{
5758
source: '/api/v1/:path*', // Match all routes starting with /api/v1/
58-
destination: 'http://localhost:8080/api/v1/:path*', // Proxy to backend server
59+
destination: `${apiUrl}/api/v1/:path*`, // Proxy to backend server
60+
},
61+
];
62+
},
63+
async redirects() {
64+
return [
65+
{
66+
source: '/',
67+
destination: '/connected-wallet',
68+
permanent: true, // Use true for a 301 redirect, false for 302
5969
},
6070
];
6171
},
62-
async redirects() {
63-
return [
64-
{
65-
source: '/',
66-
destination: '/connected-wallet',
67-
permanent: true, // Use true for a 301 redirect, false for 302
68-
},
69-
];
70-
},
7172
experimental: {
7273
esmExternals: true, // Ensure modern module support
7374
},
@@ -87,4 +88,4 @@ module.exports = (phase, {defaultConfig}) => {
8788
"@lucid-evolution/lucid"
8889
]
8990
}
90-
}
91+
}

frontend/nginx.conf

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
events {
2+
worker_connections 1024;
3+
}
4+
5+
http {
6+
include /etc/nginx/mime.types;
7+
default_type application/octet-stream;
8+
9+
sendfile on;
10+
keepalive_timeout 65;
11+
gzip on;
12+
gzip_vary on;
13+
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
14+
15+
server {
16+
listen 80;
17+
server_name _;
18+
root /usr/share/nginx/html;
19+
index index.html;
20+
21+
# Redirect root to /mint-authority
22+
location = / {
23+
return 301 /mint-authority.html;
24+
}
25+
26+
# Enable SPA routing - serve HTML files for routes
27+
location / {
28+
try_files $uri $uri.html $uri/ =404;
29+
}
30+
31+
# Cache static assets
32+
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
33+
expires 1y;
34+
add_header Cache-Control "public, immutable";
35+
}
36+
37+
# Security headers
38+
add_header X-Frame-Options "SAMEORIGIN" always;
39+
add_header X-Content-Type-Options "nosniff" always;
40+
add_header X-XSS-Protection "1; mode=block" always;
41+
}
42+
}

frontend/src/app/[username]/index.tsx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import React, { useContext, useEffect, useState, useMemo } from 'react';
44

55
//Axios imports
66
import axios from 'axios';
7+
import { getApiUrl } from '../utils/apiConfig';
78

89
//Mui imports
910
import { Box, Checkbox, CircularProgress, FormControl, FormControlLabel, InputLabel, MenuItem, Paper, Select, Typography } from '@mui/material';
@@ -365,7 +366,7 @@ export default function Profile() {
365366
};
366367
try {
367368
const response = await axios.post(
368-
'/api/v1/tx/programmable-token/transfer',
369+
getApiUrl('/api/v1/tx/programmable-token/transfer'),
369370
requestData,
370371
{
371372
headers: {
@@ -448,7 +449,7 @@ export default function Profile() {
448449
setIsRegistering(true);
449450
changeAlertInfo({ severity: 'info', message: 'Preparing registration transaction…', open: true, link: '' });
450451
const response = await axios.post(
451-
'/api/v1/tx/programmable-token/register-transfer-scripts',
452+
getApiUrl('/api/v1/tx/programmable-token/register-transfer-scripts'),
452453
{ issuer: issuerAddress },
453454
{ headers: { 'Content-Type': 'application/json;charset=utf-8' } }
454455
);
@@ -502,7 +503,7 @@ export default function Profile() {
502503
setIsInitializingBlacklist(true);
503504
changeAlertInfo({ severity: 'info', message: 'Preparing blacklist initialisation transaction…', open: true, link: '' });
504505
const response = await axios.post(
505-
'/api/v1/tx/programmable-token/blacklist-init',
506+
getApiUrl('/api/v1/tx/programmable-token/blacklist-init'),
506507
{ issuer: issuerAddress },
507508
{ headers: { 'Content-Type': 'application/json;charset=utf-8' } }
508509
);
@@ -595,7 +596,7 @@ export default function Profile() {
595596
setIsUserMinting(true);
596597
try {
597598
const response = await axios.post(
598-
'/api/v1/tx/programmable-token/issue',
599+
getApiUrl('/api/v1/tx/programmable-token/issue'),
599600
requestData,
600601
{
601602
headers: {'Content-Type': 'application/json;charset=utf-8'}
@@ -641,7 +642,7 @@ export default function Profile() {
641642
setIsUserFreezing(true);
642643
try {
643644
const response = await axios.post(
644-
'/api/v1/tx/programmable-token/blacklist',
645+
getApiUrl('/api/v1/tx/programmable-token/blacklist'),
645646
requestData,
646647
{ headers: {'Content-Type': 'application/json;charset=utf-8'} }
647648
);
@@ -694,7 +695,7 @@ export default function Profile() {
694695
setIsUserUnfreezing(true);
695696
try {
696697
const response = await axios.post(
697-
'/api/v1/tx/programmable-token/unblacklist',
698+
getApiUrl('/api/v1/tx/programmable-token/unblacklist'),
698699
requestData,
699700
{ headers: {'Content-Type': 'application/json;charset=utf-8'} }
700701
);
@@ -747,7 +748,7 @@ export default function Profile() {
747748
setIsUserSeizing(true);
748749
try {
749750
const response = await axios.post(
750-
'/api/v1/tx/programmable-token/seize',
751+
getApiUrl('/api/v1/tx/programmable-token/seize'),
751752
requestData,
752753
{ headers: {'Content-Type': 'application/json;charset=utf-8'} }
753754
);

0 commit comments

Comments
 (0)