diff --git a/.dockerignore b/.dockerignore index 762a7ba..276bbec 100644 Binary files a/.dockerignore and b/.dockerignore differ diff --git a/Dockerfile b/Dockerfile index e57cdb8..e69de29 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,14 +0,0 @@ -# Stage 1: Build Frontend -FROM node:18-alpine as build -WORKDIR /app -COPY package*.json ./ -RUN npm install -COPY . . -RUN npm run build - -# Stage 2: Serve with Nginx -FROM nginx:alpine -COPY --from=build /app/dist /usr/share/nginx/html -COPY nginx.conf /etc/nginx/nginx.conf -EXPOSE 80 -CMD ["nginx", "-g", "daemon off;"] diff --git a/nginx.conf b/nginx.conf index 91a9aa8..e69de29 100644 --- a/nginx.conf +++ b/nginx.conf @@ -1,39 +0,0 @@ - -worker_processes 1; - -events { worker_connections 1024; } - -http { - include mime.types; - default_type application/octet-stream; - sendfile on; - keepalive_timeout 65; - - # Limite upload per allegati (es. foto/video ticket) - client_max_body_size 50M; - - server { - listen 80; - root /usr/share/nginx/html; - index index.html; - - # Compressione Gzip - gzip on; - gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; - - # Gestione SPA (React Router) - location / { - try_files $uri $uri/ /index.html; - } - - # Proxy API verso il backend - location /api/ { - proxy_pass http://backend:3001; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection 'upgrade'; - proxy_set_header Host $host; - proxy_cache_bypass $http_upgrade; - } - } -} diff --git a/pages/FamilyDetail.tsx b/pages/FamilyDetail.tsx index be0e529..ec2d11a 100644 --- a/pages/FamilyDetail.tsx +++ b/pages/FamilyDetail.tsx @@ -14,6 +14,8 @@ const MONTH_NAMES = [ export const FamilyDetail: React.FC = () => { const { id } = useParams<{ id: string }>(); const navigate = useNavigate(); + const currentUser = CondoService.getCurrentUser(); + const isPrivileged = currentUser?.role === 'admin' || currentUser?.role === 'poweruser'; const [family, setFamily] = useState(null); const [payments, setPayments] = useState([]); @@ -163,6 +165,22 @@ export const FamilyDetail: React.FC = () => { const isPayPalEnabled = condo?.paypalClientId && settings?.features.payPal; + const handleOpenAddModal = (monthIndex?: number) => { + if (monthIndex !== undefined) { + setNewPaymentMonth(monthIndex + 1); + } + + // LOGIC: + // Admin -> Defaults to Manual (can switch if PayPal enabled) + // User -> Defaults to PayPal (cannot switch to manual) + if (isPrivileged) { + setPaymentMethod('manual'); + } else { + setPaymentMethod('paypal'); + } + setShowAddModal(true); + }; + if (loading) return
Caricamento dettagli...
; if (!family) return
Famiglia non trovata.
; @@ -203,10 +221,7 @@ export const FamilyDetail: React.FC = () => { - - - - ) : ( -
-
-

Stai per pagare

-

€ {newPaymentAmount.toFixed(2)}

-

{MONTH_NAMES[newPaymentMonth - 1]} {selectedYear}

-
- - {paypalSuccessMsg ? ( -
- - {paypalSuccessMsg} -
- ) : ( -
- {isPayPalEnabled && ( - - { - return actions.order.create({ - intent: "CAPTURE", - purchase_units: [ - { - description: `Quota ${MONTH_NAMES[newPaymentMonth - 1]} ${selectedYear} - Famiglia ${family.name}`, - amount: { - currency_code: "EUR", - value: newPaymentAmount.toString(), - }, - }, - ], - }); - }} - onApprove={(data, actions) => { - if(!actions.order) return Promise.resolve(); - return actions.order.capture().then((details) => { - handlePaymentSuccess(details); - }); - }} - /> - - )} -
- )} -

Il pagamento sarà registrato automaticamente.

+ {/* Non-privileged users (regular tenants) without PayPal enabled: Show Block Message */} + {!isPrivileged && !isPayPalEnabled ? ( +
+ +

Pagamenti Online non attivi

+

Contatta l'amministratore per saldare la tua rata in contanti o bonifico.

+
+ ) : ( + <> + {paymentMethod === 'manual' && isPrivileged ? ( +
+
+ + +
+ +
+ + setNewPaymentAmount(parseFloat(e.target.value))} + className="w-full border border-slate-300 rounded-xl p-3 focus:ring-2 focus:ring-blue-500 outline-none text-lg font-medium" + /> +
+ +
+ + +
+
+ ) : ( +
+
+

Stai per pagare

+

€ {newPaymentAmount.toFixed(2)}

+

{MONTH_NAMES[newPaymentMonth - 1]} {selectedYear}

+
+ + {paypalSuccessMsg ? ( +
+ + {paypalSuccessMsg} +
+ ) : ( +
+ {isPayPalEnabled && ( + + { + return actions.order.create({ + intent: "CAPTURE", + purchase_units: [ + { + description: `Quota ${MONTH_NAMES[newPaymentMonth - 1]} ${selectedYear} - Famiglia ${family.name}`, + amount: { + currency_code: "EUR", + value: newPaymentAmount.toString(), + }, + }, + ], + }); + }} + onApprove={(data, actions) => { + if(!actions.order) return Promise.resolve(); + return actions.order.capture().then((details) => { + handlePaymentSuccess(details); + }); + }} + /> + + )} +
+ )} +

Il pagamento sarà registrato automaticamente.

+
+ )} + )}
@@ -496,4 +524,4 @@ export const FamilyDetail: React.FC = () => { const BuildingIcon = ({className}:{className?:string}) => ( -); \ No newline at end of file +); diff --git a/server/Dockerfile b/server/Dockerfile index aee4f85..e69de29 100644 --- a/server/Dockerfile +++ b/server/Dockerfile @@ -1,7 +0,0 @@ -FROM node:18-alpine -WORKDIR /app -COPY package*.json ./ -RUN npm install --production -COPY . . -EXPOSE 3001 -CMD ["node", "server.js"]