diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 64e2ea9b81..b85bbfa094 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -15,6 +15,7 @@ "customizations": { "vscode": { "extensions": [ + "apollographql.vscode-apollo", "bradlc.vscode-tailwindcss", "bruno-api-client.bruno", "csstools.postcss", diff --git a/.github/actions/setup-pnpm/action.yml b/.github/actions/setup-pnpm/action.yml index 016db93faa..2c23ed2758 100644 --- a/.github/actions/setup-pnpm/action.yml +++ b/.github/actions/setup-pnpm/action.yml @@ -10,7 +10,7 @@ inputs: runs: using: 'composite' steps: - - uses: pnpm/action-setup@v2 + - uses: pnpm/action-setup@v3 with: version: latest - uses: actions/setup-node@v4 diff --git a/.gitpod.yml b/.gitpod.yml index 9a7771856b..8eda1381be 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -37,6 +37,7 @@ github: vscode: extensions: + - apollographql.vscode-apollo - bradlc.vscode-tailwindcss - bruno-api-client.bruno - csstools.postcss diff --git a/.prettierignore b/.prettierignore index f72ea2e35e..3aba1a4e6f 100644 --- a/.prettierignore +++ b/.prettierignore @@ -4,6 +4,7 @@ node_modules/ pnpm-lock.yaml .pnpm-store/ @generated/ +__generated__/ schema.gql collection/ .next/ diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 082bc94c02..e93441c845 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,3 +1,11 @@ { - "recommendations": ["ms-vscode-remote.remote-containers"] + // Recommendations for Frontend team, developing without devcontainer + "recommendations": [ + "apollographql.vscode-apollo", + "dbaeumer.vscode-eslint", + "donjayamanne.githistory", + "eamodio.gitlens", + "EditorConfig.EditorConfig", + "esbenp.prettier-vscode" + ] } diff --git a/apollo.config.js b/apollo.config.js new file mode 100644 index 0000000000..6b67e7fb18 --- /dev/null +++ b/apollo.config.js @@ -0,0 +1,10 @@ +module.exports = { + client: { + includes: ['./frontend-client/**/*.ts', './frontend-client/**/*.tsx'], + excludes: ['**/__generated__/**'], + service: { + name: 'codedang-graphql-app', + url: 'https://dev.codedang.com/graphql' + } + } +} diff --git a/frontend-client/.eslintrc.js b/frontend-client/.eslintrc.js index 3ec55e95bc..ca3136496b 100644 --- a/frontend-client/.eslintrc.js +++ b/frontend-client/.eslintrc.js @@ -22,7 +22,23 @@ module.exports = { namedComponents: 'function-declaration' } ], - 'func-style': ['off'] + 'func-style': ['off'], + 'no-restricted-imports': [ + 'error', + { + name: '@apollo/client', + importNames: ['gql'], + message: 'Please use @generated instead.' + }, + { + name: '@/__generated__', + message: 'Please use @generated instead.' + }, + { + name: '@/__generated__/graphql', + message: 'Please use @generated/graphql instead.' + } + ] } } ] diff --git a/frontend-client/.gitignore b/frontend-client/.gitignore index fd3dbb571a..16e26f00cf 100644 --- a/frontend-client/.gitignore +++ b/frontend-client/.gitignore @@ -34,3 +34,6 @@ yarn-error.log* # typescript *.tsbuildinfo next-env.d.ts + +# GraphQL Codegen +__generated__/ diff --git a/frontend-client/Dockerfile b/frontend-client/Dockerfile deleted file mode 100644 index 5733b0c351..0000000000 --- a/frontend-client/Dockerfile +++ /dev/null @@ -1,62 +0,0 @@ -# [NOTE] Build image from the root directory of this repository. -# ex) `docker build -f frontend-client/Dockerfile .` - -FROM node:20-alpine AS base - -# Install dependencies only when needed -FROM base AS deps -# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed. -RUN apk add --no-cache libc6-compat -WORKDIR /app - -# Install dependencies -COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./ -COPY frontend-client ./frontend-client -RUN corepack enable && pnpm --filter=frontend-client deploy out - - -# Rebuild the source code only when needed -FROM base AS builder - -WORKDIR /app -COPY --from=deps /app/out . - -# Next.js collects completely anonymous telemetry data about general usage. -# Learn more here: https://nextjs.org/telemetry -# Uncomment the following line in case you want to disable telemetry during the build. -# ENV NEXT_TELEMETRY_DISABLED 1 - -RUN npm run build - - -# Production image, copy all the files and run next -FROM base AS runner -WORKDIR /app - -ENV NODE_ENV production -# Uncomment the following line in case you want to disable telemetry during runtime. -# ENV NEXT_TELEMETRY_DISABLED 1 - -RUN addgroup --system --gid 1001 nodejs -RUN adduser --system --uid 1001 nextjs - -COPY --from=builder /app/public ./public - -# Set the correct permission for prerender cache -RUN mkdir .next -RUN chown nextjs:nodejs .next - -# Automatically leverage output traces to reduce image size -# https://nextjs.org/docs/advanced-features/output-file-tracing -COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ -COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static - -USER nextjs - -EXPOSE 5525 - -ENV PORT 5525 -# set hostname to localhost -ENV HOSTNAME "0.0.0.0" - -CMD ["node", "server.js"] diff --git a/frontend-client/Dockerfile.dockerignore b/frontend-client/Dockerfile.dockerignore deleted file mode 100644 index c18d4657c7..0000000000 --- a/frontend-client/Dockerfile.dockerignore +++ /dev/null @@ -1,7 +0,0 @@ -Dockerfile -Dockerfile.dockerignore -node_modules -npm-debug.log -README.md -.next -.git diff --git a/frontend-client/app/admin/_components/ApolloProvider.tsx b/frontend-client/app/admin/_components/ApolloProvider.tsx new file mode 100644 index 0000000000..86122a32d2 --- /dev/null +++ b/frontend-client/app/admin/_components/ApolloProvider.tsx @@ -0,0 +1,44 @@ +'use client' + +import { auth } from '@/lib/auth' +import { adminBaseUrl } from '@/lib/vars' +import { + ApolloClient, + ApolloLink, + ApolloProvider, + InMemoryCache, + createHttpLink +} from '@apollo/client' +import { setContext } from '@apollo/client/link/context' + +interface Props { + children: React.ReactNode +} + +export default function ClientApolloProvider({ children }: Props) { + const httpLink = createHttpLink({ + uri: adminBaseUrl + }) + const authLink = setContext(async (_, { headers }) => { + const session = await auth() + return { + headers: { + ...headers, + authorization: session?.token.accessToken + } + } + }) + const link = ApolloLink.from([authLink.concat(httpLink)]) + + const client = new ApolloClient({ + cache: new InMemoryCache(), + link, + defaultContext: { + fetchOptions: { + next: { revalidate: 0 } + } + } + }) + + return {children} +} diff --git a/frontend-client/app/admin/layout.tsx b/frontend-client/app/admin/layout.tsx index 380a6bc47b..b7ee5df38b 100644 --- a/frontend-client/app/admin/layout.tsx +++ b/frontend-client/app/admin/layout.tsx @@ -3,33 +3,36 @@ import { Separator } from '@/components/ui/separator' import type { Route } from 'next' import Link from 'next/link' import { FaArrowRightFromBracket } from 'react-icons/fa6' +import ClientApolloProvider from './_components/ApolloProvider' // import GroupSelect from './_components/GroupSelect' import SideBar from './_components/SideBar' export default function Layout({ children }: { children: React.ReactNode }) { return ( -