diff --git a/.github/workflows/frontend_lib.yml b/.github/workflows/frontend_lib.yml new file mode 100644 index 000000000..75b35ba61 --- /dev/null +++ b/.github/workflows/frontend_lib.yml @@ -0,0 +1,76 @@ +name: Frontend Lib + +permissions: read-all + +on: + push: + paths: + - frontend/lib/** + - .github/workflows/frontend_lib.yml + pull_request: + types: opened + paths: + - frontend/lib/** + - .github/workflows/frontend_lib.yml + +jobs: + format: + name: Format + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: 18.x + cache: yarn + cache-dependency-path: frontend/lib/yarn.lock + - name: Install dependencies + run: | + cd frontend/lib + yarn install + - name: Format + run: | + cd frontend/lib + yarn format + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: 18.x + cache: yarn + cache-dependency-path: frontend/lib/yarn.lock + - name: Install dependencies + run: | + cd frontend/lib + yarn install + - name: Lint + run: | + cd frontend/lib + echo "Woah there, we have no we're not linting the lib as of right now. Let's just say we're passing." && exit 0 + test: + name: Test + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: 18.x + cache: yarn + cache-dependency-path: frontend/lib/yarn.lock + - name: Install dependencies + run: | + cd frontend/lib + yarn install + - name: Test + run: | + cd frontend/lib + yarn test diff --git a/.github/workflows/frontend_lib_codeql.yml b/.github/workflows/frontend_lib_codeql.yml new file mode 100644 index 000000000..1f2fc2395 --- /dev/null +++ b/.github/workflows/frontend_lib_codeql.yml @@ -0,0 +1,41 @@ +name: Frontend Lib CodeQL + +on: + push: + paths: + - "frontend/lib/**" + - ".github/workflows/frontend_lib_codeql.yml" + pull_request: + types: [opened] + paths: + - "frontend/lib/**" + - ".github/workflows/frontend_lib_codeql.yml" + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + security-events: write + strategy: + fail-fast: false + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: javascript-typescript + queries: security-and-quality + - name: Autobuild + uses: github/codeql-action/autobuild@v3 + with: + working-directory: frontend/lib + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: lib diff --git a/backend/go.mod b/backend/go.mod index 472747b60..b4bcec6de 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -4,7 +4,7 @@ go 1.22.2 require ( github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 - github.com/aws/aws-sdk-go v1.51.25 + github.com/aws/aws-sdk-go v1.51.30 github.com/garrettladley/mattress v0.4.0 github.com/go-playground/validator/v10 v10.19.0 github.com/goccy/go-json v0.10.2 diff --git a/backend/go.sum b/backend/go.sum index db6984ce0..a763bf4f1 100644 --- a/backend/go.sum +++ b/backend/go.sum @@ -12,8 +12,8 @@ github.com/awnumar/memcall v0.2.0 h1:sRaogqExTOOkkNwO9pzJsL8jrOV29UuUW7teRMfbqtI github.com/awnumar/memcall v0.2.0/go.mod h1:S911igBPR9CThzd/hYQQmTc9SWNu3ZHIlCGaWsWsoJo= github.com/awnumar/memguard v0.22.5 h1:PH7sbUVERS5DdXh3+mLo8FDcl1eIeVjJVYMnyuYpvuI= github.com/awnumar/memguard v0.22.5/go.mod h1:+APmZGThMBWjnMlKiSM1X7MVpbIVewen2MTkqWkA/zE= -github.com/aws/aws-sdk-go v1.51.25 h1:DjTT8mtmsachhV6yrXR8+yhnG6120dazr720nopRsls= -github.com/aws/aws-sdk-go v1.51.25/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go v1.51.30 h1:RVFkjn9P0JMwnuZCVH0TlV5k9zepHzlbc4943eZMhGw= +github.com/aws/aws-sdk-go v1.51.30/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= diff --git a/cli/commands/config.go b/cli/commands/config.go index 904fadbd9..8a94d521d 100644 --- a/cli/commands/config.go +++ b/cli/commands/config.go @@ -7,10 +7,26 @@ import ( ) var ( - ROOT_DIR, _ = utils.GetRootDir() - FRONTEND_DIR = filepath.Join(ROOT_DIR, "/frontend") - BACKEND_DIR = filepath.Join(ROOT_DIR, "/backend") - CONFIG = filepath.Join(ROOT_DIR, "/config") - MIGRATIONS = filepath.Join(BACKEND_DIR, "/migrations") - MOCK_FILE = filepath.Join(BACKEND_DIR, "/mock/data.sql") + ROOT_DIR, _ = utils.GetRootDir() + FRONTEND_DIR = filepath.Join(ROOT_DIR, "/frontend") + MOBILE_DIR = filepath.Join(FRONTEND_DIR, "/mobile") + DASHBOARD_DIR = filepath.Join(FRONTEND_DIR, "/dashboard") + LIB_DIR = filepath.Join(FRONTEND_DIR, "/lib") + WEB_DIR = filepath.Join(FRONTEND_DIR, "/web") + BACKEND_DIR = filepath.Join(ROOT_DIR, "/backend") + CONFIG = filepath.Join(ROOT_DIR, "/config") + MIGRATIONS = filepath.Join(BACKEND_DIR, "/migrations") + MOCK_FILE = filepath.Join(BACKEND_DIR, "/mock/data.sql") ) + +var ( + FRONTEND_RUN_TARGETS = []string{"web", "mobile", "dashboard"} + FRONTEND_CI_TARGETS = []string{"web", "mobile", "dashboard", "lib"} +) + +var TARGET_DIRS = map[string]string{ + "web": WEB_DIR, + "mobile": MOBILE_DIR, + "dashboard": DASHBOARD_DIR, + "lib": LIB_DIR, +} diff --git a/cli/commands/format.go b/cli/commands/format.go index be02f2b7c..abcd9673e 100644 --- a/cli/commands/format.go +++ b/cli/commands/format.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "os/exec" + "slices" "github.com/urfave/cli/v2" ) @@ -33,8 +34,8 @@ func FormatCommand() *cli.Command { } target := c.String("target") - if target != "web" && target != "mobile" { - return cli.Exit("Invalid frontend type: must be 'web' or 'mobile'", 1) + if !slices.Contains(FRONTEND_CI_TARGETS, target) { + return cli.Exit("Invalid frontend type: must be 'web', 'mobile', 'dashboard', or 'lib'", 1) } err := FormatFrontend(target) @@ -69,14 +70,24 @@ func FormatCommand() *cli.Command { } func FormatFrontend(target string) error { - switch target { - case "web": - return FormatWeb() - case "mobile": - return FormatMobile() - default: - return FormatMobile() + dir, ok := TARGET_DIRS[target] + if !ok { + return cli.Exit("Invalid frontend type", 1) } + + cmd := exec.Command("yarn", "run", "format") + + cmd.Dir = dir + + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + cmd.Stdin = os.Stdin + + if err := cmd.Run(); err != nil { + return err + } + + return nil } func FormatBackend() error { @@ -93,22 +104,3 @@ func FormatBackend() error { fmt.Println("Backend formatted") return nil } - -func FormatWeb() error { - return nil -} - -func FormatMobile() error { - mobileCmd := exec.Command("yarn", "run", "format") - mobileCmd.Dir = FRONTEND_DIR + "/mobile" - - mobileCmd.Stdout = os.Stdout - mobileCmd.Stderr = os.Stderr - mobileCmd.Stdin = os.Stdin - - if err := mobileCmd.Run(); err != nil { - return err - } - - return nil -} diff --git a/cli/commands/frontend.go b/cli/commands/frontend.go index 256ada89d..01c294b11 100644 --- a/cli/commands/frontend.go +++ b/cli/commands/frontend.go @@ -3,6 +3,7 @@ package commands import ( "os" "os/exec" + "slices" "github.com/urfave/cli/v2" ) @@ -31,9 +32,8 @@ func FrontendCommand() *cli.Command { return cli.Exit("Invalid arguments", 1) } - target := c.String("target") - if target != "web" && target != "mobile" { - return cli.Exit("Invalid frontend type: must be 'web' or 'mobile'", 1) + if !slices.Contains(FRONTEND_RUN_TARGETS, c.String("target")) { + return cli.Exit("Invalid frontend type: must be 'web', 'mobile', or 'dashboard'", 1) } err := RunFE(c.String("type"), c.String("platform")) @@ -54,6 +54,8 @@ func RunFE(feType string, platform string) error { return RunMobileFE(platform) case "web": return RunWebFE() + case "dashboard": + return RunDashboardFE() default: return RunMobileFE(platform) } @@ -61,7 +63,7 @@ func RunFE(feType string, platform string) error { func RunMobileFE(platform string) error { mobileCmd := exec.Command("yarn", "run", platform) - mobileCmd.Dir = FRONTEND_DIR + "/mobile" + mobileCmd.Dir = MOBILE_DIR mobileCmd.Stdout = os.Stdout mobileCmd.Stderr = os.Stderr @@ -75,5 +77,31 @@ func RunMobileFE(platform string) error { } func RunWebFE() error { + webCmd := exec.Command("yarn", "run") + webCmd.Dir = WEB_DIR + + webCmd.Stdout = os.Stdout + webCmd.Stderr = os.Stderr + webCmd.Stdin = os.Stdin + + if err := webCmd.Run(); err != nil { + return err + } + + return nil +} + +func RunDashboardFE() error { + dashboardCmd := exec.Command("yarn", "run") + dashboardCmd.Dir = DASHBOARD_DIR + + dashboardCmd.Stdout = os.Stdout + dashboardCmd.Stderr = os.Stderr + dashboardCmd.Stdin = os.Stdin + + if err := dashboardCmd.Run(); err != nil { + return err + } + return nil } diff --git a/cli/commands/lint.go b/cli/commands/lint.go index 7a797bde5..bb4dcc00e 100644 --- a/cli/commands/lint.go +++ b/cli/commands/lint.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "os/exec" + "slices" "github.com/urfave/cli/v2" ) @@ -38,13 +39,11 @@ func LintCommand() *cli.Command { } target := c.String("target") - if target != "web" && target != "mobile" { - return cli.Exit("Invalid frontend type: must be 'web' or 'mobile'", 1) + if !slices.Contains(FRONTEND_CI_TARGETS, target) { + return cli.Exit("Invalid frontend type: must be 'web', 'mobile', 'dashboard', or 'lib'", 1) } - fix := c.Bool("fix") - - err := LintFrontend(target, fix) + err := LintFrontend(target) if err != nil { return cli.Exit(err.Error(), 1) } @@ -75,15 +74,25 @@ func LintCommand() *cli.Command { return &command } -func LintFrontend(target string, fix bool) error { - switch target { - case "web": - return LintWeb(fix) - case "mobile": - return LintMobile(fix) - default: - return LintMobile(fix) +func LintFrontend(target string) error { + dir, ok := TARGET_DIRS[target] + if !ok { + return cli.Exit("Invalid frontend type", 1) } + + cmd := exec.Command("yarn", "run", "lint") + + cmd.Dir = dir + + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + cmd.Stdin = os.Stdin + + if err := cmd.Run(); err != nil { + return err + } + + return nil } func LintBackend() error { @@ -101,27 +110,3 @@ func LintBackend() error { return nil } - -func LintWeb(fix bool) error { - return nil -} - -func LintMobile(fix bool) error { - var mobileCmd *exec.Cmd - if fix { - mobileCmd = exec.Command("yarn", "run", "lint", "--fix") - } else { - mobileCmd = exec.Command("yarn", "run", "lint") - } - mobileCmd.Dir = FRONTEND_DIR + "/mobile" - - mobileCmd.Stdout = os.Stdout - mobileCmd.Stderr = os.Stderr - mobileCmd.Stdin = os.Stdin - - if err := mobileCmd.Run(); err != nil { - return err - } - - return nil -} diff --git a/frontend/dashboard/package.json b/frontend/dashboard/package.json index 48735789f..d85af44b3 100644 --- a/frontend/dashboard/package.json +++ b/frontend/dashboard/package.json @@ -7,13 +7,12 @@ "build": "next build", "start": "next start", "lint": "next lint", - "lint:fix": "eslint . --ext .js,.jsx,.ts,.tsx --fix", "format": "prettier --write .", "test": "echo \"Woah there, we have no frontend tests as of right now. Let's just say we're passing.\" && exit 0" }, "dependencies": { "@reduxjs/toolkit": "^2.2.3", - "next": "14.2.2", + "next": "14.2.3", "react": "^18", "react-dom": "^18", "react-redux": "^9.1.1", @@ -25,7 +24,7 @@ "@types/react-dom": "^18", "autoprefixer": "^10.4.19", "eslint": "^8", - "eslint-config-next": "14.2.2", + "eslint-config-next": "14.2.3", "postcss": "^8", "tailwindcss": "^3.4.1", "typescript": "^5", diff --git a/frontend/lib/.eslintrc.json b/frontend/lib/.eslintrc.json new file mode 100644 index 000000000..83df9d1d0 --- /dev/null +++ b/frontend/lib/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "plugins": ["prettier"] +} diff --git a/frontend/lib/api/category.ts b/frontend/lib/api/category.ts index 7057b77f9..86bfa592b 100644 --- a/frontend/lib/api/category.ts +++ b/frontend/lib/api/category.ts @@ -1,9 +1,9 @@ -import { z } from 'zod'; +import { z } from "zod"; -import { API_BASE_URL } from '@/const'; -import { Category, categorySchema } from '@/types/category'; -import { uuid } from '@/types/uuid'; -import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; +import { API_BASE_URL } from "@/const"; +import { Category, categorySchema } from "@/types/category"; +import { uuid } from "@/types/uuid"; +import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; export const categoriesApi = createApi({ reducerPath: "categoriesApi", @@ -28,7 +28,4 @@ export const categoriesApi = createApi({ }), }); -export const { - useCategoriesQuery, - useCategoryQuery, -} = categoriesApi; \ No newline at end of file +export const { useCategoriesQuery, useCategoryQuery } = categoriesApi; diff --git a/frontend/lib/api/club.ts b/frontend/lib/api/club.ts index 3e2ace508..f6368028d 100644 --- a/frontend/lib/api/club.ts +++ b/frontend/lib/api/club.ts @@ -1,9 +1,9 @@ -import { API_BASE_URL } from '@/const'; -import { Club } from '@/types/club'; -import { Contact } from '@/types/contact'; -import { Tag } from '@/types/tag'; -import { uuid } from '@/types/uuid'; -import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; +import { API_BASE_URL } from "@/const"; +import { Club } from "@/types/club"; +import { Contact } from "@/types/contact"; +import { Tag } from "@/types/tag"; +import { uuid } from "@/types/uuid"; +import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; export const clubsApi = createApi({ reducerPath: "clubsApi", @@ -41,7 +41,6 @@ export const clubsApi = createApi({ providesTags: (result, _, clubID) => result ? [{ type: "Clubs", id: clubID }] : [], }), - }), }); @@ -49,5 +48,5 @@ export const { useClubsQuery, useClubQuery, useClubContactsQuery, - useClubTagsQuery -} = clubsApi; \ No newline at end of file + useClubTagsQuery, +} = clubsApi; diff --git a/frontend/lib/api/contact.ts b/frontend/lib/api/contact.ts index a2f95b8d2..9db031cd7 100644 --- a/frontend/lib/api/contact.ts +++ b/frontend/lib/api/contact.ts @@ -1,9 +1,9 @@ -import { z } from 'zod'; +import { z } from "zod"; -import { API_BASE_URL } from '@/const'; -import { Contact, contactSchema } from '@/types/contact'; -import { uuid } from '@/types/uuid'; -import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; +import { API_BASE_URL } from "@/const"; +import { Contact, contactSchema } from "@/types/contact"; +import { uuid } from "@/types/uuid"; +import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; export const contactsApi = createApi({ reducerPath: "contactApi", diff --git a/frontend/lib/api/event.ts b/frontend/lib/api/event.ts index 547ba1264..7105cce15 100644 --- a/frontend/lib/api/event.ts +++ b/frontend/lib/api/event.ts @@ -1,8 +1,8 @@ -import { API_BASE_URL } from '@/const'; -import { Club } from '@/types/club'; -import { Event } from '@/types/event'; -import { uuid } from '@/types/uuid'; -import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; +import { API_BASE_URL } from "@/const"; +import { Club } from "@/types/club"; +import { Event } from "@/types/event"; +import { uuid } from "@/types/uuid"; +import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; export const eventsApi = createApi({ reducerPath: "eventsApi", @@ -48,4 +48,4 @@ export const { useEventQuery, useEventTagsQuery, useEventHostsQuery, -} = eventsApi; \ No newline at end of file +} = eventsApi; diff --git a/frontend/lib/api/index.ts b/frontend/lib/api/index.ts index 5131285ec..e6b1183be 100644 --- a/frontend/lib/api/index.ts +++ b/frontend/lib/api/index.ts @@ -1,6 +1,6 @@ -export * from './tag' -export * from './user' -export * from './event' -export * from './contact' -export * from './club' -export * from './category' \ No newline at end of file +export * from "./tag"; +export * from "./user"; +export * from "./event"; +export * from "./contact"; +export * from "./club"; +export * from "./category"; diff --git a/frontend/lib/api/tag.ts b/frontend/lib/api/tag.ts index 7a23066cb..e6da1c3b5 100644 --- a/frontend/lib/api/tag.ts +++ b/frontend/lib/api/tag.ts @@ -1,31 +1,31 @@ -import { z } from 'zod'; +import { z } from "zod"; -import { API_BASE_URL } from '@/const'; -import { Tag, tagSchema } from '@/types/tag'; -import { uuid } from '@/types/uuid'; -import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; +import { API_BASE_URL } from "@/const"; +import { Tag, tagSchema } from "@/types/tag"; +import { uuid } from "@/types/uuid"; +import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; export const tagsApi = createApi({ - reducerPath: "tagsApi", - baseQuery: fetchBaseQuery({ baseUrl: API_BASE_URL }), - tagTypes: ["Tags"], - endpoints: (builder) => ({ - tags: builder.query({ - query: () => "tags", - transformResponse: (rawResponse: unknown) => { - return z.array(tagSchema).parse(rawResponse); - }, - providesTags: [{ type: "Tags", id: "LIST" }], - }), - tag: builder.query({ - query: (tagID: uuid) => `tags/${tagID}`, - transformResponse: (rawResponse: unknown) => { - return tagSchema.parse(rawResponse); - }, - providesTags: (result, _, tagID) => - result ? [{ type: "Tags", id: tagID }] : [], - }), + reducerPath: "tagsApi", + baseQuery: fetchBaseQuery({ baseUrl: API_BASE_URL }), + tagTypes: ["Tags"], + endpoints: (builder) => ({ + tags: builder.query({ + query: () => "tags", + transformResponse: (rawResponse: unknown) => { + return z.array(tagSchema).parse(rawResponse); + }, + providesTags: [{ type: "Tags", id: "LIST" }], }), + tag: builder.query({ + query: (tagID: uuid) => `tags/${tagID}`, + transformResponse: (rawResponse: unknown) => { + return tagSchema.parse(rawResponse); + }, + providesTags: (result, _, tagID) => + result ? [{ type: "Tags", id: tagID }] : [], + }), + }), }); -export const { useTagsQuery, useTagQuery } = tagsApi; \ No newline at end of file +export const { useTagsQuery, useTagQuery } = tagsApi; diff --git a/frontend/lib/api/user.ts b/frontend/lib/api/user.ts index b9d3a565c..bf7ead91e 100644 --- a/frontend/lib/api/user.ts +++ b/frontend/lib/api/user.ts @@ -1,22 +1,22 @@ -import { z } from 'zod'; +import { z } from "zod"; -import { API_BASE_URL } from '@/const'; -import { Club, clubSchema } from '@/types/club'; -import { User, userSchema } from '@/types/user'; -import { uuid } from '@/types/uuid'; -import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; +import { API_BASE_URL } from "@/const"; +import { Club, clubSchema } from "@/types/club"; +import { User, userSchema } from "@/types/user"; +import { uuid } from "@/types/uuid"; +import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; export const usersApi = createApi({ reducerPath: "usersApi", baseQuery: fetchBaseQuery({ baseUrl: API_BASE_URL }), - tagTypes: ['Users'], + tagTypes: ["Users"], endpoints: (builder) => ({ users: builder.query({ query: () => "users", transformResponse: (rawResponse: unknown) => { return z.array(userSchema).parse(rawResponse); }, - providesTags: [{ type: 'Users', id: 'LIST' }], + providesTags: [{ type: "Users", id: "LIST" }], }), user: builder.query({ query: (userID: uuid) => `users/${userID}`, @@ -24,7 +24,7 @@ export const usersApi = createApi({ return userSchema.parse(rawResponse); }, providesTags: (result, _, userID) => - result ? [{ type: 'Users', id: userID }] : [], + result ? [{ type: "Users", id: userID }] : [], }), userFollowing: builder.query({ query: (userID: uuid) => `users/${userID}/follower`, @@ -32,21 +32,27 @@ export const usersApi = createApi({ return z.array(clubSchema).parse(rawResponse); }, providesTags: (result, _, userID) => - result ? [{ type: 'Users', id: userID }] : [], + result ? [{ type: "Users", id: userID }] : [], }), - createUserClubFollowing: builder.mutation({ + createUserClubFollowing: builder.mutation< + void, + { userID: uuid; clubID: uuid } + >({ query: ({ userID, clubID }) => ({ url: `users/${userID}/follower/${clubID}`, - method: 'POST', + method: "POST", }), - invalidatesTags: ['Users'], + invalidatesTags: ["Users"], }), - deleteUserClubFollowing: builder.mutation({ + deleteUserClubFollowing: builder.mutation< + void, + { userID: uuid; clubID: uuid } + >({ query: ({ userID, clubID }) => ({ url: `users/${userID}/follower/${clubID}`, - method: 'DELETE', + method: "DELETE", }), - invalidatesTags: ['Users'], + invalidatesTags: ["Users"], }), }), }); @@ -56,5 +62,5 @@ export const { useUserQuery, useUserFollowingQuery, useCreateUserClubFollowingMutation, - useDeleteUserClubFollowingMutation -} = usersApi; \ No newline at end of file + useDeleteUserClubFollowingMutation, +} = usersApi; diff --git a/frontend/lib/index.ts b/frontend/lib/index.ts index 7e663cb35..c534e8d9d 100644 --- a/frontend/lib/index.ts +++ b/frontend/lib/index.ts @@ -1,5 +1,5 @@ -export * from './api'; -export * from './types'; +export * from "./api"; +export * from "./types"; -export * from './store'; -export * from './const' \ No newline at end of file +export * from "./store"; +export * from "./const"; diff --git a/frontend/lib/package.json b/frontend/lib/package.json index 637b8db3f..206ef576a 100644 --- a/frontend/lib/package.json +++ b/frontend/lib/package.json @@ -2,9 +2,18 @@ "name": "@sac/lib", "main": "index.ts", "version": "0.1.0", + "scripts": { + "test": "echo \"Woah there, we have no frontend tests as of right now. Let's just say we're passing.\" && exit 0", + "lint": "eslint . --ext .js,.jsx,.ts,.tsx --fix", + "format": "prettier --write ." + }, "private": true, "dependencies": { "@reduxjs/toolkit": "^2.2.3", "zod": "^3.22.4" + }, + "devDependencies": { + "eslint-plugin-prettier": "^5.1.3", + "prettier": "^3.2.4" } -} \ No newline at end of file +} diff --git a/frontend/lib/tsconfig.json b/frontend/lib/tsconfig.json index 7a814810d..fd9cd89d0 100644 --- a/frontend/lib/tsconfig.json +++ b/frontend/lib/tsconfig.json @@ -2,10 +2,7 @@ "compilerOptions": { "allowSyntheticDefaultImports": true, "jsx": "react", - "lib": [ - "dom", - "esnext" - ], + "lib": ["dom", "esnext"], "experimentalDecorators": true, "emitDecoratorMetadata": true, "moduleResolution": "node", @@ -17,17 +14,9 @@ "strict": true, "baseUrl": "./", "paths": { - "@/*": [ - "./*" - ] + "@/*": ["./*"] } }, - "exclude": [ - "node_modules" - ], - "include": [ - "**/*.ts", - "**/*.tsx", - "types/index.ts" - ] -} \ No newline at end of file + "exclude": ["node_modules"], + "include": ["**/*.ts", "**/*.tsx", "types/index.ts"] +} diff --git a/frontend/lib/types/auth.ts b/frontend/lib/types/auth.ts index 30635032e..bef872336 100644 --- a/frontend/lib/types/auth.ts +++ b/frontend/lib/types/auth.ts @@ -1,4 +1,4 @@ export type Tokens = { - accessToken: string; - refreshToken: string; + accessToken: string; + refreshToken: string; }; diff --git a/frontend/lib/types/club.ts b/frontend/lib/types/club.ts index a6375f4ed..26dc2641b 100644 --- a/frontend/lib/types/club.ts +++ b/frontend/lib/types/club.ts @@ -1,16 +1,16 @@ import { z } from "zod"; -import { rootModelSchema } from '@/types/root'; +import { rootModelSchema } from "@/types/root"; const clubSchemaIntermediate = z.object({ - name: z.string().max(255), - preview: z.string().max(255), - description: z.string().max(255), - num_members: z.number(), - is_recruiting: z.boolean(), - recruitment_cycle: z.enum(["fall", "spring", "fallSpring", "always"]), - recruitment_type: z.enum(["unrestricted", "tryout", "application"]), - application_link: z.string().max(255), - logo: z.string().max(255).optional(), + name: z.string().max(255), + preview: z.string().max(255), + description: z.string().max(255), + num_members: z.number(), + is_recruiting: z.boolean(), + recruitment_cycle: z.enum(["fall", "spring", "fallSpring", "always"]), + recruitment_type: z.enum(["unrestricted", "tryout", "application"]), + application_link: z.string().max(255), + logo: z.string().max(255).optional(), }); export const clubSchema = clubSchemaIntermediate.merge(rootModelSchema); diff --git a/frontend/lib/types/error.ts b/frontend/lib/types/error.ts index aa50e46ac..6bfb33c7d 100644 --- a/frontend/lib/types/error.ts +++ b/frontend/lib/types/error.ts @@ -1,3 +1,3 @@ export type ErrorResponse = { - error: string; + error: string; }; diff --git a/frontend/lib/types/event.ts b/frontend/lib/types/event.ts index 5a0e5076b..36efdb144 100644 --- a/frontend/lib/types/event.ts +++ b/frontend/lib/types/event.ts @@ -1,18 +1,18 @@ -import { z } from 'zod'; +import { z } from "zod"; -import { rootModelSchema } from './root'; +import { rootModelSchema } from "./root"; const eventSchemaIntermediate = z.object({ - name: z.string().max(255), - preview: z.string().max(255), - content: z.string().max(255), - start_time: z.date(), - end_time: z.date(), - location: z.string().max(255), - meeting_link: z.string().max(255).optional(), - event_type: z.enum(['open', 'membersOnly']), - is_recurring: z.boolean(), - host: z.string().max(255) + name: z.string().max(255), + preview: z.string().max(255), + content: z.string().max(255), + start_time: z.date(), + end_time: z.date(), + location: z.string().max(255), + meeting_link: z.string().max(255).optional(), + event_type: z.enum(["open", "membersOnly"]), + is_recurring: z.boolean(), + host: z.string().max(255), }); export const eventSchema = eventSchemaIntermediate.merge(rootModelSchema); diff --git a/frontend/lib/types/index.ts b/frontend/lib/types/index.ts index 54c08756b..2091fd7b6 100644 --- a/frontend/lib/types/index.ts +++ b/frontend/lib/types/index.ts @@ -1,12 +1,12 @@ -export * from './auth' -export * from './item' -export * from './uuid' -export * from './error' +export * from "./auth"; +export * from "./item"; +export * from "./uuid"; +export * from "./error"; -export * from './root' -export * from './club' -export * from './contact' -export * from './user' -export * from './tag' -export * from './category' -export * from './event' \ No newline at end of file +export * from "./root"; +export * from "./club"; +export * from "./contact"; +export * from "./user"; +export * from "./tag"; +export * from "./category"; +export * from "./event"; diff --git a/frontend/lib/types/item.ts b/frontend/lib/types/item.ts index 763910602..8cef04537 100644 --- a/frontend/lib/types/item.ts +++ b/frontend/lib/types/item.ts @@ -1,4 +1,4 @@ export type Item = { - label: string; - value: string; + label: string; + value: string; }; diff --git a/frontend/lib/types/root.ts b/frontend/lib/types/root.ts index 4003c9d2b..9656df9db 100644 --- a/frontend/lib/types/root.ts +++ b/frontend/lib/types/root.ts @@ -1,7 +1,7 @@ -import { z } from 'zod'; +import { z } from "zod"; export const rootModelSchema = z.object({ - id: z.string().uuid(), - created_at: z.date(), - updated_at: z.date() + id: z.string().uuid(), + created_at: z.date(), + updated_at: z.date(), }); diff --git a/frontend/lib/types/tag.ts b/frontend/lib/types/tag.ts index 2cc6d46d2..f748cc11b 100644 --- a/frontend/lib/types/tag.ts +++ b/frontend/lib/types/tag.ts @@ -3,7 +3,7 @@ import { z } from "zod"; import { rootModelSchema } from "../types/root"; export const tagSchemaIntermediate = z.object({ - name: z.string().max(255), + name: z.string().max(255), }); export const tagSchema = tagSchemaIntermediate.merge(rootModelSchema); diff --git a/frontend/lib/types/user.ts b/frontend/lib/types/user.ts index 80eb3181a..aedf4fa97 100644 --- a/frontend/lib/types/user.ts +++ b/frontend/lib/types/user.ts @@ -2,26 +2,26 @@ import { z } from "zod"; import { rootModelSchema } from "./root"; export const userSchemaIntermediate = z.object({ - role: z.enum(["super", "student"]), - first_name: z.string().min(1), - last_name: z.string().min(1), - email: z.string().email(), - college: z.string().optional(), - graduation_cycle: z.string().optional(), - graduation_year: z.number().optional(), - is_verified: z.boolean(), + role: z.enum(["super", "student"]), + first_name: z.string().min(1), + last_name: z.string().min(1), + email: z.string().email(), + college: z.string().optional(), + graduation_cycle: z.string().optional(), + graduation_year: z.number().optional(), + is_verified: z.boolean(), }); export const collegeSchema = z.enum([ - "CAMD", - "DMSB", - "KCCS", - "CE", - "BCHS", - "SL", - "CPS", - "CS", - "CSSH", + "CAMD", + "DMSB", + "KCCS", + "CE", + "BCHS", + "SL", + "CPS", + "CS", + "CSSH", ]); export type College = z.infer; @@ -29,4 +29,4 @@ export const yearSchema = z.enum(["1", "2", "3", "4", "5"]); export type Year = z.infer; export const userSchema = userSchemaIntermediate.merge(rootModelSchema); -export type User = z.infer; \ No newline at end of file +export type User = z.infer; diff --git a/frontend/mobile/package.json b/frontend/mobile/package.json index e936e2822..8353a8ea5 100644 --- a/frontend/mobile/package.json +++ b/frontend/mobile/package.json @@ -8,7 +8,7 @@ "ios": "expo run:ios", "web": "expo start --web", "test": "echo \"Woah there, we have no frontend tests as of right now. Let's just say we're passing.\" && exit 0", - "lint": "eslint . --ext .js,.jsx,.ts,.tsx", + "lint": "eslint . --ext .js,.jsx,.ts,.tsx --fix", "format": "prettier --write ." }, "jest": {