Skip to content

Commit

Permalink
Feature/refactor codebase (#7)
Browse files Browse the repository at this point in the history
* Move all types to the types folder

* Comment the api files in the client

* Fix download button alignment when sidebar is collapsed

* Enhance deleting tags option

---------

Co-authored-by: David Mang <[email protected]>
  • Loading branch information
mangdavid and David Mang authored Sep 24, 2024
1 parent 125bb7e commit 12b18d2
Show file tree
Hide file tree
Showing 47 changed files with 473 additions and 213 deletions.
4 changes: 2 additions & 2 deletions client/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
rel="stylesheet"
/>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<link rel="icon" type="image/svg+xml" href="/robot.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>MA Mang</title>
<title>Thaii</title>
</head>
<body>
<div id="root"></div>
Expand Down
Binary file added client/public/robot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,22 @@ import PageLayout from "./components/layout/page-layout.component";
import Chatbot from "./components/chatbot/chatbot.component";
import Pages from "./components/pages/pages.component";
import Login from "./components/login/login.component";
import ProtectedRoute from "./components/general/protected-route/protected-route.route";
import ProtectedRoute from "./routes/protected-route/protected-route.route";
import Register from "./components/register/register.component";
import Activation from "./components/register/activation/activation.component";
import AdminTable from "./components/admin-table/admin-table.component";
import Statistics from "./components/statistics/statistics.component";
import NotFound from "./components/not-found/not-found.component";
import InactivityLogout from "./components/general/inactivity-logout/inactivity-logout.component";
import AdminRoute from "./components/general/admin-route/admin-route.component";
import Documentation from "./components/documentation/documentation.component";
import { useAuthStore, useToolStore } from "./states/global.store";
import { getPagesForInsights } from "./services/pages.service";
import { getLabels } from "./services/label.service";
import { getTags } from "./services/tags.service";
import { PageDTO, TagDTO } from "./components/pages/types/pages.types";
import { LabelDTO } from "./types/chatbot/chatbot.types";
import { QueryClient, QueryClientProvider } from "react-query";
import AdminRoute from "./routes/admin-route/admin-route.component";
import { PageDTO, TagDTO } from "./types/page/page.types";

function App() {
const queryClient = new QueryClient()
Expand Down
11 changes: 11 additions & 0 deletions client/src/api/auth.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ const apiRefresh = axios.create({
baseURL: import.meta.env.VITE_API_URL as string,
});

// Authenticate a registered user into the system
// @user: username: string, password: string
// @response: token and refresh token
export const loginUser = async (user: UserBody) => {
try {
const response = await apiRefresh.post("api/v1/token/", user);
Expand All @@ -14,6 +17,9 @@ export const loginUser = async (user: UserBody) => {
}
};

// Refresh expired token with the provided refresh token
// @refresh: JWT to refresh token
// @response: JWT to authenticate user
export const refreshToken = async (refresh: string) => {
try {
const response = await apiRefresh.post("api/v1/token/refresh/", {
Expand All @@ -25,6 +31,9 @@ export const refreshToken = async (refresh: string) => {
}
};

// Register a new user with a username and a password. The username (email) must be whitelisted before registering
// @user: username: string, password: string
// @response: status 201 if created and an email is sent to the email
export const registerUser = async (user: UserBody) => {
try {
const response = await apiRefresh.post("api/v1/user/register/", user);
Expand All @@ -34,6 +43,8 @@ export const registerUser = async (user: UserBody) => {
}
};

// Activate account by by clicking on a link
// @activation: uique query parameters to activate account of users
export const activateUser = async (activation: ActivationBody) => {
try {
const response = await apiRefresh.post("api/v1/user/activate/", activation);
Expand Down
17 changes: 15 additions & 2 deletions client/src/api/insights.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import api from "./interceptor.api";
// - labels: Labels included in analysis
// - tags: Tags included in analysis

// Fetch number of total chats
// Fetches the total number of chats based on the provided filter criteria
export const fetchTotalChats = async (filter: FilterBody) => {
try {
const response = await api.post(`/api/v1/insights/total-chats/`, filter);
Expand All @@ -17,7 +17,7 @@ export const fetchTotalChats = async (filter: FilterBody) => {
}
};

// Fetch number of total messages
// Fetches the total number of messages based on the provided filter criteria
export const fetchTotalMessages = async (filter: FilterBody) => {
try {
const response = await api.post(`/api/v1/insights/total-messages/`, filter);
Expand All @@ -27,6 +27,7 @@ export const fetchTotalMessages = async (filter: FilterBody) => {
}
};

// Fetches chats and messages statistics by a specific time unit
export const fetchChatsMessagesByTime = async (
filter: FilterBody,
item: number
Expand All @@ -42,6 +43,7 @@ export const fetchChatsMessagesByTime = async (
}
};

// Fetches chats and messages statistics by a specific item
export const fetchChatsMessagesByItem = async (
filter: FilterBody,
item: number
Expand All @@ -57,6 +59,7 @@ export const fetchChatsMessagesByItem = async (
}
};

// Fetches the duration of conversations based on the provided filter criteria
export const fetchConversationDuration = async (filter: FilterBody) => {
try {
const response = await api.post(
Expand All @@ -69,6 +72,7 @@ export const fetchConversationDuration = async (filter: FilterBody) => {
}
};

// Fetches conversation duration by specific items
export const fetchConversationDurationByItem = async (
filter: FilterBody,
item: number
Expand All @@ -84,6 +88,7 @@ export const fetchConversationDurationByItem = async (
}
};

// Fetches the total emission statistics based on the filter criteria
export const fetchTotalEmission = async (filter: FilterBody) => {
try {
const response = await api.post(`/api/v1/insights/total-emission/`, filter);
Expand All @@ -93,6 +98,7 @@ export const fetchTotalEmission = async (filter: FilterBody) => {
}
};

// Fetches total water usage statistics based on the filter criteria
export const fetchTotalWater = async (filter: FilterBody) => {
try {
const response = await api.post(`/api/v1/insights/total-water/`, filter);
Expand All @@ -102,6 +108,7 @@ export const fetchTotalWater = async (filter: FilterBody) => {
}
};

// Fetches the total cost statistics based on the filter criteria
export const fetchTotalCost = async (filter: FilterBody) => {
try {
const response = await api.post(`/api/v1/insights/total-cost/`, filter);
Expand All @@ -111,6 +118,7 @@ export const fetchTotalCost = async (filter: FilterBody) => {
}
};

// Fetches tradeoff indicators by a time unit
export const fetchTradeoffIndicatorsByTime = async (
filter: FilterBody,
item: number
Expand All @@ -126,6 +134,7 @@ export const fetchTradeoffIndicatorsByTime = async (
}
};

// Fetches tradeoff indicators by a specific item
export const fetchTradeoffIndicatorsByItem = async (
filter: FilterBody,
item: number
Expand All @@ -141,6 +150,7 @@ export const fetchTradeoffIndicatorsByItem = async (
}
};

// Fetches keywords based on the provided filter criteria
export const fetchKeywords = async (filter: FilterBody) => {
try {
const response = await api.post(`/api/v1/insights/keywords/`, filter);
Expand All @@ -150,6 +160,7 @@ export const fetchKeywords = async (filter: FilterBody) => {
}
};

// Fetches common nouns from the API based on the filter criteria
export const fetchCommonNouns = async (filter: FilterBody) => {
try {
const response = await api.post(`/api/v1/insights/common-nouns/`, filter);
Expand All @@ -159,6 +170,7 @@ export const fetchCommonNouns = async (filter: FilterBody) => {
}
};

// Fetches common verbs from the API based on the filter criteria
export const fetchCommonVerbs = async (filter: FilterBody) => {
try {
const response = await api.post(`/api/v1/insights/common-verbs/`, filter);
Expand All @@ -168,6 +180,7 @@ export const fetchCommonVerbs = async (filter: FilterBody) => {
}
};

// Fetches common adjectives from the API based on the filter criteria
export const fetchCommonAdjectives = async (filter: FilterBody) => {
try {
const response = await api.post(
Expand Down
5 changes: 5 additions & 0 deletions client/src/api/interaction.api.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { EventLogBody } from "../types/interaction/interaction.types";
import api from "./interceptor.api";

// Creates a new event log by sending a POST request with the event log data
// @param eventlog - An object of type EventLogBody containing event log details
// @returns The response from the API if the event log is created successfully
export const createEventLog = async (eventlog: EventLogBody) => {
try {
const response = await api.post("/api/v1/event-logs/", eventlog);
Expand All @@ -11,6 +14,8 @@ export const createEventLog = async (eventlog: EventLogBody) => {
}
};

// Fetches all event logs from the API as a blob (binary large object)
// @returns The response from the API containing the event logs in binary format
export const fetchEventLogs = async () => {
try {
const response = await api.get(`/api/v1/event-logs/`, {
Expand Down
7 changes: 6 additions & 1 deletion client/src/api/interceptor.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,23 @@ import { ACCESS_TOKEN } from "../helpers/auth.helpers";
import { isTokenExpired } from "../helpers/token.helpers";
import { refreshToken } from "./auth.api";

// Creates an axios instance with the base URL set to the environment variable
const api = axios.create({
baseURL: import.meta.env.VITE_API_URL as string,
});

// Interceptor for handling requests, particularly for token management
api.interceptors.request.use(
async (config) => {
// Retrieve the access token from local storage
const token = localStorage.getItem(ACCESS_TOKEN);
// If a token exists, attach it to the request's Authorization header
if (token) {
config.headers.Authorization = `Bearer ${token}`;

// Check if the token is expired
if (isTokenExpired(token)) {
const newToken = await refreshToken(token);
// Save the new token to local storage and update the Authorization header
if (newToken) {
localStorage.setItem(ACCESS_TOKEN, String(newToken));
config.headers.Authorization = `Bearer ${newToken}`;
Expand Down
20 changes: 19 additions & 1 deletion client/src/api/label.api.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { LabelBody } from "../types/chatbot/chatbot.types";
import api from "./interceptor.api";

// Fetches all labels from the API
// @returns The response from the API containing the list of labels
export const fetchLabels = async () => {
try {
const response = await api.get(`/api/v1/labels/`);
Expand All @@ -11,12 +13,28 @@ export const fetchLabels = async () => {
}
};

// Creates a new label by sending a POST request with the label data
// @param label - An object of type LabelBody containing label details
// @returns The response from the API if the label is created successfully
export const createLabel = async (label: LabelBody) => {
try {
const response = await api.post("/api/v1/labels/", label);
return response;
} catch (error) {
console.error("Error creating user:", error);
console.error("Error creating label:", error);
throw error;
}
};

// Delete existing label of user
// @id: id of label to delete
export const deleteLabel = async (id: number) => {
try {
const response = await api.delete(`/api/v1/labels/${id}/`);
return response;
} catch (error) {
console.error("Error deleting label:", error);
throw error;
}
};

7 changes: 7 additions & 0 deletions client/src/api/message.api.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { MessageBody } from "../types/chatbot/chatbot.types";
import api from "./interceptor.api";

// Fetches all messages associated with a specific chat by its ID
// @param chatId - The unique identifier of the chat for which messages are to be fetched
// @returns The response from the API containing the list of messages for the specified chat
export const fetchMessagesByChatId = async (chatId: number) => {
try {
const response = await api.get(`/api/v1/messages/${chatId}/`);
Expand All @@ -10,6 +13,10 @@ export const fetchMessagesByChatId = async (chatId: number) => {
}
};

// Creates a new message in a specific chat by sending a POST request with the message data
// @param chatId - The unique identifier of the chat where the message will be created
// @param message - An object of type MessageBody containing message details (e.g., content, sender)
// @returns The response from the API if the message is created successfully
export const createMessage = async (chatId: number, message: MessageBody) => {
try {
const response = await api.post(`/api/v1/messages/${chatId}/`, message);
Expand Down
20 changes: 18 additions & 2 deletions client/src/api/page.api.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { PageBody } from "../components/pages/types/pages.types";
import { PageBody } from "../types/page/page.types";
import api from "./interceptor.api";

// Fetches all pages from the API
// @returns The response from the API containing the list of all pages
export const fetchPages = async () => {
try {
const response = await api.get(`/api/v1/pages/`);
Expand All @@ -10,6 +12,8 @@ export const fetchPages = async () => {
}
};

// Fetches insight-related pages from the API
// @returns The response from the API containing the list of pages with insights
export const fetchInsightPages = async () => {
try {
const response = await api.get(`/api/v1/pages/insights/`);
Expand All @@ -19,6 +23,9 @@ export const fetchInsightPages = async () => {
}
};

// Fetches a specific page by its ID from the API
// @param pageId - The unique identifier of the page to be fetched
// @returns The response from the API containing the details of the requested page
export const fetchPageById = async (pageId: number) => {
try {
const response = await api.get(`/api/v1/pages/${pageId}/`);
Expand All @@ -28,6 +35,9 @@ export const fetchPageById = async (pageId: number) => {
}
};

// Creates a new page by sending a POST request with the page data
// @param page - An object of type PageBody containing page details
// @returns The response from the API if the page is created successfully
export const createPage = async (page: PageBody) => {
try {
const response = await api.post("/api/v1/pages/", page);
Expand All @@ -37,7 +47,10 @@ export const createPage = async (page: PageBody) => {
}
};


// Updates an existing page by sending a PUT request with the updated page data
// @param id - The unique identifier of the page to be updated
// @param page - An object of type PageBody containing updated page details
// @returns The response from the API if the page is updated successfully
export const changePage = async (id: number, page: PageBody) => {
try {
const response = await api.put(`/api/v1/pages/${id}/`, page);
Expand All @@ -47,6 +60,9 @@ export const changePage = async (id: number, page: PageBody) => {
}
};

// Deletes a specific page by its ID from the API
// @param id - The unique identifier of the page to be deleted
// @returns The response from the API if the page is deleted successfully
export const deletePage = async (id: number) => {
try {
const response = await api.delete(`/api/v1/pages/${id}/`);
Expand Down
Loading

0 comments on commit 12b18d2

Please sign in to comment.