diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index ac84634a..d34b105a 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,8 +1,10 @@ -## 작업 내용 +## 작업 요약 > 해당 PR에서 작업한 내용을 정리해주세요. > Slack 요약에는 1단계 불릿만 반영됩니다. 예) - 로그인 API를 연동합니다 +## 작업 세부 내용 + ## 스크린샷 ## 연관 이슈 diff --git a/.github/workflows/slack-pr-bot.yml b/.github/workflows/slack-pr-bot.yml index 5060da40..8f9b5773 100644 --- a/.github/workflows/slack-pr-bot.yml +++ b/.github/workflows/slack-pr-bot.yml @@ -427,7 +427,7 @@ jobs: if (in_task == 1) exit r = $0 sub(/^##[[:space:]]+/, "", r) - ok = (match(r, /^작업 내용([^A-Za-z]|$)/) || match(r, /[[:space:]]작업 내용([^A-Za-z]|$)/)) + ok = (match(r, /^작업 요약([^A-Za-z]|$)/) || match(r, /[[:space:]]작업 요약([^A-Za-z]|$)/)) if (ok) { in_task=1; next } next } diff --git a/README.md b/README.md index 6a4b7d1f..ec745e85 100644 --- a/README.md +++ b/README.md @@ -18,8 +18,6 @@ This Turborepo includes the following packages/apps: - `docs`: a [Next.js](https://nextjs.org/) app - `web`: another [Next.js](https://nextjs.org/) app -- `@repo/ui`: a stub React component library shared by both `web` and `docs` applications -- `@repo/eslint-config`: `eslint` configurations (includes `eslint-config-next` and `eslint-config-prettier`) - `@repo/typescript-config`: `tsconfig.json`s used throughout the monorepo Each package/app is 100% [TypeScript](https://www.typescriptlang.org/). diff --git a/apps/app/app/_layout.tsx b/apps/app/app/_layout.tsx index dfd531f6..27fb05f1 100644 --- a/apps/app/app/_layout.tsx +++ b/apps/app/app/_layout.tsx @@ -1,11 +1,11 @@ -import { Stack } from 'expo-router' -import { StatusBar } from 'expo-status-bar' -import 'react-native-reanimated' -import { SafeAreaView } from 'react-native-safe-area-context' +import { Stack } from 'expo-router'; +import { StatusBar } from 'expo-status-bar'; +import 'react-native-reanimated'; +import { SafeAreaView } from 'react-native-safe-area-context'; export const unstable_settings = { anchor: '(tabs)', -} +}; export default function RootLayout() { return ( @@ -13,5 +13,5 @@ export default function RootLayout() { - ) + ); } diff --git a/apps/app/app/index.tsx b/apps/app/app/index.tsx index 91e197f6..6f9c8e0c 100644 --- a/apps/app/app/index.tsx +++ b/apps/app/app/index.tsx @@ -1,5 +1,5 @@ -import { KeyboardAvoidingView, Platform } from 'react-native' -import Webview from 'react-native-webview' +import { KeyboardAvoidingView, Platform } from 'react-native'; +import Webview from 'react-native-webview'; export default function Page() { return ( @@ -22,5 +22,5 @@ export default function Page() { startInLoadingState /> - ) + ); } diff --git a/apps/app/app/modal.tsx b/apps/app/app/modal.tsx index 8bdb06f9..3031b6fe 100644 --- a/apps/app/app/modal.tsx +++ b/apps/app/app/modal.tsx @@ -1,5 +1,5 @@ -import { Link } from 'expo-router' -import { StyleSheet, Text, View } from 'react-native' +import { Link } from 'expo-router'; +import { StyleSheet, Text, View } from 'react-native'; export default function ModalScreen() { return ( @@ -9,7 +9,7 @@ export default function ModalScreen() { Go to home screen - ) + ); } const styles = StyleSheet.create({ @@ -23,4 +23,4 @@ const styles = StyleSheet.create({ marginTop: 15, paddingVertical: 15, }, -}) +}); diff --git a/apps/app/components/ExternalLink.tsx b/apps/app/components/ExternalLink.tsx index 883e515a..babffe75 100644 --- a/apps/app/components/ExternalLink.tsx +++ b/apps/app/components/ExternalLink.tsx @@ -1,5 +1,5 @@ -import { Href, Link } from 'expo-router'; -import { openBrowserAsync, WebBrowserPresentationStyle } from 'expo-web-browser'; +import { type Href, Link } from 'expo-router'; +import { WebBrowserPresentationStyle, openBrowserAsync } from 'expo-web-browser'; import { type ComponentProps } from 'react'; type Props = Omit, 'href'> & { href: Href & string }; @@ -10,7 +10,7 @@ export function ExternalLink({ href, ...rest }: Props) { target="_blank" {...rest} href={href} - onPress={async (event) => { + onPress={async event => { if (process.env.EXPO_OS !== 'web') { // Prevent the default behavior of linking to the default browser on native. event.preventDefault(); diff --git a/apps/app/components/HapticTab.tsx b/apps/app/components/HapticTab.tsx index 7f3981cb..71e1d852 100644 --- a/apps/app/components/HapticTab.tsx +++ b/apps/app/components/HapticTab.tsx @@ -1,4 +1,4 @@ -import { BottomTabBarButtonProps } from '@react-navigation/bottom-tabs'; +import type { BottomTabBarButtonProps } from '@react-navigation/bottom-tabs'; import { PlatformPressable } from '@react-navigation/elements'; import * as Haptics from 'expo-haptics'; @@ -6,7 +6,7 @@ export function HapticTab(props: BottomTabBarButtonProps) { return ( { + onPressIn={ev => { if (process.env.EXPO_OS === 'ios') { // Add a soft haptic feedback when pressing down on the tabs. Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); diff --git a/apps/app/eslint.config.js b/apps/app/eslint.config.js deleted file mode 100644 index 5025da68..00000000 --- a/apps/app/eslint.config.js +++ /dev/null @@ -1,10 +0,0 @@ -// https://docs.expo.dev/guides/using-eslint/ -const { defineConfig } = require('eslint/config'); -const expoConfig = require('eslint-config-expo/flat'); - -module.exports = defineConfig([ - expoConfig, - { - ignores: ['dist/*'], - }, -]); diff --git a/apps/app/eslint.config.mjs b/apps/app/eslint.config.mjs new file mode 100644 index 00000000..58c8e290 --- /dev/null +++ b/apps/app/eslint.config.mjs @@ -0,0 +1,12 @@ +import expoConfig from 'eslint-config-expo/flat.js'; +import { defineConfig } from 'eslint/config'; + +import baseConfig from '../../eslint.config.mjs'; + +export default defineConfig([ + ...baseConfig, + expoConfig, + { + ignores: ['dist/**'], + }, +]); diff --git a/apps/app/scripts/reset-project.js b/apps/app/scripts/reset-project.js index ab41483f..bec4b89f 100755 --- a/apps/app/scripts/reset-project.js +++ b/apps/app/scripts/reset-project.js @@ -6,15 +6,15 @@ * You can remove the `reset-project` script from package.json and safely delete this file after running it. */ -const fs = require('fs') -const path = require('path') -const readline = require('readline') +const fs = require('fs'); +const path = require('path'); +const readline = require('readline'); -const root = process.cwd() -const oldDirs = ['app', 'components', 'hooks', 'constants', 'scripts'] -const exampleDir = 'app-example' -const newAppDir = 'app' -const exampleDirPath = path.join(root, exampleDir) +const root = process.cwd(); +const oldDirs = ['app', 'components', 'hooks', 'constants', 'scripts']; +const exampleDir = 'app-example'; +const newAppDir = 'app'; +const exampleDirPath = path.join(root, exampleDir); const indexContent = `import { Text, View } from "react-native"; @@ -31,77 +31,82 @@ export default function Index() { ); } -` +`; const layoutContent = `import { Stack } from "expo-router"; export default function RootLayout() { return ; } -` +`; const rl = readline.createInterface({ input: process.stdin, output: process.stdout, -}) +}); -const moveDirectories = async (userInput) => { +const moveDirectories = async userInput => { try { if (userInput === 'y') { // Create the app-example directory - await fs.promises.mkdir(exampleDirPath, { recursive: true }) - console.log(`📁 /${exampleDir} directory created.`) + await fs.promises.mkdir(exampleDirPath, { recursive: true }); + console.log(`📁 /${exampleDir} directory created.`); } // Move old directories to new app-example directory or delete them for (const dir of oldDirs) { - const oldDirPath = path.join(root, dir) + const oldDirPath = path.join(root, dir); if (fs.existsSync(oldDirPath)) { if (userInput === 'y') { - const newDirPath = path.join(root, exampleDir, dir) - await fs.promises.rename(oldDirPath, newDirPath) - console.log(`➡️ /${dir} moved to /${exampleDir}/${dir}.`) + const newDirPath = path.join(root, exampleDir, dir); + await fs.promises.rename(oldDirPath, newDirPath); + console.log(`➡️ /${dir} moved to /${exampleDir}/${dir}.`); } else { - await fs.promises.rm(oldDirPath, { recursive: true, force: true }) - console.log(`❌ /${dir} deleted.`) + await fs.promises.rm(oldDirPath, { recursive: true, force: true }); + console.log(`❌ /${dir} deleted.`); } } else { - console.log(`➡️ /${dir} does not exist, skipping.`) + console.log(`➡️ /${dir} does not exist, skipping.`); } } // Create new /app directory - const newAppDirPath = path.join(root, newAppDir) - await fs.promises.mkdir(newAppDirPath, { recursive: true }) - console.log('\n📁 New /app directory created.') + const newAppDirPath = path.join(root, newAppDir); + await fs.promises.mkdir(newAppDirPath, { recursive: true }); + console.log('\n📁 New /app directory created.'); // Create index.tsx - const indexPath = path.join(newAppDirPath, 'index.tsx') - await fs.promises.writeFile(indexPath, indexContent) - console.log('📄 app/index.tsx created.') + const indexPath = path.join(newAppDirPath, 'index.tsx'); + await fs.promises.writeFile(indexPath, indexContent); + console.log('📄 app/index.tsx created.'); // Create _layout.tsx - const layoutPath = path.join(newAppDirPath, '_layout.tsx') - await fs.promises.writeFile(layoutPath, layoutContent) - console.log('📄 app/_layout.tsx created.') + const layoutPath = path.join(newAppDirPath, '_layout.tsx'); + await fs.promises.writeFile(layoutPath, layoutContent); + console.log('📄 app/_layout.tsx created.'); - console.log('\n✅ Project reset complete. Next steps:') + console.log('\n✅ Project reset complete. Next steps:'); console.log( `1. Run \`npx expo start\` to start a development server.\n2. Edit app/index.tsx to edit the main screen.${ - userInput === 'y' ? `\n3. Delete the /${exampleDir} directory when you're done referencing it.` : '' + userInput === 'y' + ? `\n3. Delete the /${exampleDir} directory when you're done referencing it.` + : '' }` - ) + ); } catch (error) { - console.error(`❌ Error during script execution: ${error.message}`) + console.error(`❌ Error during script execution: ${error.message}`); } -} +}; -rl.question('Do you want to move existing files to /app-example instead of deleting them? (Y/n): ', (answer) => { - const userInput = answer.trim().toLowerCase() || 'y' - if (userInput === 'y' || userInput === 'n') { - moveDirectories(userInput).finally(() => rl.close()) - } else { - console.log("❌ Invalid input. Please enter 'Y' or 'N'.") - rl.close() +rl.question( + 'Do you want to move existing files to /app-example instead of deleting them? (Y/n): ', + answer => { + const userInput = answer.trim().toLowerCase() || 'y'; + if (userInput === 'y' || userInput === 'n') { + moveDirectories(userInput).finally(() => rl.close()); + } else { + console.log("❌ Invalid input. Please enter 'Y' or 'N'."); + rl.close(); + } } -}) +); diff --git a/apps/web/eslint.config.mjs b/apps/web/eslint.config.mjs index 4ac79e2c..53f4a527 100644 --- a/apps/web/eslint.config.mjs +++ b/apps/web/eslint.config.mjs @@ -1,57 +1,12 @@ -import js from '@eslint/js'; import nextVitals from 'eslint-config-next/core-web-vitals'; import nextTs from 'eslint-config-next/typescript'; -import eslintConfigPrettier from 'eslint-config-prettier'; -import unusedImports from 'eslint-plugin-unused-imports'; import { defineConfig, globalIgnores } from 'eslint/config'; -import globals from 'globals'; -const eslintConfig = defineConfig([ +import baseConfig from '../../eslint.config.mjs'; + +export default defineConfig([ + ...baseConfig, ...nextVitals, ...nextTs, globalIgnores(['.next/**', 'out/**', 'build/**', 'next-env.d.ts']), - - /** 모든 파일 공통 규칙 */ - js.configs.recommended, - { - files: ['**/*.{js,jsx,ts,tsx}'], - plugins: { 'unused-imports': unusedImports }, - rules: { - 'no-console': ['warn', { allow: ['warn', 'error'] }], - 'no-nested-ternary': 'error', - 'no-unused-vars': 'off', - 'unused-imports/no-unused-imports': 'error', - }, - }, - - /** TS 전용 설정 + 규칙 */ - { - files: ['**/*.{ts,tsx}'], - languageOptions: { - ecmaVersion: 2020, - globals: globals.browser, - parserOptions: { - projectService: true, - tsconfigRootDir: process.cwd(), - }, - }, - rules: { - 'no-undef': 'off', - '@typescript-eslint/consistent-type-imports': 'error', - '@typescript-eslint/no-explicit-any': 'error', - '@typescript-eslint/no-unused-vars': [ - 'error', - { - vars: 'all', - varsIgnorePattern: '^_', - args: 'after-used', - argsIgnorePattern: '^_', - }, - ], - }, - }, - - eslintConfigPrettier, ]); - -export default eslintConfig; diff --git a/apps/web/package.json b/apps/web/package.json index 62988cc8..2e0a8ac8 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -10,32 +10,27 @@ "lint": "eslint --max-warnings 0", "check-types": "next typegen && tsc --noEmit" }, -"dependencies": { - "@repo/core": "workspace:*", - "@tanstack/react-query": "^5.96.2", - "@tanstack/react-query-devtools": "^5.96.2", - "next": "16.2.0", - "react": "^19.2.0", - "react-dom": "^19.2.0", - "zod": "^4.3.6", - "zustand": "^5.0.12" -}, + "dependencies": { + "@repo/core": "workspace:*", + "@tanstack/react-query": "^5.96.2", + "@tanstack/react-query-devtools": "^5.96.2", + "clsx": "^2.1.1", + "next": "16.2.0", + "react": "^19.2.0", + "react-dom": "^19.2.0", + "tailwind-merge": "^3.5.0", + "zod": "^4.3.6", + "zustand": "^5.0.12" + }, "devDependencies": { - "@eslint/js": "^9.39.1", - "@repo/eslint-config": "workspace:*", "@repo/typescript-config": "workspace:*", "@tailwindcss/postcss": "^4.2.2", "@types/node": "^22.15.3", "@types/react": "19.2.2", "@types/react-dom": "19.2.2", - "eslint": "^9.39.1", "eslint-config-next": "^16.2.2", - "eslint-config-prettier": "^10.1.1", - "eslint-plugin-unused-imports": "^4.4.1", - "globals": "^16.5.0", "postcss": "^8.5.8", "tailwindcss": "^4.2.2", - "typescript": "5.9.2", - "typescript-eslint": "^8.50.0" + "typescript": "5.9.2" } } diff --git a/apps/web/src/components/.gitkeep b/apps/web/public/.gitkeep similarity index 100% rename from apps/web/src/components/.gitkeep rename to apps/web/public/.gitkeep diff --git a/apps/web/public/file-text.svg b/apps/web/public/file-text.svg deleted file mode 100644 index 9cfb3c98..00000000 --- a/apps/web/public/file-text.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/apps/web/public/globe.svg b/apps/web/public/globe.svg deleted file mode 100644 index 4230a3d2..00000000 --- a/apps/web/public/globe.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/apps/web/public/next.svg b/apps/web/public/next.svg deleted file mode 100644 index 5174b28c..00000000 --- a/apps/web/public/next.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/apps/web/public/turborepo-dark.svg b/apps/web/public/turborepo-dark.svg deleted file mode 100644 index dae38fed..00000000 --- a/apps/web/public/turborepo-dark.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/apps/web/public/turborepo-light.svg b/apps/web/public/turborepo-light.svg deleted file mode 100644 index ddea9158..00000000 --- a/apps/web/public/turborepo-light.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/apps/web/public/vercel.svg b/apps/web/public/vercel.svg deleted file mode 100644 index 0164ddc5..00000000 --- a/apps/web/public/vercel.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/apps/web/public/window.svg b/apps/web/public/window.svg deleted file mode 100644 index bbc78006..00000000 --- a/apps/web/public/window.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/apps/web/src/app/favicon.ico b/apps/web/src/app/favicon.ico deleted file mode 100644 index 718d6fea..00000000 Binary files a/apps/web/src/app/favicon.ico and /dev/null differ diff --git a/apps/web/src/app/fonts/GeistMonoVF.woff b/apps/web/src/app/fonts/GeistMonoVF.woff deleted file mode 100644 index f2ae185c..00000000 Binary files a/apps/web/src/app/fonts/GeistMonoVF.woff and /dev/null differ diff --git a/apps/web/src/app/fonts/GeistVF.woff b/apps/web/src/app/fonts/GeistVF.woff deleted file mode 100644 index 1b62daac..00000000 Binary files a/apps/web/src/app/fonts/GeistVF.woff and /dev/null differ diff --git a/apps/web/src/app/layout.tsx b/apps/web/src/app/layout.tsx index 122e9cb5..d4c05ba4 100644 --- a/apps/web/src/app/layout.tsx +++ b/apps/web/src/app/layout.tsx @@ -1,17 +1,26 @@ -import React from 'react'; import type { Metadata } from 'next'; import localFont from 'next/font/local'; +import React from 'react'; +import Providers from '../components/Providers'; import '../styles/globals.css'; -import Providers from './providers'; -const geistSans = localFont({ - src: './fonts/GeistVF.woff', - variable: '--font-geist-sans', -}); -const geistMono = localFont({ - src: './fonts/GeistMonoVF.woff', - variable: '--font-geist-mono', +const pretendard = localFont({ + src: '../assets/fonts/PretendardVariable.woff2', + display: 'swap', + weight: '45 920', + preload: true, + fallback: [ + '-apple-system', + 'BlinkMacSystemFont', + 'Segoe UI', + 'Roboto', + 'Oxygen', + 'Ubuntu', + 'Cantarell', + 'Helvetica Neue', + 'sans-serif', + ], }); export const metadata: Metadata = { @@ -25,8 +34,8 @@ export default function RootLayout({ children: React.ReactNode; }>): React.JSX.Element { return ( - - + + {children} diff --git a/apps/web/src/app/page.module.css b/apps/web/src/app/page.module.css deleted file mode 100644 index e769a990..00000000 --- a/apps/web/src/app/page.module.css +++ /dev/null @@ -1,192 +0,0 @@ -.page { - --gray-rgb: 0, 0, 0; - --gray-alpha-200: rgba(var(--gray-rgb), 0.08); - --gray-alpha-100: rgba(var(--gray-rgb), 0.05); - - --button-primary-hover: #383838; - --button-secondary-hover: #f2f2f2; - - display: grid; - grid-template-rows: 20px 1fr 20px; - align-items: center; - justify-items: center; - min-height: 100svh; - padding: 80px; - gap: 64px; - font-synthesis: none; -} - -@media (prefers-color-scheme: dark) { - .page { - --gray-rgb: 255, 255, 255; - --gray-alpha-200: rgba(var(--gray-rgb), 0.145); - --gray-alpha-100: rgba(var(--gray-rgb), 0.06); - - --button-primary-hover: #ccc; - --button-secondary-hover: #1a1a1a; - } -} - -.main { - display: flex; - flex-direction: column; - gap: 32px; - grid-row-start: 2; -} - -.main ol { - font-family: var(--font-geist-mono); - padding-left: 0; - margin: 0; - font-size: 14px; - line-height: 24px; - letter-spacing: -0.01em; - list-style-position: inside; -} - -.main li:not(:last-of-type) { - margin-bottom: 8px; -} - -.main code { - font-family: inherit; - background: var(--gray-alpha-100); - padding: 2px 4px; - border-radius: 4px; - font-weight: 600; -} - -.ctas { - display: flex; - gap: 16px; -} - -.ctas a { - appearance: none; - border-radius: 128px; - height: 48px; - padding: 0 20px; - font-family: var(--font-geist-sans); - border: 1px solid transparent; - transition: - background 0.2s, - color 0.2s, - border-color 0.2s; - cursor: pointer; - display: flex; - align-items: center; - justify-content: center; - font-size: 16px; - line-height: 20px; - font-weight: 500; -} - -a.primary { - background: var(--foreground); - color: var(--background); - gap: 8px; -} - -a.secondary { - border-color: var(--gray-alpha-200); - min-width: 180px; -} - -button.secondary { - appearance: none; - border-radius: 128px; - height: 48px; - padding: 0 20px; - font-family: var(--font-geist-sans); - border: 1px solid transparent; - transition: - background 0.2s, - color 0.2s, - border-color 0.2s; - cursor: pointer; - display: flex; - align-items: center; - justify-content: center; - font-size: 16px; - line-height: 20px; - font-weight: 500; - background: transparent; - border-color: var(--gray-alpha-200); - min-width: 180px; -} - -.footer { - font-family: var(--font-geist-sans); - grid-row-start: 3; - display: flex; - gap: 24px; -} - -.footer a { - display: flex; - align-items: center; - gap: 8px; -} - -.footer img { - flex-shrink: 0; -} - -/* Enable hover only on non-touch devices */ -@media (hover: hover) and (pointer: fine) { - a.primary:hover { - background: var(--button-primary-hover); - border-color: transparent; - } - - a.secondary:hover { - background: var(--button-secondary-hover); - border-color: transparent; - } - - .footer a:hover { - text-decoration: underline; - text-underline-offset: 4px; - } -} - -@media (max-width: 600px) { - .page { - padding: 32px; - padding-bottom: 80px; - } - - .main { - align-items: center; - } - - .main ol { - text-align: center; - } - - .ctas { - flex-direction: column; - } - - .ctas a { - font-size: 14px; - height: 40px; - padding: 0 16px; - } - - a.secondary { - min-width: auto; - } - - .footer { - flex-wrap: wrap; - align-items: center; - justify-content: center; - } -} - -@media (prefers-color-scheme: dark) { - .logo { - filter: invert(); - } -} diff --git a/apps/web/src/app/page.tsx b/apps/web/src/app/page.tsx index 5ce97ac7..aa7fcf6c 100644 --- a/apps/web/src/app/page.tsx +++ b/apps/web/src/app/page.tsx @@ -1,65 +1,3 @@ -import React from 'react'; -import Image, { type ImageProps } from 'next/image'; -import styles from './page.module.css'; - -type Props = Omit & { - srcLight: string; - srcDark: string; -}; - -const ThemeImage = (props: Props) => { - const { srcLight, srcDark, alt, ...rest } = props; - - return ( - <> - {alt} - {alt} - - ); -}; - -export default function Home(): React.JSX.Element { - return ( -
-
- -
    -
  1. - Get started by editing apps/web/app/page.tsx -
  2. -
  3. Save and see your changes instantly.
  4. -
- - -
- -
- ); +export default function Home() { + return
main
; } - diff --git a/apps/web/src/app/providers.tsx b/apps/web/src/app/providers.tsx deleted file mode 100644 index 9e1c4c84..00000000 --- a/apps/web/src/app/providers.tsx +++ /dev/null @@ -1,33 +0,0 @@ -'use client'; - -import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; -import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; -import { useState } from 'react'; - -type ProvidersProps = { - children: React.ReactNode; -}; - -function Providers({ children }: ProvidersProps): React.JSX.Element { - const [queryClient] = useState( - () => - new QueryClient({ - defaultOptions: { - queries: { - staleTime: 60 * 1000, - refetchOnWindowFocus: false, - retry: 1, - }, - }, - }) - ); - - return ( - - {children} - - - ); -} - -export default Providers; diff --git a/apps/web/src/assets/fonts/PretendardVariable.woff2 b/apps/web/src/assets/fonts/PretendardVariable.woff2 new file mode 100644 index 00000000..49c54b51 Binary files /dev/null and b/apps/web/src/assets/fonts/PretendardVariable.woff2 differ diff --git a/apps/web/src/components/Providers.tsx b/apps/web/src/components/Providers.tsx new file mode 100644 index 00000000..62b7c514 --- /dev/null +++ b/apps/web/src/components/Providers.tsx @@ -0,0 +1,18 @@ +'use client'; + +import { QueryClientProvider } from '@tanstack/react-query'; +import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; +import { type ReactNode } from 'react'; + +import { getQueryClient } from '@/utils/queryClient'; + +export default function Providers({ children }: Readonly<{ children: ReactNode }>) { + const queryClient = getQueryClient(); + + return ( + + {children} + + + ); +} diff --git a/apps/web/src/styles/globals.css b/apps/web/src/styles/globals.css index edfec187..2b2e169a 100644 --- a/apps/web/src/styles/globals.css +++ b/apps/web/src/styles/globals.css @@ -1,46 +1,6 @@ @import 'tailwindcss'; +@import './reset.css'; -:root { - --background: #ffffff; - --foreground: #171717; -} - -@media (prefers-color-scheme: dark) { - :root { - --background: #0a0a0a; - --foreground: #ededed; - } -} - -html, -body { - max-width: 100vw; - overflow-x: hidden; -} - -body { - color: var(--foreground); - background: var(--background); -} - -a { - color: inherit; - text-decoration: none; -} - -.imgDark { - display: none; -} - -@media (prefers-color-scheme: dark) { - html { - color-scheme: dark; - } - - .imgLight { - display: none; - } - .imgDark { - display: unset; - } +/** 디자인 토큰 정의 */ +@theme { } diff --git a/apps/web/src/styles/reset.css b/apps/web/src/styles/reset.css new file mode 100644 index 00000000..c3c1ed20 --- /dev/null +++ b/apps/web/src/styles/reset.css @@ -0,0 +1,130 @@ +/* http://meyerweb.com/eric/tools/css/reset/ + v2.0 | 20110126 + License: none (public domain) +*/ +@layer base { + html, + body, + div, + span, + applet, + object, + iframe, + h1, + h2, + h3, + h4, + h5, + h6, + p, + blockquote, + pre, + a, + abbr, + acronym, + address, + big, + cite, + code, + del, + dfn, + em, + img, + ins, + kbd, + q, + s, + samp, + small, + strike, + strong, + sub, + sup, + tt, + var, + b, + u, + i, + center, + dl, + dt, + dd, + ol, + ul, + li, + fieldset, + form, + label, + legend, + table, + caption, + tbody, + tfoot, + thead, + tr, + th, + td, + article, + aside, + canvas, + details, + embed, + figure, + figcaption, + footer, + header, + hgroup, + menu, + nav, + output, + ruby, + section, + summary, + time, + mark, + audio, + video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; + } + /* HTML5 display-role reset for older browsers */ + article, + aside, + details, + figcaption, + figure, + footer, + header, + hgroup, + menu, + nav, + section { + display: block; + } + body { + line-height: 1; + } + ol, + ul { + list-style: none; + } + blockquote, + q { + quotes: none; + } + blockquote:before, + blockquote:after, + q:before, + q:after { + content: ''; + content: none; + } + table { + border-collapse: collapse; + border-spacing: 0; + } +} diff --git a/apps/web/src/utils/cn.ts b/apps/web/src/utils/cn.ts new file mode 100644 index 00000000..9ad0df42 --- /dev/null +++ b/apps/web/src/utils/cn.ts @@ -0,0 +1,6 @@ +import { type ClassValue, clsx } from 'clsx'; +import { twMerge } from 'tailwind-merge'; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +} diff --git a/apps/web/src/utils/queryClient.ts b/apps/web/src/utils/queryClient.ts new file mode 100644 index 00000000..dc2a28cd --- /dev/null +++ b/apps/web/src/utils/queryClient.ts @@ -0,0 +1,23 @@ +import { QueryClient, environmentManager } from '@tanstack/react-query'; + +/** REF: https://tanstack.com/query/latest/docs/framework/react/guides/advanced-ssr */ + +const makeQueryClient = () => { + return new QueryClient({ + defaultOptions: { + queries: { + staleTime: 60 * 1000, + refetchOnWindowFocus: false, + }, + }, + }); +}; + +let browserQueryClient: QueryClient | undefined; + +export const getQueryClient = () => { + if (environmentManager.isServer()) return makeQueryClient(); + if (!browserQueryClient) browserQueryClient = makeQueryClient(); + + return browserQueryClient; +}; diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 00000000..763d19c1 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,61 @@ +import js from '@eslint/js'; +import eslintConfigPrettier from 'eslint-config-prettier'; +import turboPlugin from 'eslint-plugin-turbo'; +import unusedImports from 'eslint-plugin-unused-imports'; +import { defineConfig } from 'eslint/config'; +import globals from 'globals'; +import process from 'node:process'; +import tseslint from 'typescript-eslint'; + +export default defineConfig([ + /** 모든 파일 공통 규칙 */ + js.configs.recommended, + tseslint.configs.recommended, + { + files: ['**/*.{js,jsx,ts,tsx}'], + plugins: { 'unused-imports': unusedImports }, + rules: { + 'no-console': ['warn', { allow: ['warn', 'error'] }], + 'no-nested-ternary': 'error', + 'no-unused-vars': 'off', + 'unused-imports/no-unused-imports': 'error', + }, + }, + { + plugins: { + turbo: turboPlugin, + }, + rules: { + 'turbo/no-undeclared-env-vars': 'warn', + }, + }, + + /** TS 전용 설정 + 규칙 */ + { + files: ['**/*.{ts,tsx}'], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + parserOptions: { + projectService: true, + tsconfigRootDir: process.cwd(), + }, + }, + rules: { + 'no-undef': 'off', + '@typescript-eslint/consistent-type-imports': 'error', + '@typescript-eslint/no-explicit-any': 'error', + '@typescript-eslint/no-unused-vars': [ + 'error', + { + vars: 'all', + varsIgnorePattern: '^_', + args: 'after-used', + argsIgnorePattern: '^_', + }, + ], + }, + }, + + eslintConfigPrettier, +]); diff --git a/package.json b/package.json index a4e921f8..7673ba2d 100644 --- a/package.json +++ b/package.json @@ -14,11 +14,18 @@ "dev:app": "pnpm --filter app start" }, "devDependencies": { + "@eslint/js": "^9.39.1", "@trivago/prettier-plugin-sort-imports": "^6.0.2", + "eslint": "^9.39.1", + "eslint-config-prettier": "^10.1.1", + "eslint-plugin-turbo": "^2.8.3", + "eslint-plugin-unused-imports": "^4.4.1", + "globals": "^16.5.0", "prettier": "^3.7.4", "prettier-plugin-tailwindcss": "^0.7.2", "turbo": "^2.8.21", - "typescript": "5.9.2" + "typescript": "5.9.2", + "typescript-eslint": "^8.50.0" }, "packageManager": "pnpm@10.17.0", "engines": { diff --git a/packages/core/package.json b/packages/core/package.json index c3079810..c7741981 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -9,6 +9,8 @@ "react": "^19.2.0" }, "devDependencies": { - "@types/react": "^19.0.0" + "@repo/typescript-config": "workspace:*", + "@types/react": "^19.0.0", + "typescript": "5.9.2" } -} \ No newline at end of file +} diff --git a/apps/web/src/utils/.gitkeep b/packages/core/src/hooks/.gitkeep similarity index 100% rename from apps/web/src/utils/.gitkeep rename to packages/core/src/hooks/.gitkeep diff --git a/packages/core/src/hooks/example.ts b/packages/core/src/hooks/example.ts deleted file mode 100644 index c6d95e32..00000000 --- a/packages/core/src/hooks/example.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { useState } from 'react'; - -export const useCounter = () => { - const [count, setCount] = useState(0); - return { count, setCount }; -}; \ No newline at end of file diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 9f660c20..e69de29b 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,3 +0,0 @@ -export { formatDate } from './utils/example'; -export type { UserT } from './types/example'; -export { useCounter } from './hooks/example'; \ No newline at end of file diff --git a/packages/core/src/types/.gitkeep b/packages/core/src/types/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/packages/core/src/types/example.ts b/packages/core/src/types/example.ts deleted file mode 100644 index ef58fa4f..00000000 --- a/packages/core/src/types/example.ts +++ /dev/null @@ -1,4 +0,0 @@ -export type UserT = { - id: number; - name: string; -}; \ No newline at end of file diff --git a/packages/core/src/utils/.gitkeep b/packages/core/src/utils/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/packages/core/src/utils/example.ts b/packages/core/src/utils/example.ts deleted file mode 100644 index d04b9414..00000000 --- a/packages/core/src/utils/example.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const formatDate = (date: Date): string => { - return date.toISOString().split('T')[0] ?? ''; -}; \ No newline at end of file diff --git a/packages/ui/tsconfig.json b/packages/core/tsconfig.json similarity index 70% rename from packages/ui/tsconfig.json rename to packages/core/tsconfig.json index ed023ce4..45fbbdb1 100644 --- a/packages/ui/tsconfig.json +++ b/packages/core/tsconfig.json @@ -1,9 +1,8 @@ { "extends": "@repo/typescript-config/react-library.json", "compilerOptions": { - "outDir": "dist", "strictNullChecks": true }, "include": ["src"], - "exclude": ["node_modules", "dist"] + "exclude": ["node_modules"] } diff --git a/packages/eslint-config/README.md b/packages/eslint-config/README.md deleted file mode 100644 index 8b42d901..00000000 --- a/packages/eslint-config/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# `@turbo/eslint-config` - -Collection of internal eslint configurations. diff --git a/packages/eslint-config/base.js b/packages/eslint-config/base.js deleted file mode 100644 index 09d316ef..00000000 --- a/packages/eslint-config/base.js +++ /dev/null @@ -1,32 +0,0 @@ -import js from "@eslint/js"; -import eslintConfigPrettier from "eslint-config-prettier"; -import turboPlugin from "eslint-plugin-turbo"; -import tseslint from "typescript-eslint"; -import onlyWarn from "eslint-plugin-only-warn"; - -/** - * A shared ESLint configuration for the repository. - * - * @type {import("eslint").Linter.Config[]} - * */ -export const config = [ - js.configs.recommended, - eslintConfigPrettier, - ...tseslint.configs.recommended, - { - plugins: { - turbo: turboPlugin, - }, - rules: { - "turbo/no-undeclared-env-vars": "warn", - }, - }, - { - plugins: { - onlyWarn, - }, - }, - { - ignores: ["dist/**"], - }, -]; diff --git a/packages/eslint-config/next.js b/packages/eslint-config/next.js deleted file mode 100644 index 4df088ac..00000000 --- a/packages/eslint-config/next.js +++ /dev/null @@ -1,57 +0,0 @@ -import js from "@eslint/js"; -import { globalIgnores } from "eslint/config"; -import eslintConfigPrettier from "eslint-config-prettier"; -import tseslint from "typescript-eslint"; -import pluginReactHooks from "eslint-plugin-react-hooks"; -import pluginReact from "eslint-plugin-react"; -import globals from "globals"; -import pluginNext from "@next/eslint-plugin-next"; -import { config as baseConfig } from "./base.js"; - -/** - * A custom ESLint configuration for libraries that use Next.js. - * - * @type {import("eslint").Linter.Config[]} - * */ -export const nextJsConfig = [ - ...baseConfig, - js.configs.recommended, - eslintConfigPrettier, - ...tseslint.configs.recommended, - globalIgnores([ - // Default ignores of eslint-config-next: - ".next/**", - "out/**", - "build/**", - "next-env.d.ts", - ]), - { - ...pluginReact.configs.flat.recommended, - languageOptions: { - ...pluginReact.configs.flat.recommended.languageOptions, - globals: { - ...globals.serviceworker, - }, - }, - }, - { - plugins: { - "@next/next": pluginNext, - }, - rules: { - ...pluginNext.configs.recommended.rules, - ...pluginNext.configs["core-web-vitals"].rules, - }, - }, - { - plugins: { - "react-hooks": pluginReactHooks, - }, - settings: { react: { version: "detect" } }, - rules: { - ...pluginReactHooks.configs.recommended.rules, - // React scope no longer necessary with new JSX transform. - "react/react-in-jsx-scope": "off", - }, - }, -]; diff --git a/packages/eslint-config/package.json b/packages/eslint-config/package.json deleted file mode 100644 index 6fd5c24d..00000000 --- a/packages/eslint-config/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "@repo/eslint-config", - "version": "0.0.0", - "type": "module", - "private": true, - "exports": { - "./base": "./base.js", - "./next-js": "./next.js", - "./react-internal": "./react-internal.js" - }, - "devDependencies": { - "@eslint/js": "^9.39.1", - "@next/eslint-plugin-next": "^16.2.0", - "eslint": "^9.39.1", - "eslint-config-prettier": "^10.1.1", - "eslint-plugin-only-warn": "^1.1.0", - "eslint-plugin-react": "^7.37.5", - "eslint-plugin-react-hooks": "^5.2.0", - "eslint-plugin-turbo": "^2.7.1", - "globals": "^16.5.0", - "typescript": "^5.9.2", - "typescript-eslint": "^8.50.0" - } -} diff --git a/packages/eslint-config/react-internal.js b/packages/eslint-config/react-internal.js deleted file mode 100644 index daeccba2..00000000 --- a/packages/eslint-config/react-internal.js +++ /dev/null @@ -1,39 +0,0 @@ -import js from "@eslint/js"; -import eslintConfigPrettier from "eslint-config-prettier"; -import tseslint from "typescript-eslint"; -import pluginReactHooks from "eslint-plugin-react-hooks"; -import pluginReact from "eslint-plugin-react"; -import globals from "globals"; -import { config as baseConfig } from "./base.js"; - -/** - * A custom ESLint configuration for libraries that use React. - * - * @type {import("eslint").Linter.Config[]} */ -export const config = [ - ...baseConfig, - js.configs.recommended, - eslintConfigPrettier, - ...tseslint.configs.recommended, - pluginReact.configs.flat.recommended, - { - languageOptions: { - ...pluginReact.configs.flat.recommended.languageOptions, - globals: { - ...globals.serviceworker, - ...globals.browser, - }, - }, - }, - { - plugins: { - "react-hooks": pluginReactHooks, - }, - settings: { react: { version: "detect" } }, - rules: { - ...pluginReactHooks.configs.recommended.rules, - // React scope no longer necessary with new JSX transform. - "react/react-in-jsx-scope": "off", - }, - }, -]; diff --git a/packages/typescript-config/nextjs.json b/packages/typescript-config/nextjs.json index e6defa48..964f1909 100644 --- a/packages/typescript-config/nextjs.json +++ b/packages/typescript-config/nextjs.json @@ -7,6 +7,8 @@ "moduleResolution": "Bundler", "allowJs": true, "jsx": "preserve", - "noEmit": true + "noEmit": true, + "declaration": false, + "declarationMap": false } } diff --git a/packages/ui/eslint.config.mjs b/packages/ui/eslint.config.mjs deleted file mode 100644 index 19170f88..00000000 --- a/packages/ui/eslint.config.mjs +++ /dev/null @@ -1,4 +0,0 @@ -import { config } from "@repo/eslint-config/react-internal"; - -/** @type {import("eslint").Linter.Config} */ -export default config; diff --git a/packages/ui/package.json b/packages/ui/package.json deleted file mode 100644 index 90c14881..00000000 --- a/packages/ui/package.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "@repo/ui", - "version": "0.0.0", - "private": true, - "exports": { - "./*": "./src/*.tsx" - }, - "scripts": { - "lint": "eslint . --max-warnings 0", - "generate:component": "turbo gen react-component", - "check-types": "tsc --noEmit" - }, - "devDependencies": { - "@repo/eslint-config": "workspace:*", - "@repo/typescript-config": "workspace:*", - "@types/node": "^22.15.3", - "@types/react": "19.2.2", - "@types/react-dom": "19.2.2", - "eslint": "^9.39.1", - "typescript": "5.9.2" - }, - "dependencies": { - "react": "^19.2.0", - "react-dom": "^19.2.0" - } -} diff --git a/packages/ui/src/button.tsx b/packages/ui/src/button.tsx deleted file mode 100644 index 78e5420c..00000000 --- a/packages/ui/src/button.tsx +++ /dev/null @@ -1,20 +0,0 @@ -"use client"; - -import { ReactNode } from "react"; - -interface ButtonProps { - children: ReactNode; - className?: string; - appName: string; -} - -export const Button = ({ children, className, appName }: ButtonProps) => { - return ( - - ); -}; diff --git a/packages/ui/src/card.tsx b/packages/ui/src/card.tsx deleted file mode 100644 index 7b988937..00000000 --- a/packages/ui/src/card.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { type JSX } from "react"; - -export function Card({ - className, - title, - children, - href, -}: { - className?: string; - title: string; - children: React.ReactNode; - href: string; -}): JSX.Element { - return ( - -

- {title} -> -

-

{children}

-
- ); -} diff --git a/packages/ui/src/code.tsx b/packages/ui/src/code.tsx deleted file mode 100644 index f7cbd22a..00000000 --- a/packages/ui/src/code.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { type JSX } from "react"; - -export function Code({ - children, - className, -}: { - children: React.ReactNode; - className?: string; -}): JSX.Element { - return {children}; -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ba845bb0..14937ab4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,9 +8,27 @@ importers: .: devDependencies: + '@eslint/js': + specifier: ^9.39.1 + version: 9.39.1 '@trivago/prettier-plugin-sort-imports': specifier: ^6.0.2 version: 6.0.2(prettier@3.7.4) + eslint: + specifier: ^9.39.1 + version: 9.39.1(jiti@2.6.1) + eslint-config-prettier: + specifier: ^10.1.1 + version: 10.1.1(eslint@9.39.1(jiti@2.6.1)) + eslint-plugin-turbo: + specifier: ^2.8.3 + version: 2.9.6(eslint@9.39.1(jiti@2.6.1))(turbo@2.8.21) + eslint-plugin-unused-imports: + specifier: ^4.4.1 + version: 4.4.1(@typescript-eslint/eslint-plugin@8.50.0(@typescript-eslint/parser@8.50.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.2))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.2))(eslint@9.39.1(jiti@2.6.1)) + globals: + specifier: ^16.5.0 + version: 16.5.0 prettier: specifier: ^3.7.4 version: 3.7.4 @@ -23,6 +41,9 @@ importers: typescript: specifier: 5.9.2 version: 5.9.2 + typescript-eslint: + specifier: ^8.50.0 + version: 8.50.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.2) apps/app: dependencies: @@ -129,6 +150,9 @@ importers: '@tanstack/react-query-devtools': specifier: ^5.96.2 version: 5.96.2(@tanstack/react-query@5.96.2(react@19.2.0))(react@19.2.0) + clsx: + specifier: ^2.1.1 + version: 2.1.1 next: specifier: 16.2.0 version: 16.2.0(@babel/core@7.29.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -138,6 +162,9 @@ importers: react-dom: specifier: ^19.2.0 version: 19.2.0(react@19.2.0) + tailwind-merge: + specifier: ^3.5.0 + version: 3.5.0 zod: specifier: ^4.3.6 version: 4.3.6 @@ -145,12 +172,6 @@ importers: specifier: ^5.0.12 version: 5.0.12(@types/react@19.2.2)(react@19.2.0)(use-sync-external-store@1.6.0(react@19.2.0)) devDependencies: - '@eslint/js': - specifier: ^9.39.1 - version: 9.39.1 - '@repo/eslint-config': - specifier: workspace:* - version: link:../../packages/eslint-config '@repo/typescript-config': specifier: workspace:* version: link:../../packages/typescript-config @@ -166,21 +187,9 @@ importers: '@types/react-dom': specifier: 19.2.2 version: 19.2.2(@types/react@19.2.2) - eslint: - specifier: ^9.39.1 - version: 9.39.1(jiti@2.6.1) eslint-config-next: specifier: ^16.2.2 version: 16.2.2(@typescript-eslint/parser@8.50.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.2))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.2) - eslint-config-prettier: - specifier: ^10.1.1 - version: 10.1.1(eslint@9.39.1(jiti@2.6.1)) - eslint-plugin-unused-imports: - specifier: ^4.4.1 - version: 4.4.1(@typescript-eslint/eslint-plugin@8.50.0(@typescript-eslint/parser@8.50.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.2))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.2))(eslint@9.39.1(jiti@2.6.1)) - globals: - specifier: ^16.5.0 - version: 16.5.0 postcss: specifier: ^8.5.8 version: 8.5.8 @@ -190,9 +199,6 @@ importers: typescript: specifier: 5.9.2 version: 5.9.2 - typescript-eslint: - specifier: ^8.50.0 - version: 8.50.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.2) packages/core: dependencies: @@ -200,79 +206,18 @@ importers: specifier: ^19.2.0 version: 19.2.0 devDependencies: - '@types/react': - specifier: ^19.0.0 - version: 19.2.2 - - packages/eslint-config: - devDependencies: - '@eslint/js': - specifier: ^9.39.1 - version: 9.39.1 - '@next/eslint-plugin-next': - specifier: ^16.2.0 - version: 16.2.0 - eslint: - specifier: ^9.39.1 - version: 9.39.1(jiti@2.6.1) - eslint-config-prettier: - specifier: ^10.1.1 - version: 10.1.1(eslint@9.39.1(jiti@2.6.1)) - eslint-plugin-only-warn: - specifier: ^1.1.0 - version: 1.1.0 - eslint-plugin-react: - specifier: ^7.37.5 - version: 7.37.5(eslint@9.39.1(jiti@2.6.1)) - eslint-plugin-react-hooks: - specifier: ^5.2.0 - version: 5.2.0(eslint@9.39.1(jiti@2.6.1)) - eslint-plugin-turbo: - specifier: ^2.7.1 - version: 2.7.1(eslint@9.39.1(jiti@2.6.1))(turbo@2.8.21) - globals: - specifier: ^16.5.0 - version: 16.5.0 - typescript: - specifier: ^5.9.2 - version: 5.9.2 - typescript-eslint: - specifier: ^8.50.0 - version: 8.50.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.2) - - packages/typescript-config: {} - - packages/ui: - dependencies: - react: - specifier: ^19.2.0 - version: 19.2.0 - react-dom: - specifier: ^19.2.0 - version: 19.2.0(react@19.2.0) - devDependencies: - '@repo/eslint-config': - specifier: workspace:* - version: link:../eslint-config '@repo/typescript-config': specifier: workspace:* version: link:../typescript-config - '@types/node': - specifier: ^22.15.3 - version: 22.15.3 '@types/react': - specifier: 19.2.2 + specifier: ^19.0.0 version: 19.2.2 - '@types/react-dom': - specifier: 19.2.2 - version: 19.2.2(@types/react@19.2.2) - eslint: - specifier: ^9.39.1 - version: 9.39.1(jiti@2.6.1) typescript: specifier: 5.9.2 version: 5.9.2 + packages/typescript-config: {} + packages: '@0no-co/graphql.web@1.2.0': @@ -1183,9 +1128,6 @@ packages: '@next/env@16.2.0': resolution: {integrity: sha512-OZIbODWWAi0epQRCRjNe1VO45LOFBzgiyqmTLzIqWq6u1wrxKnAyz1HH6tgY/Mc81YzIjRPoYsPAEr4QV4l9TA==} - '@next/eslint-plugin-next@16.2.0': - resolution: {integrity: sha512-3D3pEMcGKfENC9Pzlkr67GOm+205+5hRdYPZvHuNIy5sr9k0ybSU8g+sxOO/R/RLEh/gWZ3UlY+5LmEyZ1xgXQ==} - '@next/eslint-plugin-next@16.2.2': resolution: {integrity: sha512-IOPbWzDQ+76AtjZioaCjpIY72xNSDMnarZ2GMQ4wjNLvnJEJHqxQwGFhgnIWLV9klb4g/+amg88Tk5OXVpyLTw==} @@ -2338,6 +2280,10 @@ packages: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} @@ -2673,10 +2619,6 @@ packages: peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 - eslint-plugin-only-warn@1.1.0: - resolution: {integrity: sha512-2tktqUAT+Q3hCAU0iSf4xAN1k9zOpjK5WO8104mB0rT/dGhOa09582HN5HlbxNbPRZ0THV7nLGvzugcNOSjzfA==} - engines: {node: '>=6'} - eslint-plugin-react-hooks@5.2.0: resolution: {integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==} engines: {node: '>=10'} @@ -2695,8 +2637,8 @@ packages: peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 - eslint-plugin-turbo@2.7.1: - resolution: {integrity: sha512-ZC7dTOdw6tGuvx1CeC1WQ0pMkgT/Jmj69QW93d63nysiLbbKRLiDKKA9s/TvwJHq8Uvbou2+hnU8if1L0jHsVQ==} + eslint-plugin-turbo@2.9.6: + resolution: {integrity: sha512-mntEkRe71izva2mJHZGxH2ccOdySqXiNJf5tdzRabaxhudLCeonPUdTE6aNGOhgVeL1lclxg5/ibp3C/cpe+kQ==} peerDependencies: eslint: '>6.6.0' turbo: '>2.0.0' @@ -4676,6 +4618,9 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + tailwind-merge@3.5.0: + resolution: {integrity: sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==} + tailwindcss@4.2.2: resolution: {integrity: sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==} @@ -6266,10 +6211,6 @@ snapshots: '@next/env@16.2.0': {} - '@next/eslint-plugin-next@16.2.0': - dependencies: - fast-glob: 3.3.1 - '@next/eslint-plugin-next@16.2.2': dependencies: fast-glob: 3.3.1 @@ -7498,6 +7439,8 @@ snapshots: clone@1.0.4: {} + clsx@2.1.1: {} + color-convert@1.9.3: dependencies: color-name: 1.1.3 @@ -7929,8 +7872,6 @@ snapshots: safe-regex-test: 1.1.0 string.prototype.includes: 2.0.1 - eslint-plugin-only-warn@1.1.0: {} - eslint-plugin-react-hooks@5.2.0(eslint@9.39.1(jiti@2.6.1)): dependencies: eslint: 9.39.1(jiti@2.6.1) @@ -7968,7 +7909,7 @@ snapshots: string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 - eslint-plugin-turbo@2.7.1(eslint@9.39.1(jiti@2.6.1))(turbo@2.8.21): + eslint-plugin-turbo@2.9.6(eslint@9.39.1(jiti@2.6.1))(turbo@2.8.21): dependencies: dotenv: 16.0.3 eslint: 9.39.1(jiti@2.6.1) @@ -10281,6 +10222,8 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} + tailwind-merge@3.5.0: {} + tailwindcss@4.2.2: {} tapable@2.3.2: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 3ff5faaa..e9b0dad6 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,3 +1,3 @@ packages: - - "apps/*" - - "packages/*" + - 'apps/*' + - 'packages/*'