Merge pull request '#60-Added dynamic changing host logic.' (#73) from #60-Dynamisches-angeben-des-Hostes-für-das-frontend into main
Reviewed-on: #73pull/75/head
commit
fc900c68d0
|
|
@ -4,6 +4,9 @@ services:
|
||||||
context: frontend
|
context: frontend
|
||||||
ports:
|
ports:
|
||||||
- 8080:80
|
- 8080:80
|
||||||
|
environment:
|
||||||
|
- API_HOST=http://localhost:5050
|
||||||
|
|
||||||
db:
|
db:
|
||||||
image: postgres:17-alpine
|
image: postgres:17-alpine
|
||||||
env_file:
|
env_file:
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,21 @@ RUN bun install --frozen-lockfile
|
||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
|
# dummy environment variable for build - DONT CHANGE!!!
|
||||||
|
ENV VITE_API_HOST=SECRET_HOST
|
||||||
|
|
||||||
RUN bun run build
|
RUN bun run build
|
||||||
|
|
||||||
FROM nginx:1.28.0-alpine3.21
|
FROM nginx:1.28.0-alpine3.21
|
||||||
|
|
||||||
|
# default environment variable that will be replaced at runtime
|
||||||
|
ENV API_HOST=http://localhost:5050
|
||||||
|
|
||||||
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf
|
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf
|
||||||
COPY --from=base /usr/src/app/dist /usr/share/nginx/html
|
COPY --from=base /usr/src/app/dist /usr/share/nginx/html
|
||||||
|
|
||||||
|
# entrypoint script
|
||||||
|
COPY docker/docker-entrypoint.sh /docker-entrypoint.sh
|
||||||
|
RUN chmod +x /docker-entrypoint.sh
|
||||||
|
|
||||||
|
CMD ["/docker-entrypoint.sh"]
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Replace API host in built JavaScript files
|
||||||
|
echo "Replacing SECRET_HOST with ${API_HOST}"
|
||||||
|
|
||||||
|
# Replace in main JS files
|
||||||
|
for i in /usr/share/nginx/html/*.js; do
|
||||||
|
if [ -f "$i" ]; then
|
||||||
|
sed -i "s|SECRET_HOST|${API_HOST}|g" "$i"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Replace in assets folder JS files
|
||||||
|
for i in /usr/share/nginx/html/assets/*.js; do
|
||||||
|
if [ -f "$i" ]; then
|
||||||
|
sed -i "s|SECRET_HOST|${API_HOST}|g" "$i"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Replacement completed. Starting nginx..."
|
||||||
|
|
||||||
|
# Start nginx and replace the shell process
|
||||||
|
exec nginx -g 'daemon off;'
|
||||||
|
|
@ -5,6 +5,7 @@ import { useEffect, useState } from "react";
|
||||||
import type { Kennzahl } from "../types/kpi";
|
import type { Kennzahl } from "../types/kpi";
|
||||||
import { getDisplayType } from "../types/kpi";
|
import { getDisplayType } from "../types/kpi";
|
||||||
import { fetchKennzahlen as fetchK } from "../util/api";
|
import { fetchKennzahlen as fetchK } from "../util/api";
|
||||||
|
import { API_HOST } from "../util/api";
|
||||||
|
|
||||||
export function ConfigTable() {
|
export function ConfigTable() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
@ -42,7 +43,7 @@ export function ConfigTable() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`http://localhost:5050/api/kpi_setting/${id}`,
|
`${API_HOST}/api/kpi_setting/${id}`,
|
||||||
{
|
{
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
headers: {
|
headers: {
|
||||||
|
|
@ -79,7 +80,7 @@ export function ConfigTable() {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`http://localhost:5050/api/kpi_setting/update-kpi-positions`,
|
`${API_HOST}/api/kpi_setting/update-kpi-positions`,
|
||||||
{
|
{
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
headers: {
|
headers: {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import { useCallback, useEffect, useState } from "react";
|
||||||
import FileUpload from "react-material-file-upload";
|
import FileUpload from "react-material-file-upload";
|
||||||
import { socket } from "../socket";
|
import { socket } from "../socket";
|
||||||
import { CircularProgressWithLabel } from "./CircularProgressWithLabel";
|
import { CircularProgressWithLabel } from "./CircularProgressWithLabel";
|
||||||
|
import { API_HOST } from "../util/api";
|
||||||
|
|
||||||
const PROGRESS = true;
|
const PROGRESS = true;
|
||||||
|
|
||||||
|
|
@ -18,7 +19,7 @@ export default function UploadPage() {
|
||||||
const uploadFile = useCallback(async () => {
|
const uploadFile = useCallback(async () => {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append("file", files[0]);
|
formData.append("file", files[0]);
|
||||||
const response = await fetch("http://localhost:5050/api/pitch_book", {
|
const response = await fetch(`${API_HOST}/api/pitch_book`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: formData,
|
body: formData,
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import type {
|
||||||
} from "node_modules/react-pdf/dist/esm/shared/types";
|
} from "node_modules/react-pdf/dist/esm/shared/types";
|
||||||
import { socket } from "../socket";
|
import { socket } from "../socket";
|
||||||
import { highlightPattern } from "../util/highlighting";
|
import { highlightPattern } from "../util/highlighting";
|
||||||
|
import { API_HOST } from "../util/api";
|
||||||
|
|
||||||
interface PDFViewerProps {
|
interface PDFViewerProps {
|
||||||
pitchBookId: string;
|
pitchBookId: string;
|
||||||
|
|
@ -172,7 +173,7 @@ export default function PDFViewer({
|
||||||
>
|
>
|
||||||
<Document
|
<Document
|
||||||
key={pdfKey}
|
key={pdfKey}
|
||||||
file={`http://localhost:5050/api/pitch_book/${pitchBookId}/download`}
|
file={`${API_HOST}/api/pitch_book/${pitchBookId}/download`}
|
||||||
onLoadSuccess={onDocumentLoadSuccess}
|
onLoadSuccess={onDocumentLoadSuccess}
|
||||||
onLoadError={(error) =>
|
onLoadError={(error) =>
|
||||||
console.error("Es gab ein Fehler beim Laden des PDFs:", error)
|
console.error("Es gab ein Fehler beim Laden des PDFs:", error)
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import { Box, Typography, IconButton } from "@mui/material";
|
||||||
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
|
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
|
||||||
import { KPIForm } from "../components/KPIForm";
|
import { KPIForm } from "../components/KPIForm";
|
||||||
import type { Kennzahl } from "../types/kpi";
|
import type { Kennzahl } from "../types/kpi";
|
||||||
|
import { API_HOST } from "../util/api";
|
||||||
|
|
||||||
export const Route = createFileRoute("/config-add")({
|
export const Route = createFileRoute("/config-add")({
|
||||||
component: ConfigAddPage,
|
component: ConfigAddPage,
|
||||||
|
|
@ -13,7 +14,7 @@ function ConfigAddPage() {
|
||||||
|
|
||||||
const handleSave = async (formData: Partial<Kennzahl>) => {
|
const handleSave = async (formData: Partial<Kennzahl>) => {
|
||||||
try {
|
try {
|
||||||
const existingKPIsResponse = await fetch('http://localhost:5050/api/kpi_setting/');
|
const existingKPIsResponse = await fetch(`${API_HOST}/api/kpi_setting/`);
|
||||||
const existingKPIs = await existingKPIsResponse.json();
|
const existingKPIs = await existingKPIsResponse.json();
|
||||||
const maxPosition = existingKPIs.length > 0
|
const maxPosition = existingKPIs.length > 0
|
||||||
? Math.max(...existingKPIs.map((kpi: Kennzahl) => kpi.position))
|
? Math.max(...existingKPIs.map((kpi: Kennzahl) => kpi.position))
|
||||||
|
|
@ -25,7 +26,7 @@ function ConfigAddPage() {
|
||||||
active: formData.active !== false
|
active: formData.active !== false
|
||||||
};
|
};
|
||||||
|
|
||||||
const response = await fetch('http://localhost:5050/api/kpi_setting/', {
|
const response = await fetch(`${API_HOST}/api/kpi_setting/`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import { useEffect, useState } from "react";
|
||||||
import type { Kennzahl } from "../types/kpi";
|
import type { Kennzahl } from "../types/kpi";
|
||||||
import { KPIForm } from "../components/KPIForm";
|
import { KPIForm } from "../components/KPIForm";
|
||||||
import { typeDisplayMapping } from "../types/kpi";
|
import { typeDisplayMapping } from "../types/kpi";
|
||||||
|
import { API_HOST } from "../util/api";
|
||||||
|
|
||||||
export const Route = createFileRoute("/config-detail/$kpiId")({
|
export const Route = createFileRoute("/config-detail/$kpiId")({
|
||||||
component: KPIDetailPage,
|
component: KPIDetailPage,
|
||||||
|
|
@ -23,7 +24,7 @@ function KPIDetailPage() {
|
||||||
const fetchKennzahl = async () => {
|
const fetchKennzahl = async () => {
|
||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const response = await fetch(`http://localhost:5050/api/kpi_setting/${kpiId}`);
|
const response = await fetch(`${API_HOST}/api/kpi_setting/${kpiId}`);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
if (response.status === 404) {
|
if (response.status === 404) {
|
||||||
setError('KPI not found');
|
setError('KPI not found');
|
||||||
|
|
@ -47,7 +48,7 @@ function KPIDetailPage() {
|
||||||
|
|
||||||
const handleSave = async (formData: Partial<Kennzahl>) => {
|
const handleSave = async (formData: Partial<Kennzahl>) => {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`http://localhost:5050/api/kpi_setting/${kpiId}`, {
|
const response = await fetch(`${API_HOST}/api/kpi_setting/${kpiId}`, {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { io } from "socket.io-client";
|
import { io } from "socket.io-client";
|
||||||
|
import { API_HOST } from "./util/api";
|
||||||
|
|
||||||
// "undefined" means the URL will be computed from the `window.location` object
|
// "undefined" means the URL will be computed from the `window.location` object
|
||||||
// const URL = process.env.NODE_ENV === 'production' ? undefined : 'http://localhost:4000';
|
// const URL = process.env.NODE_ENV === 'production' ? undefined : 'http://localhost:4000';
|
||||||
|
|
||||||
export const socket = io("http://localhost:5050");
|
export const socket = io(`${API_HOST}`);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
import type { Kennzahl } from "@/types/kpi";
|
import type { Kennzahl } from "@/types/kpi";
|
||||||
|
|
||||||
|
const API_HOST = import.meta.env.VITE_API_HOST || 'http://localhost:5050';
|
||||||
|
|
||||||
|
export { API_HOST };
|
||||||
|
|
||||||
export const fetchKPI = async (
|
export const fetchKPI = async (
|
||||||
pitchBookId: string,
|
pitchBookId: string,
|
||||||
): Promise<{
|
): Promise<{
|
||||||
|
|
@ -12,7 +16,7 @@ export const fetchKPI = async (
|
||||||
}[];
|
}[];
|
||||||
}> => {
|
}> => {
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`http://localhost:5050/api/pitch_book/${pitchBookId}`,
|
`${API_HOST}/api/pitch_book/${pitchBookId}`,
|
||||||
);
|
);
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
|
|
||||||
|
|
@ -43,7 +47,7 @@ export const fetchPutKPI = async (
|
||||||
formData.append("kpi", JSON.stringify(flattenKPIArray(kpi)));
|
formData.append("kpi", JSON.stringify(flattenKPIArray(kpi)));
|
||||||
|
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`http://localhost:5050/api/pitch_book/${pitchBookId}`,
|
`${API_HOST}/api/pitch_book/${pitchBookId}`,
|
||||||
{
|
{
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
body: formData,
|
body: formData,
|
||||||
|
|
@ -99,7 +103,7 @@ export const flattenKPIArray = (kpi: {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchKennzahlen = async (): Promise<Kennzahl[]> => {
|
export const fetchKennzahlen = async (): Promise<Kennzahl[]> => {
|
||||||
const response = await fetch("http://localhost:5050/api/kpi_setting/");
|
const response = await fetch(`${API_HOST}/api/kpi_setting/`);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`HTTP error! status: ${response.status}`);
|
throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue