diff --git a/.eslintrc.cjs b/.eslintrc.cjs
index d942c2d5..fb2c88af 100644
--- a/.eslintrc.cjs
+++ b/.eslintrc.cjs
@@ -3,7 +3,6 @@ module.exports = {
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react-hooks/recommended',
- 'plugin:@tanstack/eslint-plugin-query/recommended',
'prettier',
],
parser: '@typescript-eslint/parser',
@@ -28,11 +27,7 @@ module.exports = {
// Warn to encourage type safety, could be upgraded to 'error' for stricter enforcement
'@typescript-eslint/no-explicit-any': 'warn',
- // 5. '@tanstack/query/exhaustive-deps': Ensure exhaustive dependency arrays in React hooks
- // Warn to highlight potential issues, but doesn't necessarily break the build
- '@tanstack/query/exhaustive-deps': 'warn',
-
- // 6. '@typescript-eslint/no-unused-vars': Avoid unused variables, enforcing cleaner code
+ // 5. '@typescript-eslint/no-unused-vars': Avoid unused variables, enforcing cleaner code
// Error to ensure unused variables are caught during linting
'@typescript-eslint/no-unused-vars': [
'error',
diff --git a/.prettierrc.cjs b/.prettierrc.cjs
index c920e99b..7b8b2d7f 100644
--- a/.prettierrc.cjs
+++ b/.prettierrc.cjs
@@ -3,4 +3,5 @@ module.exports = {
singleQuote: true,
quoteProps: 'consistent',
printWidth: 100,
-};
\ No newline at end of file
+ plugins: ['prettier-plugin-tailwindcss'],
+};
diff --git a/package.json b/package.json
index 860d2d4b..ad1e00e1 100644
--- a/package.json
+++ b/package.json
@@ -1,12 +1,11 @@
{
"name": "lexicon-frontend",
"private": true,
- "version": "1.0.0",
"type": "module",
"scripts": {
- "berlin:dev": "pnpm -r --filter berlin dev",
- "berlin:build": "pnpm -r --filter berlin build",
- "berlin:preview": "pnpm -r --filter berlin preview",
+ "dev": "pnpm -r --filter berlin dev",
+ "build": "pnpm -r --filter berlin build",
+ "preview": "pnpm -r --filter berlin preview",
"format": "pnpm exec prettier --check \"packages/**/*.{ts,tsx,json,md}\"",
"format:fix": "pnpm exec prettier --write \"packages/**/*.{ts,tsx,json,md}\"",
"lint": "pnpm exec eslint ."
@@ -14,50 +13,17 @@
"keywords": [],
"author": "",
"license": "ISC",
- "engines": {
- "node": "^20"
- },
- "dependencies": {
- "@hookform/resolvers": "^3.3.4",
- "@pcd/passport-interface": "^0.8.0",
- "@pcd/pcd-types": "^0.8.0",
- "@pcd/semaphore-identity-pcd": "^0.8.0",
- "@pcd/semaphore-signature-pcd": "^0.9.0",
- "@radix-ui/react-dialog": "^1.0.5",
- "@radix-ui/react-icons": "^1.3.0",
- "@tanstack/react-query": "^5.13.4",
- "@tanstack/react-query-devtools": "^5.13.5",
- "class-variance-authority": "^0.7.0",
- "clsx": "^2.1.0",
- "lucide-react": "^0.397.0",
- "react": "^18.2.0",
- "react-content-loader": "^7.0.0",
- "react-dom": "^18.2.0",
- "react-hook-form": "^7.49.3",
- "react-hot-toast": "^2.4.1",
- "react-joyride": "^2.8.2",
- "react-markdown": "^9.0.1",
- "react-router-dom": "^6.20.1",
- "styled-components": "^6.1.1",
- "zod": "^3.22.4",
- "zustand": "^4.4.7"
- },
"devDependencies": {
- "@hookform/devtools": "^4.3.1",
- "@tanstack/eslint-plugin-query": "^5.18.0",
- "@types/node": "^20.12.4",
- "@types/react": "^18.2.37",
- "@types/react-dom": "^18.2.15",
- "@typescript-eslint/eslint-plugin": "^6.19.0",
- "@typescript-eslint/parser": "^6.19.0",
- "@vitejs/plugin-react": "^4.2.0",
- "eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
- "eslint-plugin-react-hooks": "^4.6.0",
- "eslint-plugin-react-refresh": "^0.4.4",
+ "prettier-plugin-tailwindcss": "^0.6.5",
"prettier": "^3.1.1",
- "typescript": "^5.5.2",
- "vite": "^5.0.0",
- "vite-plugin-node-polyfills": "^0.17.0"
+ "eslint": "^8.57.0",
+ "eslint-plugin-react-hooks": "^4.6.0",
+ "eslint-plugin-react-refresh": "^0.4.6",
+ "@typescript-eslint/parser": "^7.2.0",
+ "typescript": "^5.5.2"
+ },
+ "engines": {
+ "node": "^20"
}
-}
\ No newline at end of file
+}
diff --git a/packages/api/package.json b/packages/api/package.json
index 03f62343..05c9fc26 100644
--- a/packages/api/package.json
+++ b/packages/api/package.json
@@ -1,6 +1,6 @@
{
"name": "api",
- "version": "2.4.0",
+ "version": "2.6.0",
"type": "module",
"main": "./src/index.ts"
}
diff --git a/packages/api/src/deleteComment.ts b/packages/api/src/deleteComment.ts
index 9d53e897..a52844a1 100644
--- a/packages/api/src/deleteComment.ts
+++ b/packages/api/src/deleteComment.ts
@@ -1,10 +1,11 @@
-import { DeleteCommentRequest, DeleteCommentResponse } from './types';
+import { ApiRequest, DeleteCommentRequest, DeleteCommentResponse } from './types';
-async function deleteComment({
+export async function deleteComment({
commentId,
-}: DeleteCommentRequest): Promise {
+ serverUrl,
+}: ApiRequest): Promise {
try {
- const response = await fetch(`${import.meta.env.VITE_SERVER_URL}/api/comments/${commentId}`, {
+ const response = await fetch(`${serverUrl}/api/comments/${commentId}`, {
method: 'DELETE',
credentials: 'include',
headers: {
@@ -23,5 +24,3 @@ async function deleteComment({
return null;
}
}
-
-export default deleteComment;
diff --git a/packages/api/src/deleteLike.ts b/packages/api/src/deleteLike.ts
index 2d4d9ac4..2d0a202f 100644
--- a/packages/api/src/deleteLike.ts
+++ b/packages/api/src/deleteLike.ts
@@ -1,17 +1,17 @@
-import { DeleteLikeRequest, DeleteLikeResponse } from './types';
+import { ApiRequest, DeleteLikeRequest, DeleteLikeResponse } from './types';
-async function deleteLike({ commentId }: DeleteLikeRequest): Promise {
+export async function deleteLike({
+ commentId,
+ serverUrl,
+}: ApiRequest): Promise {
try {
- const response = await fetch(
- `${import.meta.env.VITE_SERVER_URL}/api/comments/${commentId}/likes`,
- {
- method: 'DELETE',
- credentials: 'include',
- headers: {
- 'Content-Type': 'application/json',
- },
+ const response = await fetch(`${serverUrl}/api/comments/${commentId}/likes`, {
+ method: 'DELETE',
+ credentials: 'include',
+ headers: {
+ 'Content-Type': 'application/json',
},
- );
+ });
if (!response.ok) {
throw new Error(`HTTP Error! Status: ${response.status}`);
@@ -24,5 +24,3 @@ async function deleteLike({ commentId }: DeleteLikeRequest): Promise {
+ serverUrl,
+}: ApiRequest): Promise<
+ DeleteUsersToGroupsResponse | { errors: string[] } | null
+> {
try {
- const response = await fetch(
- `${import.meta.env.VITE_SERVER_URL}/api/users-to-groups/${userToGroupId}`,
- {
- method: 'DELETE',
- credentials: 'include',
- headers: {
- 'Content-Type': 'application/json',
- },
+ const response = await fetch(`${serverUrl}/api/users-to-groups/${userToGroupId}`, {
+ method: 'DELETE',
+ credentials: 'include',
+ headers: {
+ 'Content-Type': 'application/json',
},
- );
+ });
if (!response.ok) {
if (response.status < 500) {
@@ -33,5 +33,3 @@ async function deleteUsersToGroups({
return null;
}
}
-
-export default deleteUsersToGroups;
diff --git a/packages/api/src/fetchAlerts.ts b/packages/api/src/fetchAlerts.ts
index 3a22dafc..444ee160 100644
--- a/packages/api/src/fetchAlerts.ts
+++ b/packages/api/src/fetchAlerts.ts
@@ -1,8 +1,10 @@
-import { GetAlertsResponse } from './types';
+import { ApiRequest, GetAlertsResponse } from './types';
-async function fetchAlerts(): Promise {
+export async function fetchAlerts({
+ serverUrl,
+}: ApiRequest): Promise {
try {
- const response = await fetch(`${import.meta.env.VITE_SERVER_URL}/api/alerts`, {
+ const response = await fetch(`${serverUrl}/api/alerts`, {
credentials: 'include',
headers: {
'Content-Type': 'application/json',
@@ -20,5 +22,3 @@ async function fetchAlerts(): Promise {
return null;
}
}
-
-export default fetchAlerts;
diff --git a/packages/api/src/fetchCommentLikes.ts b/packages/api/src/fetchCommentLikes.ts
index 7a1e09d7..c73a0031 100644
--- a/packages/api/src/fetchCommentLikes.ts
+++ b/packages/api/src/fetchCommentLikes.ts
@@ -1,16 +1,16 @@
-import { GetLikesRequest, GetLikesResponse } from './types';
+import { ApiRequest, GetLikesRequest, GetLikesResponse } from './types';
-async function fetchLikes({ commentId }: GetLikesRequest): Promise {
+export async function fetchCommentLikes({
+ commentId,
+ serverUrl,
+}: ApiRequest): Promise {
try {
- const response = await fetch(
- `${import.meta.env.VITE_SERVER_URL}/api/comments/${commentId}/likes`,
- {
- credentials: 'include',
- headers: {
- 'Content-type': 'application/json',
- },
+ const response = await fetch(`${serverUrl}/api/comments/${commentId}/likes`, {
+ credentials: 'include',
+ headers: {
+ 'Content-type': 'application/json',
},
- );
+ });
if (!response.ok) {
throw new Error(`HTTP Error! Status: ${response.status}`);
@@ -23,5 +23,3 @@ async function fetchLikes({ commentId }: GetLikesRequest): Promise {
+ serverUrl,
+}: ApiRequest): Promise {
try {
- const response = await fetch(
- `${import.meta.env.VITE_SERVER_URL}/api/options/${optionId}/comments`,
- {
- credentials: 'include',
- headers: {
- 'Content-type': 'application/json',
- },
+ const response = await fetch(`${serverUrl}/api/options/${optionId}/comments`, {
+ credentials: 'include',
+ headers: {
+ 'Content-type': 'application/json',
},
- );
+ });
if (!response.ok) {
throw new Error(`HTTP Error! Status: ${response.status}`);
@@ -25,5 +23,3 @@ async function fetchComments({
return null;
}
}
-
-export default fetchComments;
diff --git a/packages/api/src/fetchCycle.ts b/packages/api/src/fetchCycle.ts
index 788d776b..392ff4f4 100644
--- a/packages/api/src/fetchCycle.ts
+++ b/packages/api/src/fetchCycle.ts
@@ -1,8 +1,11 @@
-import { GetCyclesResponse } from './types';
+import { ApiRequest, GetCyclesResponse } from './types';
-async function fetchCycle(cycleId: string): Promise {
+export async function fetchCycle({
+ cycleId,
+ serverUrl,
+}: ApiRequest<{ cycleId: string }>): Promise {
try {
- const response = await fetch(`${import.meta.env.VITE_SERVER_URL}/api/cycles/${cycleId}`, {
+ const response = await fetch(`${serverUrl}/api/cycles/${cycleId}`, {
credentials: 'include',
headers: {
'Content-Type': 'application/json',
@@ -20,5 +23,3 @@ async function fetchCycle(cycleId: string): Promise {
+export async function fetchCycles({
+ serverUrl,
+}: ApiRequest): Promise {
try {
- const response = await fetch(`${import.meta.env.VITE_SERVER_URL}/api/cycles`, {
+ const response = await fetch(`${serverUrl}/api/cycles`, {
credentials: 'include',
headers: {
'Content-Type': 'application/json',
@@ -20,5 +22,3 @@ async function fetchCycles(): Promise {
return null;
}
}
-
-export default fetchCycles;
diff --git a/packages/api/src/fetchEvent.ts b/packages/api/src/fetchEvent.ts
index 3a8d1843..a6beaa22 100644
--- a/packages/api/src/fetchEvent.ts
+++ b/packages/api/src/fetchEvent.ts
@@ -1,8 +1,11 @@
-import { GetEventResponse } from './types';
+import { ApiRequest, GetEventResponse } from './types';
-async function fetchEvent(eventId: string): Promise {
+export async function fetchEvent({
+ serverUrl,
+ eventId,
+}: ApiRequest<{ eventId: string }>): Promise {
try {
- const response = await fetch(`${import.meta.env.VITE_SERVER_URL}/api/events/${eventId}`, {
+ const response = await fetch(`${serverUrl}/api/events/${eventId}`, {
credentials: 'include',
headers: {
'Content-Type': 'application/json',
@@ -20,5 +23,3 @@ async function fetchEvent(eventId: string): Promise {
return null;
}
}
-
-export default fetchEvent;
diff --git a/packages/api/src/fetchEventCycles.ts b/packages/api/src/fetchEventCycles.ts
index 086f865c..7efdcb39 100644
--- a/packages/api/src/fetchEventCycles.ts
+++ b/packages/api/src/fetchEventCycles.ts
@@ -1,16 +1,16 @@
-import { GetCyclesResponse } from './types';
+import { ApiRequest, GetCyclesResponse } from './types';
-async function fetchEventCycles(eventId: string): Promise {
+export async function fetchEventCycles({
+ eventId,
+ serverUrl,
+}: ApiRequest<{ eventId: string }>): Promise {
try {
- const response = await fetch(
- `${import.meta.env.VITE_SERVER_URL}/api/events/${eventId}/cycles`,
- {
- credentials: 'include',
- headers: {
- 'Content-Type': 'application/json',
- },
+ const response = await fetch(`${serverUrl}/api/events/${eventId}/cycles`, {
+ credentials: 'include',
+ headers: {
+ 'Content-Type': 'application/json',
},
- );
+ });
if (!response.ok) {
throw new Error(`HTTP Error! Status: ${response.status}`);
@@ -23,5 +23,3 @@ async function fetchEventCycles(eventId: string): Promise {
+export async function fetchEventGroupCategories({
+ eventId,
+ serverUrl,
+}: ApiRequest<{ eventId: string }>): Promise {
try {
- const response = await fetch(
- `${import.meta.env.VITE_SERVER_URL}/api/events/${eventId}/group-categories`,
- {
- credentials: 'include',
- headers: {
- 'Content-Type': 'application/json',
- },
+ const response = await fetch(`${serverUrl}/api/events/${eventId}/group-categories`, {
+ credentials: 'include',
+ headers: {
+ 'Content-Type': 'application/json',
},
- );
+ });
if (!response.ok) {
throw new Error(`HTTP Error! Status: ${response.status}`);
@@ -25,5 +23,3 @@ async function fetchEventGroupCategories(
return null;
}
}
-
-export default fetchEventGroupCategories;
diff --git a/packages/api/src/fetchEvents.ts b/packages/api/src/fetchEvents.ts
index ebe15c99..0df4240f 100644
--- a/packages/api/src/fetchEvents.ts
+++ b/packages/api/src/fetchEvents.ts
@@ -1,8 +1,10 @@
-import { GetEventsResponse } from './types';
+import { ApiRequest, GetEventsResponse } from './types';
-async function fetchEvents(): Promise {
+export async function fetchEvents({
+ serverUrl,
+}: ApiRequest): Promise {
try {
- const response = await fetch(`${import.meta.env.VITE_SERVER_URL}/api/events`, {
+ const response = await fetch(`${serverUrl}/api/events`, {
credentials: 'include',
headers: {
'Content-Type': 'application/json',
@@ -20,5 +22,3 @@ async function fetchEvents(): Promise {
return null;
}
}
-
-export default fetchEvents;
diff --git a/packages/api/src/fetchForumQuestionFunding.ts b/packages/api/src/fetchForumQuestionFunding.ts
deleted file mode 100644
index e8ab651f..00000000
--- a/packages/api/src/fetchForumQuestionFunding.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import { GetFundingResponse } from './types';
-
-async function fetchForumQuestionFunding(questionId: string): Promise {
- try {
- const response = await fetch(
- `${import.meta.env.VITE_SERVER_URL}/api/forum-questions/${questionId}/funding`,
- {
- credentials: 'include',
- headers: {
- 'Content-Type': 'application/json',
- },
- },
- );
- if (!response.ok) {
- throw new Error(`HTTP Error! Status: ${response.status}`);
- }
-
- const stats = (await response.json()) as { data: GetFundingResponse };
- return stats.data;
- } catch (error) {
- console.error('Error fetching forum question funding:', error);
- return null;
- }
-}
-
-export default fetchForumQuestionFunding;
diff --git a/packages/api/src/fetchForumQuestionStatistics.ts b/packages/api/src/fetchForumQuestionStatistics.ts
deleted file mode 100644
index fe14e18d..00000000
--- a/packages/api/src/fetchForumQuestionStatistics.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import { GetForumQuestionStatisticsResponse } from './types';
-
-async function fetchForumQuestionStatistics(
- questionId: string,
-): Promise {
- try {
- const response = await fetch(
- `${import.meta.env.VITE_SERVER_URL}/api/forum-questions/${questionId}/statistics`,
- {
- credentials: 'include',
- headers: {
- 'Content-Type': 'application/json',
- },
- },
- );
- if (!response.ok) {
- throw new Error(`HTTP Error! Status: ${response.status}`);
- }
-
- const stats = (await response.json()) as { data: GetForumQuestionStatisticsResponse };
- return stats.data;
- } catch (error) {
- console.error('Error fetching forum question statistics:', error);
- return null;
- }
-}
-
-export default fetchForumQuestionStatistics;
diff --git a/packages/api/src/fetchGroupCategories.ts b/packages/api/src/fetchGroupCategories.ts
index f9c4d49d..7fdc3a82 100644
--- a/packages/api/src/fetchGroupCategories.ts
+++ b/packages/api/src/fetchGroupCategories.ts
@@ -1,8 +1,10 @@
-import { GetGroupCategoriesResponse } from './types';
+import { ApiRequest, GetGroupCategoriesResponse } from './types';
-async function fetchGroupCategories(): Promise {
+export async function fetchGroupCategories({
+ serverUrl,
+}: ApiRequest): Promise {
try {
- const response = await fetch(`${import.meta.env.VITE_SERVER_URL}/api/group-categories`, {
+ const response = await fetch(`${serverUrl}/api/group-categories`, {
credentials: 'include',
headers: {
'Content-type': 'application/json',
@@ -20,5 +22,3 @@ async function fetchGroupCategories(): Promise {
+export async function fetchGroupMembers({
+ serverUrl,
+ groupId,
+}: ApiRequest<{ groupId: string }>): Promise {
try {
- const response = await fetch(
- `${import.meta.env.VITE_SERVER_URL}/api/groups/${groupId}/users-to-groups`,
- {
- credentials: 'include',
- headers: {
- 'Content-type': 'application/json',
- },
+ const response = await fetch(`${serverUrl}/api/groups/${groupId}/users-to-groups`, {
+ credentials: 'include',
+ headers: {
+ 'Content-type': 'application/json',
},
- );
+ });
if (!response.ok) {
throw new Error(`HTTP Error! Status: ${response.status}`);
@@ -23,5 +23,3 @@ async function fetchGroupMembers(groupId: string): Promise {
+export async function fetchGroupRegistrations({
+ serverUrl,
+ groupId,
+}: ApiRequest<{ groupId: string }>): Promise {
try {
- const response = await fetch(
- `${import.meta.env.VITE_SERVER_URL}/api/groups/${groupId}/registrations`,
- {
- credentials: 'include',
- headers: {
- 'Content-type': 'application/json',
- },
+ const response = await fetch(`${serverUrl}/api/groups/${groupId}/registrations`, {
+ credentials: 'include',
+ headers: {
+ 'Content-type': 'application/json',
},
- );
+ });
if (!response.ok) {
throw new Error(`HTTP Error! Status: ${response.status}`);
@@ -23,5 +23,3 @@ async function fetchGroupRegistrations(groupId: string): Promise {
+}: ApiRequest<{ groupCategoryId: string }>): Promise {
try {
- const response = await fetch(
- `${import.meta.env.VITE_SERVER_URL}/api/group-categories/${groupCategoryId}/groups`,
- {
- credentials: 'include',
- headers: {
- 'Content-type': 'application/json',
- },
+ const response = await fetch(`${serverUrl}/api/group-categories/${groupCategoryId}/groups`, {
+ credentials: 'include',
+ headers: {
+ 'Content-type': 'application/json',
},
- );
+ });
if (!response.ok) {
throw new Error(`HTTP Error! Status: ${response.status}`);
@@ -27,5 +23,3 @@ async function fetchGroups({
return null;
}
}
-
-export default fetchGroups;
diff --git a/packages/api/src/fetchOption.ts b/packages/api/src/fetchOption.ts
index 4b483e5b..9feccc95 100644
--- a/packages/api/src/fetchOption.ts
+++ b/packages/api/src/fetchOption.ts
@@ -1,8 +1,11 @@
-import { GetQuestionOptionResponse } from './types';
+import { ApiRequest, GetOptionResponse } from './types';
-async function fetchOption(optionId: string): Promise {
+export async function fetchOption({
+ serverUrl,
+ optionId,
+}: ApiRequest<{ optionId: string }>): Promise {
try {
- const response = await fetch(`${import.meta.env.VITE_SERVER_URL}/api/options/${optionId}`, {
+ const response = await fetch(`${serverUrl}/api/options/${optionId}`, {
credentials: 'include',
headers: {
'Content-type': 'application/json',
@@ -12,12 +15,10 @@ async function fetchOption(optionId: string): Promise {
+export async function fetchOptionUsers({
+ serverUrl,
+ optionId,
+}: ApiRequest<{ optionId: string }>): Promise {
try {
- const response = await fetch(
- `${import.meta.env.VITE_SERVER_URL}/api/options/${optionId}/users`,
- {
- credentials: 'include',
- headers: {
- 'Content-Type': 'application/json',
- },
+ const response = await fetch(`${serverUrl}/api/options/${optionId}/users`, {
+ credentials: 'include',
+ headers: {
+ 'Content-Type': 'application/json',
},
- );
+ });
if (!response.ok) {
throw new Error(`HTTP Error! Status: ${response.status}`);
@@ -23,5 +23,3 @@ async function fetchOptionUsers(optionId: string): Promise): Promise {
+ try {
+ const response = await fetch(`${serverUrl}/api/questions/${questionId}/funding`, {
+ credentials: 'include',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ });
+ if (!response.ok) {
+ throw new Error(`HTTP Error! Status: ${response.status}`);
+ }
+
+ const stats = (await response.json()) as { data: GetFundingResponse };
+ return stats.data;
+ } catch (error) {
+ console.error('Error fetching forum question funding:', error);
+ return null;
+ }
+}
diff --git a/packages/api/src/fetchQuestionStatistics.ts b/packages/api/src/fetchQuestionStatistics.ts
new file mode 100644
index 00000000..aeeb3578
--- /dev/null
+++ b/packages/api/src/fetchQuestionStatistics.ts
@@ -0,0 +1,24 @@
+import { ApiRequest, GetQuestionStatisticsResponse } from './types';
+
+export async function fetchQuestionStatistics({
+ serverUrl,
+ questionId,
+}: ApiRequest<{ questionId: string }>): Promise {
+ try {
+ const response = await fetch(`${serverUrl}/api/questions/${questionId}/statistics`, {
+ credentials: 'include',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ });
+ if (!response.ok) {
+ throw new Error(`HTTP Error! Status: ${response.status}`);
+ }
+
+ const stats = (await response.json()) as { data: GetQuestionStatisticsResponse };
+ return stats.data;
+ } catch (error) {
+ console.error('Error fetching forum question statistics:', error);
+ return null;
+ }
+}
diff --git a/packages/api/src/fetchRegistrationData.ts b/packages/api/src/fetchRegistrationData.ts
index a896fa7d..01a7267a 100644
--- a/packages/api/src/fetchRegistrationData.ts
+++ b/packages/api/src/fetchRegistrationData.ts
@@ -1,11 +1,12 @@
-import { GetRegistrationDataResponse } from './types';
+import { ApiRequest, GetRegistrationDataResponse } from './types';
-async function fetchRegistrationData(
- registrationId: string,
-): Promise {
+export async function fetchRegistrationData({
+ serverUrl,
+ registrationId,
+}: ApiRequest<{ registrationId: string }>): Promise {
try {
const response = await fetch(
- `${import.meta.env.VITE_SERVER_URL}/api/registrations/${registrationId}/registration-data`,
+ `${serverUrl}/api/registrations/${registrationId}/registration-data`,
{
credentials: 'include',
headers: {
@@ -25,5 +26,3 @@ async function fetchRegistrationData(
return null;
}
}
-
-export default fetchRegistrationData;
diff --git a/packages/api/src/fetchRegistrationFields.ts b/packages/api/src/fetchRegistrationFields.ts
index 6b92592e..56840ea2 100644
--- a/packages/api/src/fetchRegistrationFields.ts
+++ b/packages/api/src/fetchRegistrationFields.ts
@@ -1,18 +1,16 @@
-import { GetRegistrationFieldsResponse } from './types';
+import { ApiRequest, GetRegistrationFieldsResponse } from './types';
-async function fetchRegistrationFields(
- eventId: string,
-): Promise {
+export async function fetchRegistrationFields({
+ serverUrl,
+ eventId,
+}: ApiRequest<{ eventId: string }>): Promise {
try {
- const response = await fetch(
- `${import.meta.env.VITE_SERVER_URL}/api/events/${eventId}/registration-fields`,
- {
- credentials: 'include',
- headers: {
- 'Content-Type': 'application/json',
- },
+ const response = await fetch(`${serverUrl}/api/events/${eventId}/registration-fields`, {
+ credentials: 'include',
+ headers: {
+ 'Content-Type': 'application/json',
},
- );
+ });
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
@@ -25,5 +23,3 @@ async function fetchRegistrationFields(
return null;
}
}
-
-export default fetchRegistrationFields;
diff --git a/packages/api/src/fetchRegistrations.ts b/packages/api/src/fetchRegistrations.ts
index 48ec2aac..364f8a23 100644
--- a/packages/api/src/fetchRegistrations.ts
+++ b/packages/api/src/fetchRegistrations.ts
@@ -1,16 +1,16 @@
-import { GetRegistrationsResponseType } from './types';
+import { ApiRequest, GetRegistrationsResponseType } from './types';
-async function fetchRegistrations(eventId: string): Promise {
+export async function fetchRegistrations({
+ serverUrl,
+ eventId,
+}: ApiRequest<{ eventId: string }>): Promise {
try {
- const response = await fetch(
- `${import.meta.env.VITE_SERVER_URL}/api/events/${eventId}/registrations`,
- {
- credentials: 'include',
- headers: {
- 'Content-Type': 'application/json',
- },
+ const response = await fetch(`${serverUrl}/api/events/${eventId}/registrations`, {
+ credentials: 'include',
+ headers: {
+ 'Content-Type': 'application/json',
},
- );
+ });
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
@@ -27,5 +27,3 @@ async function fetchRegistrations(eventId: string): Promise {
+export async function fetchUser({
+ serverUrl,
+}: ApiRequest): Promise {
try {
- const response = await fetch(`${import.meta.env.VITE_SERVER_URL}/api/users`, {
+ const response = await fetch(`${serverUrl}/api/users`, {
credentials: 'include',
headers: {
'Content-Type': 'application/json',
@@ -20,5 +22,3 @@ async function fetchUserData(): Promise {
return null;
}
}
-
-export default fetchUserData;
diff --git a/packages/api/src/fetchUserAttributes.ts b/packages/api/src/fetchUserAttributes.ts
index cf718a2f..7b5948e2 100644
--- a/packages/api/src/fetchUserAttributes.ts
+++ b/packages/api/src/fetchUserAttributes.ts
@@ -1,16 +1,16 @@
-import { GetUserAttributesResponse } from './types';
+import { ApiRequest, GetUserAttributesResponse } from './types';
-async function fetchUserAttributes(userId: string): Promise {
+export async function fetchUserAttributes({
+ serverUrl,
+ userId,
+}: ApiRequest<{ userId: string }>): Promise {
try {
- const response = await fetch(
- `${import.meta.env.VITE_SERVER_URL}/api/users/${userId}/attributes`,
- {
- credentials: 'include',
- headers: {
- 'Content-Type': 'application/json',
- },
+ const response = await fetch(`${serverUrl}/api/users/${userId}/attributes`, {
+ credentials: 'include',
+ headers: {
+ 'Content-Type': 'application/json',
},
- );
+ });
if (!response.ok) {
throw new Error(`HTTP Error! Status: ${response.status}`);
@@ -23,5 +23,3 @@ async function fetchUserAttributes(userId: string): Promise): Promise {
+ try {
+ const response = await fetch(`${serverUrl}/api/users/${userId}/options`, {
+ credentials: 'include',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ });
+
+ if (!response.ok) {
+ throw new Error(`HTTP Error! Status: ${response.status}`);
+ }
+
+ const userOptions = (await response.json()) as { data: GetUserOptionsResponse };
+ return userOptions.data;
+ } catch (error) {
+ console.error('Error fetching user options:', error);
+ return null;
+ }
+}
diff --git a/packages/api/src/fetchUserRegistrations.ts b/packages/api/src/fetchUserRegistrations.ts
index 0ee8786f..ed741920 100644
--- a/packages/api/src/fetchUserRegistrations.ts
+++ b/packages/api/src/fetchUserRegistrations.ts
@@ -1,18 +1,16 @@
-import { GetRegistrationsResponseType } from './types';
+import { ApiRequest, GetRegistrationsResponseType } from './types';
-async function fetchUserRegistrations(
- userId: string,
-): Promise {
+export async function fetchUserRegistrations({
+ serverUrl,
+ userId,
+}: ApiRequest<{ userId: string }>): Promise {
try {
- const response = await fetch(
- `${import.meta.env.VITE_SERVER_URL}/api/users/${userId}/registrations`,
- {
- credentials: 'include',
- headers: {
- 'Content-Type': 'application/json',
- },
+ const response = await fetch(`${serverUrl}/api/users/${userId}/registrations`, {
+ credentials: 'include',
+ headers: {
+ 'Content-Type': 'application/json',
},
- );
+ });
if (!response.ok) {
throw new Error(`HTTP Error! Status: ${response.status}`);
@@ -25,5 +23,3 @@ async function fetchUserRegistrations(
return null;
}
}
-
-export default fetchUserRegistrations;
diff --git a/packages/api/src/fetchUserVotes.ts b/packages/api/src/fetchUserVotes.ts
index d957578a..fab3d056 100644
--- a/packages/api/src/fetchUserVotes.ts
+++ b/packages/api/src/fetchUserVotes.ts
@@ -1,8 +1,11 @@
-import { GetUserVotesResponse } from './types';
+import { ApiRequest, GetUserVotesResponse } from './types';
-async function fetchUserVotes(cycleId: string): Promise {
+export async function fetchUserVotes({
+ serverUrl,
+ cycleId,
+}: ApiRequest<{ cycleId: string }>): Promise {
try {
- const response = await fetch(`${import.meta.env.VITE_SERVER_URL}/api/cycles/${cycleId}/votes`, {
+ const response = await fetch(`${serverUrl}/api/cycles/${cycleId}/votes`, {
credentials: 'include',
headers: {
'Content-Type': 'application/json',
@@ -19,5 +22,3 @@ async function fetchUserVotes(cycleId: string): Promise {
+export async function fetchUsersToGroups({
+ serverUrl,
+ userId,
+}: ApiRequest<{ userId: string }>): Promise {
try {
- const response = await fetch(
- `${import.meta.env.VITE_SERVER_URL}/api/users/${userId}/users-to-groups`,
- {
- credentials: 'include',
- headers: {
- 'Content-Type': 'application/json',
- },
+ const response = await fetch(`${serverUrl}/api/users/${userId}/users-to-groups`, {
+ credentials: 'include',
+ headers: {
+ 'Content-Type': 'application/json',
},
- );
+ });
if (!response.ok) {
throw new Error(`HTTP Error! Status: ${response.status}`);
@@ -23,5 +23,3 @@ async function fetchUsersToGroups(userId: string): Promise) {
try {
- const response = await fetch(`${import.meta.env.VITE_SERVER_URL}/api/auth/logout`, {
+ const response = await fetch(`${serverUrl}/api/auth/logout`, {
method: 'POST',
credentials: 'include',
headers: {
@@ -18,5 +20,3 @@ async function logout() {
throw new Error('Logout failed');
}
}
-
-export default logout;
diff --git a/packages/api/src/postComment.ts b/packages/api/src/postComment.ts
index 35a8c0ed..e7693bc5 100644
--- a/packages/api/src/postComment.ts
+++ b/packages/api/src/postComment.ts
@@ -1,11 +1,12 @@
-import { PostCommentRequest, PostCommentResponse } from './types';
+import { ApiRequest, PostCommentRequest, PostCommentResponse } from './types';
-async function postComment({
+export async function postComment({
questionOptionId,
value,
-}: PostCommentRequest): Promise {
+ serverUrl,
+}: ApiRequest): Promise {
try {
- const response = await fetch(`${import.meta.env.VITE_SERVER_URL}/api/comments`, {
+ const response = await fetch(`${serverUrl}/api/comments`, {
method: 'POST',
credentials: 'include',
headers: {
@@ -25,5 +26,3 @@ async function postComment({
return null;
}
}
-
-export default postComment;
diff --git a/packages/api/src/postGroup.ts b/packages/api/src/postGroup.ts
index 53bd46c2..61d90694 100644
--- a/packages/api/src/postGroup.ts
+++ b/packages/api/src/postGroup.ts
@@ -1,11 +1,12 @@
-import { PostGroupRequest, PostGroupResponse } from './types';
+import { ApiRequest, PostGroupRequest, PostGroupResponse } from './types';
-async function postGroup({
+export async function postGroup({
name,
groupCategoryId,
-}: PostGroupRequest): Promise {
+ serverUrl,
+}: ApiRequest): Promise {
try {
- const response = await fetch(`${import.meta.env.VITE_SERVER_URL}/api/groups`, {
+ const response = await fetch(`${serverUrl}/api/groups`, {
method: 'POST',
credentials: 'include',
headers: {
@@ -28,5 +29,3 @@ async function postGroup({
return null;
}
}
-
-export default postGroup;
diff --git a/packages/api/src/postLike.ts b/packages/api/src/postLike.ts
index 5b1e7099..75d3ed85 100644
--- a/packages/api/src/postLike.ts
+++ b/packages/api/src/postLike.ts
@@ -1,17 +1,17 @@
-import { PostLikeRequest, PostLikeResponse } from './types';
+import { ApiRequest, PostLikeRequest, PostLikeResponse } from './types';
-async function postLike({ commentId }: PostLikeRequest): Promise {
+export async function postLike({
+ commentId,
+ serverUrl,
+}: ApiRequest): Promise {
try {
- const response = await fetch(
- `${import.meta.env.VITE_SERVER_URL}/api/comments/${commentId}/likes`,
- {
- method: 'POST',
- credentials: 'include',
- headers: {
- 'Content-Type': 'application/json',
- },
+ const response = await fetch(`${serverUrl}/api/comments/${commentId}/likes`, {
+ method: 'POST',
+ credentials: 'include',
+ headers: {
+ 'Content-Type': 'application/json',
},
- );
+ });
if (!response.ok) {
throw new Error(`HTTP Error! Status: ${response.status}`);
@@ -24,5 +24,3 @@ async function postLike({ commentId }: PostLikeRequest): Promise {
+}>): Promise {
try {
- const response = await fetch(`${import.meta.env.VITE_SERVER_URL}/api/registrations`, {
+ const response = await fetch(`${serverUrl}/api/registrations`, {
method: 'POST',
credentials: 'include',
headers: {
@@ -16,6 +17,10 @@ async function postRegistration({
});
if (!response.ok) {
+ if (response.status < 500) {
+ const errors = (await response.json()) as { errors: string[] };
+ return errors;
+ }
throw new Error(`HTTP error! Status: ${response.status}`);
}
@@ -26,5 +31,3 @@ async function postRegistration({
return null;
}
}
-
-export default postRegistration;
diff --git a/packages/api/src/postUsersToGroups.ts b/packages/api/src/postUsersToGroups.ts
index a4357b9b..f39f3877 100644
--- a/packages/api/src/postUsersToGroups.ts
+++ b/packages/api/src/postUsersToGroups.ts
@@ -1,11 +1,14 @@
-import { PostUsersToGroupsRequest, PostUsersToGroupsResponse } from './types';
+import { ApiRequest, PostUsersToGroupsRequest, PostUsersToGroupsResponse } from './types';
-async function postUserToGroups({
+export async function postUsersToGroups({
secret,
groupId,
-}: PostUsersToGroupsRequest): Promise {
+ serverUrl,
+}: ApiRequest): Promise<
+ PostUsersToGroupsResponse | { errors: string[] } | null
+> {
try {
- const response = await fetch(`${import.meta.env.VITE_SERVER_URL}/api/users-to-groups`, {
+ const response = await fetch(`${serverUrl}/api/users-to-groups`, {
method: 'POST',
credentials: 'include',
headers: {
@@ -32,5 +35,3 @@ async function postUserToGroups({
return null;
}
}
-
-export default postUserToGroups;
diff --git a/packages/api/src/postVerify.ts b/packages/api/src/postVerify.ts
index 9b68549d..d3753ce8 100644
--- a/packages/api/src/postVerify.ts
+++ b/packages/api/src/postVerify.ts
@@ -1,18 +1,23 @@
-import { GetUserResponse } from './types';
+import { ApiRequest, GetUserResponse } from './types';
-async function postVerify(body: {
+export async function postVerify({
+ email,
+ pcdStr,
+ serverUrl,
+ uuid,
+}: ApiRequest<{
pcdStr: string;
email: string;
uuid: string;
-}): Promise {
+}>): Promise {
try {
- const response = await fetch(`${import.meta.env.VITE_SERVER_URL}/api/auth/zupass/verify`, {
+ const response = await fetch(`${serverUrl}/api/auth/zupass/verify`, {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
},
- body: JSON.stringify({ pcd: body.pcdStr, email: body.email, uuid: body.uuid }),
+ body: JSON.stringify({ pcd: pcdStr, email: email, uuid: uuid }),
});
if (!response.ok) {
@@ -26,5 +31,3 @@ async function postVerify(body: {
return null;
}
}
-
-export default postVerify;
diff --git a/packages/api/src/postVotes.ts b/packages/api/src/postVotes.ts
index 2f660a9b..b486afc4 100644
--- a/packages/api/src/postVotes.ts
+++ b/packages/api/src/postVotes.ts
@@ -1,8 +1,11 @@
-import { PostVotesRequest, PostVotesResponse } from './types';
+import { ApiRequest, PostVotesRequest, PostVotesResponse } from './types';
-async function postVotes({ votes }: PostVotesRequest): Promise {
+export async function postVotes({
+ votes,
+ serverUrl,
+}: ApiRequest): Promise {
try {
- const response = await fetch(`${import.meta.env.VITE_SERVER_URL}/api/votes`, {
+ const response = await fetch(`${serverUrl}/api/votes`, {
method: 'POST',
credentials: 'include',
headers: {
@@ -22,5 +25,3 @@ async function postVotes({ votes }: PostVotesRequest): Promise {
+}>): Promise {
try {
- const response = await fetch(
- `${import.meta.env.VITE_SERVER_URL}/api/registrations/${registrationId}`,
- {
- method: 'PUT',
- credentials: 'include',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify(body),
+ const response = await fetch(`${serverUrl}/api/registrations/${registrationId}`, {
+ method: 'PUT',
+ credentials: 'include',
+ headers: {
+ 'Content-Type': 'application/json',
},
- );
+ body: JSON.stringify(body),
+ });
if (!response.ok) {
+ if (response.status < 500) {
+ const errors = (await response.json()) as { errors: string[] };
+ return errors;
+ }
throw new Error(`HTTP error! Status: ${response.status}`);
}
@@ -31,5 +33,3 @@ async function putRegistration({
return null;
}
}
-
-export default putRegistration;
diff --git a/packages/api/src/putUser.ts b/packages/api/src/putUser.ts
index e492ee00..cffd455f 100644
--- a/packages/api/src/putUser.ts
+++ b/packages/api/src/putUser.ts
@@ -1,16 +1,16 @@
-import { PutUserRequest, GetUserResponse } from './types';
+import { PutUserRequest, GetUserResponse, ApiRequest } from './types';
-async function updateUserData({
+export async function putUser({
email,
firstName,
lastName,
telegram,
- userAttributes,
userId,
username,
-}: PutUserRequest): Promise<{ data: GetUserResponse } | { errors: string[] } | null> {
+ serverUrl,
+}: ApiRequest): Promise<{ data: GetUserResponse } | { errors: string[] } | null> {
try {
- const response = await fetch(`${import.meta.env.VITE_SERVER_URL}/api/users/${userId}`, {
+ const response = await fetch(`${serverUrl}/api/users/${userId}`, {
method: 'PUT',
credentials: 'include',
headers: {
@@ -21,7 +21,6 @@ async function updateUserData({
firstName,
lastName,
telegram,
- userAttributes,
username,
}),
});
@@ -41,5 +40,3 @@ async function updateUserData({
return null;
}
}
-
-export default updateUserData;
diff --git a/packages/api/src/putUsersToGroups.ts b/packages/api/src/putUsersToGroups.ts
index 94e3fd08..96f1abcb 100644
--- a/packages/api/src/putUsersToGroups.ts
+++ b/packages/api/src/putUsersToGroups.ts
@@ -1,21 +1,21 @@
-import { PostUsersToGroupsResponse, PutUsersToGroupsRequest } from './types';
+import { ApiRequest, PostUsersToGroupsResponse, PutUsersToGroupsRequest } from './types';
-async function postUsersToGroups({
+export async function putUsersToGroups({
groupId,
userToGroupId,
-}: PutUsersToGroupsRequest): Promise {
+ serverUrl,
+}: ApiRequest): Promise<
+ PostUsersToGroupsResponse | { errors: string[] } | null
+> {
try {
- const response = await fetch(
- `${import.meta.env.VITE_SERVER_URL}/api/users-to-groups/${userToGroupId}`,
- {
- method: 'PUT',
- credentials: 'include',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({ groupId }),
+ const response = await fetch(`${serverUrl}/api/users-to-groups/${userToGroupId}`, {
+ method: 'PUT',
+ credentials: 'include',
+ headers: {
+ 'Content-Type': 'application/json',
},
- );
+ body: JSON.stringify({ groupId }),
+ });
if (!response.ok) {
if (response.status < 500) {
@@ -35,5 +35,3 @@ async function postUsersToGroups({
return null;
}
}
-
-export default postUsersToGroups;
diff --git a/packages/api/src/types/AlertType.ts b/packages/api/src/types/Alerts.ts
similarity index 100%
rename from packages/api/src/types/AlertType.ts
rename to packages/api/src/types/Alerts.ts
diff --git a/packages/api/src/types/ApiRequest.ts b/packages/api/src/types/ApiRequest.ts
new file mode 100644
index 00000000..9186407e
--- /dev/null
+++ b/packages/api/src/types/ApiRequest.ts
@@ -0,0 +1,3 @@
+export type ApiRequest = {
+ serverUrl: string;
+} & T;
diff --git a/packages/api/src/types/CommentType.ts b/packages/api/src/types/Comments.ts
similarity index 100%
rename from packages/api/src/types/CommentType.ts
rename to packages/api/src/types/Comments.ts
diff --git a/packages/api/src/types/CycleType.ts b/packages/api/src/types/Cycles.ts
similarity index 89%
rename from packages/api/src/types/CycleType.ts
rename to packages/api/src/types/Cycles.ts
index b95e5612..f9952921 100644
--- a/packages/api/src/types/CycleType.ts
+++ b/packages/api/src/types/Cycles.ts
@@ -1,25 +1,26 @@
export type GetCycleResponse = {
id: string;
+ eventId: string;
createdAt: string;
updatedAt: string;
status: 'OPEN' | 'CLOSED' | 'UPCOMING' | null;
startAt: string;
endAt: string;
- forumQuestions: {
+ questions: {
id: string;
showScore: boolean;
createdAt: string;
updatedAt: string;
questionSubTitle: string | null;
cycleId: string;
- questionTitle: string;
- questionOptions: {
+ title: string;
+ options: {
id: string;
createdAt: string;
updatedAt: string;
questionId: string;
- optionTitle: string;
- optionSubTitle?: string;
+ title: string;
+ subTitle?: string;
accepted: boolean;
voteScore?: number;
fundingRequest: string;
diff --git a/packages/api/src/types/EventType.ts b/packages/api/src/types/Events.ts
similarity index 80%
rename from packages/api/src/types/EventType.ts
rename to packages/api/src/types/Events.ts
index 7cd41f4e..2ea07899 100644
--- a/packages/api/src/types/EventType.ts
+++ b/packages/api/src/types/Events.ts
@@ -7,6 +7,8 @@ export type GetEventResponse = {
createdAt: string;
updatedAt: string;
description: string | null;
+ fields: unknown;
+ status: 'OPEN' | 'CLOSED' | 'UPCOMING' | null;
};
export type GetEventsResponse = GetEventResponse[];
diff --git a/packages/api/src/types/FundingType.ts b/packages/api/src/types/Funding.ts
similarity index 100%
rename from packages/api/src/types/FundingType.ts
rename to packages/api/src/types/Funding.ts
diff --git a/packages/api/src/types/GroupCategoryType.ts b/packages/api/src/types/GroupCategories.ts
similarity index 100%
rename from packages/api/src/types/GroupCategoryType.ts
rename to packages/api/src/types/GroupCategories.ts
diff --git a/packages/api/src/types/GroupMembersType.ts b/packages/api/src/types/GroupMembers.ts
similarity index 100%
rename from packages/api/src/types/GroupMembersType.ts
rename to packages/api/src/types/GroupMembers.ts
diff --git a/packages/api/src/types/GroupRegistrationsType.ts b/packages/api/src/types/GroupRegistrations.ts
similarity index 100%
rename from packages/api/src/types/GroupRegistrationsType.ts
rename to packages/api/src/types/GroupRegistrations.ts
diff --git a/packages/api/src/types/GroupType.ts b/packages/api/src/types/Groups.ts
similarity index 100%
rename from packages/api/src/types/GroupType.ts
rename to packages/api/src/types/Groups.ts
diff --git a/packages/api/src/types/LikeType.ts b/packages/api/src/types/Likes.ts
similarity index 100%
rename from packages/api/src/types/LikeType.ts
rename to packages/api/src/types/Likes.ts
diff --git a/packages/api/src/types/OptionUsersType.ts b/packages/api/src/types/OptionUsers.ts
similarity index 100%
rename from packages/api/src/types/OptionUsersType.ts
rename to packages/api/src/types/OptionUsers.ts
diff --git a/packages/api/src/types/QuestionOptionType.ts b/packages/api/src/types/Options.ts
similarity index 63%
rename from packages/api/src/types/QuestionOptionType.ts
rename to packages/api/src/types/Options.ts
index 659b519a..8c0dbfe6 100644
--- a/packages/api/src/types/QuestionOptionType.ts
+++ b/packages/api/src/types/Options.ts
@@ -1,4 +1,4 @@
-export type QuestionOption = {
+export type Option = {
id: string;
createdAt: string;
updatedAt: string;
@@ -7,11 +7,12 @@ export type QuestionOption = {
userId?: string;
optionSubTitle?: string;
accepted: boolean;
+ data: unknown;
fundingRequest: string;
};
-export type GetQuestionOptionRequest = {
+export type GetOptionRequest = {
optionId: string;
};
-export type GetQuestionOptionResponse = QuestionOption;
+export type GetOptionResponse = Option;
diff --git a/packages/api/src/types/ForumQuestionType.ts b/packages/api/src/types/Questions.ts
similarity index 85%
rename from packages/api/src/types/ForumQuestionType.ts
rename to packages/api/src/types/Questions.ts
index c8cd09ee..3e9b1805 100644
--- a/packages/api/src/types/ForumQuestionType.ts
+++ b/packages/api/src/types/Questions.ts
@@ -1,4 +1,4 @@
-export type GetForumQuestionStatisticsResponse = {
+export type GetQuestionStatisticsResponse = {
numProposals: number;
sumNumOfHearts: number;
numOfParticipants: number;
@@ -6,7 +6,7 @@ export type GetForumQuestionStatisticsResponse = {
optionStats: Record<
string,
{
- optionTitle: string;
+ title: string;
pluralityScore: string;
distinctUsers: string;
allocatedHearts: string;
@@ -25,4 +25,5 @@ export type Question = {
description: string | null;
cycleId: string;
title: string;
+ fields: unknown;
};
diff --git a/packages/api/src/types/RegistrationDataType.ts b/packages/api/src/types/RegistrationData.ts
similarity index 53%
rename from packages/api/src/types/RegistrationDataType.ts
rename to packages/api/src/types/RegistrationData.ts
index 83c7e198..033f17c7 100644
--- a/packages/api/src/types/RegistrationDataType.ts
+++ b/packages/api/src/types/RegistrationData.ts
@@ -1,4 +1,4 @@
-import { RegistrationStatus } from './RegistrationType';
+import { RegistrationStatus } from './Registrations';
export type GetRegistrationDataResponse = {
id: string;
@@ -13,33 +13,32 @@ export type PostRegistrationRequest = {
eventId: string;
groupId: string | null;
status: RegistrationStatus;
- registrationData: {
- registrationFieldId: string;
- value: string;
- }[];
+ data: Record<
+ string,
+ {
+ value: string | number | boolean | string[] | null;
+ type: 'TEXT' | 'TEXTAREA' | 'SELECT' | 'CHECKBOX' | 'MULTI_SELECT' | 'NUMBER';
+ fieldId: string;
+ }
+ >;
};
export type PutRegistrationRequest = {
eventId: string;
groupId: string | null;
status: RegistrationStatus;
- registrationData: {
- registrationFieldId: string;
- value: string;
- }[];
+ data: Record<
+ string,
+ {
+ value: string | number | boolean | string[] | null;
+ type: 'TEXT' | 'TEXTAREA' | 'SELECT' | 'CHECKBOX' | 'MULTI_SELECT' | 'NUMBER';
+ fieldId: string;
+ }
+ >;
};
export type PostRegistrationResponse = {
- registrationData:
- | {
- id: string;
- createdAt: string;
- updatedAt: string;
- registrationId: string;
- registrationFieldId: string;
- value: string;
- }[]
- | null;
+ data: unknown | null;
id: string;
createdAt: string;
updatedAt: string;
@@ -49,16 +48,7 @@ export type PostRegistrationResponse = {
};
export type PutRegistrationResponse = {
- registrationData:
- | {
- id: string;
- createdAt: string;
- updatedAt: string;
- registrationId: string;
- registrationFieldId: string;
- value: string;
- }[]
- | null;
+ registrationData: unknown | null;
id: string;
createdAt: string;
updatedAt: string;
diff --git a/packages/api/src/types/RegistrationFieldOptionType.ts b/packages/api/src/types/RegistrationFieldOptions.ts
similarity index 100%
rename from packages/api/src/types/RegistrationFieldOptionType.ts
rename to packages/api/src/types/RegistrationFieldOptions.ts
diff --git a/packages/api/src/types/RegistrationFieldType.ts b/packages/api/src/types/RegistrationFields.ts
similarity index 98%
rename from packages/api/src/types/RegistrationFieldType.ts
rename to packages/api/src/types/RegistrationFields.ts
index 506308cb..1a707107 100644
--- a/packages/api/src/types/RegistrationFieldType.ts
+++ b/packages/api/src/types/RegistrationFields.ts
@@ -1,4 +1,4 @@
-import { RegistrationFieldOption } from './RegistrationFieldOptionType';
+import { RegistrationFieldOption } from './RegistrationFieldOptions';
export type GetRegistrationFieldsResponse = {
id: string;
diff --git a/packages/api/src/types/RegistrationType.ts b/packages/api/src/types/RegistrationType.ts
deleted file mode 100644
index da9e0855..00000000
--- a/packages/api/src/types/RegistrationType.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-export type RegistrationStatus = 'DRAFT' | 'APPROVED' | 'PUBLISHED' | null;
-
-export type GetRegistrationResponseType = {
- id?: string | undefined;
- status: RegistrationStatus;
- userId: string;
- groupId: string | null;
- eventId?: string | undefined;
- createdAt: string;
- updatedAt: string;
-};
-
-export type GetRegistrationsResponseType = GetRegistrationResponseType[];
diff --git a/packages/api/src/types/Registrations.ts b/packages/api/src/types/Registrations.ts
new file mode 100644
index 00000000..c3495ba6
--- /dev/null
+++ b/packages/api/src/types/Registrations.ts
@@ -0,0 +1,24 @@
+export type RegistrationStatus = 'DRAFT' | 'APPROVED' | 'REJECTED' | null;
+
+export type GetRegistrationResponseType = {
+ id?: string | undefined;
+ status: RegistrationStatus;
+ userId: string;
+ groupId: string | null;
+ eventId?: string | undefined;
+ createdAt: string;
+ data: unknown;
+ updatedAt: string;
+ event?: {
+ id: string;
+ name: string;
+ imageUrl: string;
+ link: string | null;
+ registrationDescription: string | null;
+ createdAt: string;
+ updatedAt: string;
+ description: string | null;
+ };
+};
+
+export type GetRegistrationsResponseType = GetRegistrationResponseType[];
diff --git a/packages/api/src/types/UserAttributesType.ts b/packages/api/src/types/UserAttributes.ts
similarity index 100%
rename from packages/api/src/types/UserAttributesType.ts
rename to packages/api/src/types/UserAttributes.ts
diff --git a/packages/api/src/types/UserOptions.ts b/packages/api/src/types/UserOptions.ts
new file mode 100644
index 00000000..6208f635
--- /dev/null
+++ b/packages/api/src/types/UserOptions.ts
@@ -0,0 +1,21 @@
+export type GetUserOptionsResponse = {
+ id: string;
+ createdAt: Date;
+ updatedAt: Date;
+ userId: string | null;
+ registrationId: string | null;
+ questionId: string;
+ optionTitle: string;
+ optionSubTitle: string | null;
+ accepted: boolean | null;
+ voteScore: string;
+ fundingRequest: string | null;
+ question: {
+ id: string;
+ createdAt: string;
+ updatedAt: string;
+ description: string | null;
+ cycleId: string;
+ title: string;
+ };
+}[];
diff --git a/packages/api/src/types/UserVotesType.ts b/packages/api/src/types/UserVotes.ts
similarity index 100%
rename from packages/api/src/types/UserVotesType.ts
rename to packages/api/src/types/UserVotes.ts
diff --git a/packages/api/src/types/UserType.ts b/packages/api/src/types/Users.ts
similarity index 100%
rename from packages/api/src/types/UserType.ts
rename to packages/api/src/types/Users.ts
diff --git a/packages/api/src/types/UsersToGroupsType.ts b/packages/api/src/types/UsersToGroups.ts
similarity index 100%
rename from packages/api/src/types/UsersToGroupsType.ts
rename to packages/api/src/types/UsersToGroups.ts
diff --git a/packages/api/src/types/index.ts b/packages/api/src/types/index.ts
index 7f94de9e..b0aab253 100644
--- a/packages/api/src/types/index.ts
+++ b/packages/api/src/types/index.ts
@@ -1,21 +1,22 @@
-export * from './AlertType';
-export * from './CommentType';
-export * from './CycleType';
-export * from './EventType';
-export * from './ForumQuestionType';
-export * from './FundingType';
-export * from './GroupCategoryType';
-export * from './GroupMembersType';
-export * from './GroupRegistrationsType';
-export * from './GroupType';
-export * from './LikeType';
-export * from './OptionUsersType';
-export * from './QuestionOptionType';
-export * from './RegistrationDataType';
-export * from './RegistrationFieldOptionType';
-export * from './RegistrationFieldType';
-export * from './RegistrationType';
-export * from './UserAttributesType';
-export * from './UsersToGroupsType';
-export * from './UserType';
-export * from './UserVotesType';
+export * from './Alerts';
+export * from './Comments';
+export * from './Cycles';
+export * from './Events';
+export * from './Questions';
+export * from './Funding';
+export * from './GroupCategories';
+export * from './GroupMembers';
+export * from './GroupRegistrations';
+export * from './Groups';
+export * from './Likes';
+export * from './OptionUsers';
+export * from './Options';
+export * from './RegistrationData';
+export * from './RegistrationFieldOptions';
+export * from './RegistrationFields';
+export * from './Registrations';
+export * from './UserAttributes';
+export * from './UsersToGroups';
+export * from './Users';
+export * from './UserVotes';
+export * from './ApiRequest';
diff --git a/packages/berlin/package.json b/packages/berlin/package.json
index 57c77548..879af783 100644
--- a/packages/berlin/package.json
+++ b/packages/berlin/package.json
@@ -4,44 +4,63 @@
"type": "module",
"main": "./src/main.ts",
"scripts": {
- "dev": "vite",
- "build": "vite build",
+ "dev": "pnpm exec vite",
+ "build": "pnpm exec vite build",
"lint": "pnpm exec eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
- "format": "pnpm exec prettier --check \"src/**/*.{ts,md}\"",
- "format:fix": "pnpm exec prettier --write \"src/**/*.{ts,md}\"",
- "preview": "vite preview"
+ "format": "pnpm exec prettier . --write",
+ "preview": "pnpm exec vite preview"
},
"dependencies": {
+ "@hookform/resolvers": "^3.3.4",
+ "@pcd/passport-interface": "^0.8.0",
+ "@pcd/semaphore-identity-pcd": "^0.8.0",
+ "@pcd/semaphore-signature-pcd": "^0.9.0",
"@radix-ui/react-dialog": "^1.0.5",
+ "@radix-ui/react-dropdown-menu": "^2.1.1",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-navigation-menu": "^1.2.0",
"@radix-ui/react-popover": "^1.0.7",
"@radix-ui/react-separator": "^1.1.0",
"@radix-ui/react-slot": "^1.0.2",
+ "@tanstack/react-query": "^5.13.4",
"api": "workspace:*",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"cmdk": "^1.0.0",
"lucide-react": "^0.397.0",
+ "react": "^18.2.0",
+ "react-content-loader": "^7.0.0",
+ "react-dom": "^18.2.0",
+ "react-hook-form": "^7.49.3",
+ "react-hot-toast": "^2.4.1",
+ "react-joyride": "^2.8.2",
+ "react-markdown": "^9.0.1",
+ "react-router-dom": "^6.20.1",
+ "styled-components": "^6.1.1",
"tailwind-merge": "^2.2.2",
"tailwindcss-animate": "^1.0.7",
- "ui": "workspace:*"
+ "ui": "workspace:*",
+ "zod": "^3.22.4",
+ "zustand": "^4.4.7"
},
"devDependencies": {
+ "@hookform/devtools": "^4.3.1",
+ "@pcd/pcd-types": "^0.8.0",
+ "@tanstack/react-query-devtools": "^5.13.5",
"@types/node": "^20.12.4",
- "@types/react-dom": "^18.2.22",
"@types/react": "^18.3.3",
+ "@types/react-dom": "^18.2.22",
"@typescript-eslint/eslint-plugin": "^7.2.0",
- "@typescript-eslint/parser": "^7.2.0",
"@vitejs/plugin-react": "^4.2.1",
"autoprefixer": "^10.4.19",
- "eslint-plugin-react-hooks": "^4.6.0",
- "eslint-plugin-react-refresh": "^0.4.6",
- "eslint": "^8.57.0",
- "postcss-cli": "^11.0.0",
"postcss": "^8.4.38",
+ "postcss-cli": "^11.0.0",
"tailwindcss": "^3.4.3",
- "vite-plugin-dts": "^3.8.1",
- "vite": "^5.2.0"
+ "typescript": "^5.5.2",
+ "vite": "^5.3.5",
+ "vite-plugin-node-polyfills": "^0.17.0"
+ },
+ "engines": {
+ "node": "^20"
}
}
diff --git a/packages/berlin/src/App.tsx b/packages/berlin/src/App.tsx
index b517473d..29a6e2da 100644
--- a/packages/berlin/src/App.tsx
+++ b/packages/berlin/src/App.tsx
@@ -1,9 +1,6 @@
// React and third-party libraries
-import { QueryClient } from '@tanstack/react-query';
-import { RouterProvider, createBrowserRouter, redirect } from 'react-router-dom';
-
-// Store
-import { useAppStore } from './store';
+import { CancelledError, QueryClient } from '@tanstack/react-query';
+import { RouterProvider, createBrowserRouter, redirect, useRouteError } from 'react-router-dom';
// API
import { fetchCycle, fetchEvents, fetchRegistrations, fetchUser } from 'api';
@@ -28,90 +25,103 @@ import SecretGroupRegistration from './pages/SecretGroupRegistration.tsx';
* Redirects the user to the landing page if they are not logged in
*/
async function redirectToLandingLoader(queryClient: QueryClient) {
- const user = await queryClient.fetchQuery({
- queryKey: ['user'],
- queryFn: fetchUser,
- staleTime: 10000,
- });
-
- if (!user) {
- return redirect('/');
- }
- return null;
-}
+ try {
+ const user = await queryClient.fetchQuery({
+ queryKey: ['user'],
+ queryFn: () => fetchUser({ serverUrl: import.meta.env.VITE_SERVER_URL }),
+ staleTime: 10000,
+ });
-/**
- * Redirects the user to the account page if they have not completed their profile
- */
-async function redirectToAccount(queryClient: QueryClient) {
- const user = await queryClient.fetchQuery({
- queryKey: ['user'],
- queryFn: fetchUser,
- });
-
- if (user?.username) {
- useAppStore.setState({ userStatus: 'COMPLETE' });
+ if (!user) {
+ return redirect('/');
+ }
return null;
- }
+ } catch (e) {
+ if (e instanceof CancelledError) {
+ console.log('Tanstack cancelled error:', e);
+ }
- useAppStore.setState({ userStatus: 'INCOMPLETE' });
- return redirect('/account');
+ return redirect('/');
+ }
}
/**
- * Redirects the user to the landing page to cycles or account page
+ * Redirects the user after successful login
*/
-async function redirectOnLandingLoader(queryClient: QueryClient) {
- const user = await queryClient.fetchQuery({
- queryKey: ['user'],
- queryFn: fetchUser,
- });
-
- if (!user) {
- return null;
- }
-
- const events = await queryClient.fetchQuery({
- queryKey: ['events'],
- queryFn: fetchEvents,
- });
+async function redirectAfterLogin(queryClient: QueryClient) {
+ try {
+ const user = await queryClient.fetchQuery({
+ queryKey: ['user'],
+ queryFn: () => fetchUser({ serverUrl: import.meta.env.VITE_SERVER_URL }),
+ });
- const userIsComplete = await redirectToAccount(queryClient);
+ if (!user) {
+ return null;
+ }
- if (userIsComplete) {
- return userIsComplete;
- }
+ if (!user.username) {
+ return redirect('/account');
+ }
- if (events?.length === 1) {
- const registrations = await queryClient.fetchQuery({
- queryKey: ['event', events?.[0].id, 'registrations'],
- queryFn: () => fetchRegistrations(events?.[0].id || ''),
+ const events = await queryClient.fetchQuery({
+ queryKey: ['events'],
+ queryFn: () => fetchEvents({ serverUrl: import.meta.env.VITE_SERVER_URL }),
});
- if (registrations && registrations.some((registration) => registration.status === 'APPROVED')) {
- return redirect(`/events/${events?.[0].id}/register`);
+ // if there is only one event, redirect to the cycles page
+ if (events?.length === 1) {
+ const registrations = await queryClient.fetchQuery({
+ queryKey: ['event', events?.[0].id, 'registrations'],
+ queryFn: () =>
+ fetchRegistrations({
+ eventId: events?.[0].id || '',
+ serverUrl: import.meta.env.VITE_SERVER_URL,
+ }),
+ });
+
+ if (
+ registrations &&
+ registrations.every((registration) => registration.status !== 'APPROVED')
+ ) {
+ return redirect(`/events/${events?.[0].id}/register`);
+ }
+
+ return redirect(`/events/${events?.[0].id}/cycles`);
}
- return redirect(`/events/${events?.[0].id}/cycles`);
- }
+ // if there are multiple events, redirect to the events page
+ return redirect('/events');
+ } catch (e) {
+ if (e instanceof CancelledError) {
+ console.log('Tanstack cancelled error:', e);
+ }
- return null;
+ return null;
+ }
}
/**
* Redirects the user to the only event if there is only one event
*/
async function redirectToOnlyOneEventLoader(queryClient: QueryClient) {
- const events = await queryClient.fetchQuery({
- queryKey: ['events'],
- queryFn: fetchEvents,
- });
+ try {
+ const events = await queryClient.fetchQuery({
+ queryKey: ['events'],
+ queryFn: () => fetchEvents({ serverUrl: import.meta.env.VITE_SERVER_URL }),
+ });
- if (events?.length === 1) {
- return redirect(`/events/${events?.[0].id}/cycles`);
- }
+ if (events?.length === 1) {
+ return redirect(`/events/${events?.[0].id}/cycles`);
+ }
+
+ return null;
+ } catch (e) {
+ if (e instanceof CancelledError) {
+ console.log('Tanstack cancelled error:', e);
+ }
- return null;
+ return redirect('/');
+ }
}
/**
@@ -119,20 +129,28 @@ async function redirectToOnlyOneEventLoader(queryClient: QueryClient) {
* Redirects the user to the holding page if they don't have any approved registrations
*/
async function redirectToEventHoldingOrRegister(queryClient: QueryClient, eventId?: string) {
- const registrations = await queryClient.fetchQuery({
- queryKey: ['event', eventId, 'registrations'],
- queryFn: () => fetchRegistrations(eventId || ''),
- });
+ try {
+ const registrations = await queryClient.fetchQuery({
+ queryKey: ['event', eventId, 'registrations'],
+ queryFn: () =>
+ fetchRegistrations({ eventId: eventId || '', serverUrl: import.meta.env.VITE_SERVER_URL }),
+ });
- if (!registrations || !registrations.length) {
- return redirect(`/events/${eventId}/register`);
- }
+ if (!registrations || !registrations.length) {
+ return redirect(`/events/${eventId}/register`);
+ }
- if (!registrations.some((registration) => registration.status === 'APPROVED')) {
- return redirect(`/events/${eventId}/holding`);
- }
+ if (!registrations.some((registration) => registration.status === 'APPROVED')) {
+ return redirect(`/events/${eventId}/holding`);
+ }
- return null;
+ return null;
+ } catch (e) {
+ if (e instanceof CancelledError) {
+ console.log('Tanstack cancelled error:', e);
+ }
+ return redirect('/');
+ }
}
/**
@@ -143,32 +161,48 @@ async function redirectToCycleResultsLoader(
eventId?: string,
cycleId?: string,
) {
- const cycle = await queryClient.fetchQuery({
- queryKey: ['cycles', cycleId],
- queryFn: () => fetchCycle(cycleId || ''),
- });
+ try {
+ const cycle = await queryClient.fetchQuery({
+ queryKey: ['cycles', cycleId],
+ queryFn: () =>
+ fetchCycle({ cycleId: cycleId || '', serverUrl: import.meta.env.VITE_SERVER_URL }),
+ });
- if (cycle?.status === 'CLOSED') {
- return redirect(`/events/${eventId}/cycles/${cycleId}/results`);
- }
+ if (cycle?.status === 'CLOSED') {
+ return redirect(`/events/${eventId}/cycles/${cycleId}/results`);
+ }
- return null;
+ return null;
+ } catch (e) {
+ if (e instanceof CancelledError) {
+ console.log('Tanstack cancelled error:', e);
+ }
+ return redirect('/');
+ }
}
/**
* Redirects the user to the cycle page if the cycle is open
*/
async function redirectToCycleIfOpen(queryClient: QueryClient, eventId?: string, cycleId?: string) {
- const cycle = await queryClient.fetchQuery({
- queryKey: ['cycles', cycleId],
- queryFn: () => fetchCycle(cycleId || ''),
- });
+ try {
+ const cycle = await queryClient.fetchQuery({
+ queryKey: ['cycles', cycleId],
+ queryFn: () =>
+ fetchCycle({ cycleId: cycleId || '', serverUrl: import.meta.env.VITE_SERVER_URL }),
+ });
- if (cycle?.status === 'OPEN') {
- return redirect(`/events/${eventId}/cycles/${cycleId}`);
- }
+ if (cycle?.status === 'OPEN') {
+ return redirect(`/events/${eventId}/cycles/${cycleId}`);
+ }
- return null;
+ return null;
+ } catch (e) {
+ if (e instanceof CancelledError) {
+ console.log('Tanstack cancelled error:', e);
+ }
+ return redirect('/');
+ }
}
const router = (queryClient: QueryClient) =>
@@ -179,10 +213,11 @@ const router = (queryClient: QueryClient) =>
},
{
element: ,
+ errorElement: ,
children: [
{
path: '/',
- loader: () => redirectOnLandingLoader(queryClient),
+ loader: () => redirectAfterLogin(queryClient),
element: ,
},
{
@@ -205,7 +240,6 @@ const router = (queryClient: QueryClient) =>
Component: PublicGroupRegistration,
},
{
- loader: () => redirectToAccount(queryClient),
path: '/events',
children: [
{
@@ -256,6 +290,13 @@ const router = (queryClient: QueryClient) =>
},
]);
+function ErrorBoundary() {
+ const error = useRouteError();
+ console.log('@ErrorBoundary error', error);
+ // Uncaught ReferenceError: path is not defined
+ return Dang!
;
+}
+
function App({ queryClient }: { queryClient: QueryClient }) {
return ;
}
diff --git a/packages/berlin/src/_components/ui/command.tsx b/packages/berlin/src/_components/ui/command.tsx
index 265ce7c6..f19ed548 100644
--- a/packages/berlin/src/_components/ui/command.tsx
+++ b/packages/berlin/src/_components/ui/command.tsx
@@ -15,7 +15,7 @@ const Command = React.forwardRef<
{
return (
+ Research Output: {researchOutputValue}
+
+ Lead Author: {optionUsers?.user?.firstName} {optionUsers?.user?.lastName}
+
+ Collaborators:{' '}
+ {collaborators && collaborators.length > 0 ? collaborators.join(', ') : 'None'}
+
Distinct voters: {option.distinctUsers}
Voter affiliations: {option.listOfGroupNames.join(', ')}