diff --git a/.idea/.idea.T120B165-ImgBoard/.idea/workspace.xml b/.idea/.idea.T120B165-ImgBoard/.idea/workspace.xml
index a578a10..24b2dfd 100644
--- a/.idea/.idea.T120B165-ImgBoard/.idea/workspace.xml
+++ b/.idea/.idea.T120B165-ImgBoard/.idea/workspace.xml
@@ -8,19 +8,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -179,6 +167,7 @@
+
diff --git a/Client/Dockerfile b/Client/Dockerfile
index 207bf93..129629a 100644
--- a/Client/Dockerfile
+++ b/Client/Dockerfile
@@ -1,21 +1,21 @@
FROM node:20-alpine AS development-dependencies-env
-COPY . /app
+COPY Client /app
WORKDIR /app
RUN npm ci
FROM node:20-alpine AS production-dependencies-env
-COPY ./package.json package-lock.json /app/
+COPY Client/package.json Client/package-lock.json /app/
WORKDIR /app
RUN npm ci --omit=dev
FROM node:20-alpine AS build-env
-COPY . /app/
+COPY Client /app/
COPY --from=development-dependencies-env /app/node_modules /app/node_modules
WORKDIR /app
RUN npm run build
FROM node:20-alpine
-COPY ./package.json package-lock.json /app/
+COPY Client/package.json Client/package-lock.json /app/
COPY --from=production-dependencies-env /app/node_modules /app/node_modules
COPY --from=build-env /app/build /app/build
WORKDIR /app
diff --git a/Client/app/api/api.ts b/Client/app/api/api.ts
index 7ab7c11..347b64e 100644
--- a/Client/app/api/api.ts
+++ b/Client/app/api/api.ts
@@ -4,7 +4,7 @@ import type { PaginatedResponse } from "~/types/PaginatedResponse";
import type { Post } from "~/types/post";
import type { Tag } from "~/types/tag";
-const ENDPOINT = 'http://localhost:5259/api';
+const API_URL = import.meta.env.PROD ? '/api' : 'http://localhost:5259/api';
// This is a simplified session renewal handler. It's outside the class
// to avoid circular dependencies or complex context passing.
@@ -14,7 +14,7 @@ const renewSessionAndRetry = async (failedRequest: () => Promise): Pro
if (!refreshToken) return failedRequest();
try {
- const renewResponse = await fetch(`${ENDPOINT}/auth/renew`, {
+ const renewResponse = await fetch(`${API_URL}/auth/renew`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ refreshToken }),
@@ -129,31 +129,31 @@ export class API {
/* Tag APIs */
public static async fetchTags(page: number): Promise> {
- const data = await API.get(`${ENDPOINT}/tags?page=${page}`);
+ const data = await API.get(`${API_URL}/tags?page=${page}`);
return data
}
public static async createTag(name: string, tagType: string, user: User): Promise {
- return await API.post(`${ENDPOINT}/tags`, { name, type: tagType });
+ return await API.post(`${API_URL}/tags`, { name, type: tagType });
}
public static async updateTag(name: string, newType: string, user: User): Promise {
- return await API.patch(`${ENDPOINT}/tags/${encodeURIComponent(name)}`, { type: newType });
+ return await API.patch(`${API_URL}/tags/${encodeURIComponent(name)}`, { type: newType });
}
public static async deleteTag(name: string, user: User): Promise {
- return await API.delete(`${ENDPOINT}/tags/${encodeURIComponent(name)}`, {});
+ return await API.delete(`${API_URL}/tags/${encodeURIComponent(name)}`, {});
}
/* Post APIs */
public static async fetchPostById(id: number): Promise {
- const data = await API.get(`${ENDPOINT}/posts/${id}`);
+ const data = await API.get(`${API_URL}/posts/${id}`);
return data;
}
public static async fetchPosts(page: number, filter: string = ""): Promise> {
- const data = await API.get(`${ENDPOINT}/posts?page=${page}&query=${encodeURIComponent(filter)}`);
+ const data = await API.get(`${API_URL}/posts?page=${page}&query=${encodeURIComponent(filter)}`);
return data
}
@@ -163,7 +163,7 @@ export class API {
fileMimeType: string, fileSize: number,
user: User
): Promise {
- return await API.post(`${ENDPOINT}/posts`, {
+ return await API.post(`${API_URL}/posts`, {
title, description, tags, filename,
fileMimeType, fileSize
});
@@ -183,48 +183,48 @@ export class API {
}
public static async updatePost(postId: number, title: string, description: string, tags: string[], user: User): Promise {
- return await API.patch(`${ENDPOINT}/posts/${postId}`, { title, description, tags });
+ return await API.patch(`${API_URL}/posts/${postId}`, { title, description, tags });
}
public static async deletePost(postId: number, user: User): Promise {
- return await API.delete(`${ENDPOINT}/posts/${postId}`, {});
+ return await API.delete(`${API_URL}/posts/${postId}`, {});
}
/* Comment APIs */
public static async fetchCommentsByPostId(postId: number, page: number): Promise> {
- const data = await API.get(`${ENDPOINT}/posts/${postId}/comments?page=${page}`);
+ const data = await API.get(`${API_URL}/posts/${postId}/comments?page=${page}`);
return data;
}
public static async postComment(postId: number, text: string, user: User): Promise {
- return await API.post(`${ENDPOINT}/posts/${postId}/comments`, { text });
+ return await API.post(`${API_URL}/posts/${postId}/comments`, { text });
}
public static async updateComment(postId: number, commentId: number, newText: string, user: User): Promise {
- return await API.patch(`${ENDPOINT}/posts/${postId}/comments/${commentId}`, { text: newText });
+ return await API.patch(`${API_URL}/posts/${postId}/comments/${commentId}`, { text: newText });
}
public static async deleteComment(postId: number, commentId: number, user: User): Promise {
- return await API.delete(`${ENDPOINT}/posts/${postId}/comments/${commentId}`, {});
+ return await API.delete(`${API_URL}/posts/${postId}/comments/${commentId}`, {});
}
/* Auth APIs */
public static async register(username: string, email: string, password: string): Promise {
- return await API.post(`${ENDPOINT}/auth/register`, { username, email, password });
+ return await API.post(`${API_URL}/auth/register`, { username, email, password });
}
public static async login(email: string, password: string): Promise {
- return await API.post(`${ENDPOINT}/auth/login`, { email, password });
+ return await API.post(`${API_URL}/auth/login`, { email, password });
}
public static async renewToken(refreshToken: string): Promise {
- return await API.post(`${ENDPOINT}/auth/renew`, { refreshToken });
+ return await API.post(`${API_URL}/auth/renew`, { refreshToken });
}
public static async revokeToken(refreshToken: string): Promise {
- return await API.post(`${ENDPOINT}/auth/revoke`, { refreshToken });
+ return await API.post(`${API_URL}/auth/revoke`, { refreshToken });
}
}
diff --git a/compose.yaml b/compose.yaml
index c90ce41..caa5e80 100644
--- a/compose.yaml
+++ b/compose.yaml
@@ -12,6 +12,20 @@
- "8080:8080"
volumes:
- app_data:/app/Storage
+
+ t120b165-imgboard-client:
+ image: t120b165-imgboard-client
+ container_name: t120b165_app_client
+ restart: unless-stopped
+ build:
+ context: .
+ dockerfile: Client/Dockerfile
+ depends_on:
+ - db
+ - t120b165-imgboard
+ ports:
+ - "8000:3000"
+
db:
image: mariadb:lts
container_name: t120b165_db