diff --git a/.claude/settings.local.json b/.claude/settings.local.json deleted file mode 100644 index 725b4574..00000000 --- a/.claude/settings.local.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "permissions": { - "allow": [ - "Bash(grep:*)", - "Bash(tree:*)", - "Bash(find:*)", - "Bash(git mv:*)", - "Bash(wc:*)", - "Bash(npx tsc:*)", - "Bash(git add:*)", - "Bash(git commit:*)" - ] - } -} diff --git a/.github/ISSUE_TEMPLATE/bug_issue.yml b/.github/ISSUE_TEMPLATE/bug_issue.yml deleted file mode 100644 index a44d8e43..00000000 --- a/.github/ISSUE_TEMPLATE/bug_issue.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: '버그 제보' -description: Bug Issue 작성 기본 양식입니다. -labels: ['🐞 Fix'] -title: '[fix] ' -body: - - type: markdown - attributes: - value: | - 작성 예시 : "[fix] 버튼 컴포넌트 버그 수정" - - type: textarea - id: bug-description - attributes: - label: 버그 설명 - description: 버그가 언제/어떻게 발생했는지 명확하게 적어주세요. - placeholder: 설명을 적어주세요. - validations: - required: true - - type: textarea - id: reproduction - attributes: - label: 재현 방법 - description: 버그가 재현되는 상황을 설명해주세요. - placeholder: 설명을 적어주세요. - validations: - required: true - - type: textarea - id: expected - attributes: - label: 기대했던 정상 동작 - description: 기대했던 정상적인 동작에 대해서 설명해주세요. - placeholder: 설명을 적어주세요. - validations: - required: true diff --git a/.github/ISSUE_TEMPLATE/feature_issue.yml b/.github/ISSUE_TEMPLATE/feature_issue.yml deleted file mode 100644 index e9ab468f..00000000 --- a/.github/ISSUE_TEMPLATE/feature_issue.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: '기능 추가' -description: 기능 추가 Issue 작성 양식입니다. -labels: ['✨ Feature'] -title: '[feat] ' -body: - - type: markdown - attributes: - value: | - 작성 예시 : "[feat] 버튼 컴포넌트 만들기" - - type: textarea - id: feature-description - attributes: - label: 작업 설명 - description: 어떠한 기능을 추가하시는 건지 적어주세요. - placeholder: 설명을 적어주세요. - validations: - required: true - - type: textarea - id: approach - attributes: - label: 접근 방법 - description: 고려하신 방법이나, 접근에 대해서 설명해주세요. - placeholder: 설명을 적어주세요. - validations: - required: true diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 843738a5..9ae31a0f 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,46 +1,37 @@ - - - - + + + + -## 📌 Related Issue Number +## Summary - + -- Closes #1 +## Linear ---- + + -## Checklist +- -- [ ] 🎋 base 브랜치를 제대로 설정했나요? -- [ ] 🖌️ PR 제목은 형식에 맞게 잘 작성했나요? -- [ ] 🏗️ 빌드는 성공했나요? (pnpm build) -- [ ] 🧹 불필요한 코드는 제거했나요? e.g. console.log -- [ ] 🙇‍♂️ 리뷰어를 지정했나요? -- [ ] 🏷️ 라벨은 등록했나요? +## Changes ---- +- +- +- -## ✅ Key Changes +## Testing -> 이번 PR에서 작업한 내용을 간략히 설명해주세요 + -1. 내용1 - - 설명 -2. 내용2 - - 설명 +- ---- +## Risk / Impact -## 💡 New Insights & Learnings +- 영향 범위: +- 확인이 필요한 부분: +- 배포 시 유의사항: -- *** +## Screenshots / Video -## 📢 To Reviewers - -- *** - -## 📸 Screenshot or Video (Optional) - - + diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index be1265b2..92449635 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,39 +3,37 @@ name: CI on: pull_request: branches: + - develop - main - - pre-production jobs: ci: runs-on: ubuntu-latest - env: - NEXT_PUBLIC_API_BASE_URL: ${{ secrets.NEXT_PUBLIC_API_BASE_URL }} - steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 - name: Setup Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: '20' - - - name: Install pnpm - run: npm install -g pnpm + cache: 'pnpm' - name: Install dependencies - run: pnpm install + run: pnpm install --frozen-lockfile - - name: Run Lint - run: pnpm lint + - name: Run lint + run: pnpm ci:lint - - name: Check Prettier formatting - run: pnpm prettier --check "**/*.{js,ts,tsx,jsx,mjs,hbs,json,css,md}" + - name: Check formatting + run: pnpm format:check - - name: TypeScript Check - run: pnpm tsc --noEmit + - name: Type check + run: pnpm ci:typecheck - name: Build project - run: pnpm build + run: pnpm ci:build diff --git a/.github/workflows/expo-deploy.yml b/.github/workflows/expo-deploy.yml deleted file mode 100644 index 101851f6..00000000 --- a/.github/workflows/expo-deploy.yml +++ /dev/null @@ -1,140 +0,0 @@ -name: Deploy to EC2 and Notify Slack - -on: - push: - branches: - - native - -jobs: - deploy: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Deploy to EC2 - uses: appleboy/ssh-action@master - env: - REPO_PATH: /home/ubuntu/Pointer - with: - host: ${{ secrets.EC2_HOST }} - username: ${{ secrets.EC2_USER }} - key: ${{ secrets.EC2_SSH_KEY }} - envs: REPO_PATH - script: | - cd $REPO_PATH - echo "Pulling latest changes..." - git pull origin native - - echo "Installing dependencies..." - cd apps/native - npm install - pm2 restart expo - - echo "✅ Deployment completed!" - - - name: Prepare commit message - if: always() - id: commit - run: | - COMMIT_MSG=$(echo '${{ github.event.head_commit.message }}' | head -n 1 | sed 's/"/\\"/g' | sed "s/'/\\'/g") - echo "message=$COMMIT_MSG" >> $GITHUB_OUTPUT - - - name: Notify Slack - Success - if: success() - uses: slackapi/slack-github-action@v1.26.0 - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK - with: - payload: | - { - "text": "✅ Expo Deployment Success", - "blocks": [ - { - "type": "header", - "text": { - "type": "plain_text", - "text": "✅ Expo Deployment Successful" - } - }, - { - "type": "section", - "fields": [ - { - "type": "mrkdwn", - "text": "*Repository:* ${{ github.repository }}" - }, - { - "type": "mrkdwn", - "text": "*Branch:* ${{ github.ref_name }}" - }, - { - "type": "mrkdwn", - "text": "*Author:* ${{ github.event.head_commit.author.name }}" - }, - { - "type": "mrkdwn", - "text": "*Commit:* ${{ steps.commit.outputs.message }}" - } - ] - }, - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "<${{ github.event.head_commit.url }}|View Commit>" - } - } - ] - } - - - name: Notify Slack - Failure - if: failure() - uses: slackapi/slack-github-action@v1.26.0 - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK - with: - payload: | - { - "text": "❌ Expo Deployment Failed", - "blocks": [ - { - "type": "header", - "text": { - "type": "plain_text", - "text": "❌ Expo Deployment Failed" - } - }, - { - "type": "section", - "fields": [ - { - "type": "mrkdwn", - "text": "*Repository:* ${{ github.repository }}" - }, - { - "type": "mrkdwn", - "text": "*Branch:* ${{ github.ref_name }}" - }, - { - "type": "mrkdwn", - "text": "*Author:* ${{ github.event.head_commit.author.name }}" - }, - { - "type": "mrkdwn", - "text": "*Commit:* ${{ steps.commit.outputs.message }}" - } - ] - }, - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "⚠️ Check the <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|workflow logs>" - } - } - ] - } diff --git a/.github/workflows/pre-production.yml b/.github/workflows/pre-production.yml deleted file mode 100644 index 5575aef6..00000000 --- a/.github/workflows/pre-production.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Synchronize to forked repo -on: - push: - branches: - - pre-production - -jobs: - sync: - name: Sync forked repo - runs-on: ubuntu-latest - - steps: - - name: Checkout pre-production - uses: actions/checkout@v4 - with: - token: ${{ secrets.FORKED_REPO_TOKEN }} - fetch-depth: 0 - ref: pre-production - - - name: Add remote-url - run: | - git remote add forked-repo https://gudusol:${{ secrets.FORKED_REPO_TOKEN }}@github.com/gudusol/mopl - git config user.name gudusol - git config user.email ${{ secrets.EMAIL }} - - - name: Push changes to forked-repo - run: | - git push -f forked-repo pre-production - - - name: Clean up - run: | - git remote remove forked-repo diff --git a/.github/workflows/production.yml b/.github/workflows/production.yml deleted file mode 100644 index 5be09a7c..00000000 --- a/.github/workflows/production.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Synchronize to forked repo -on: - push: - branches: - - production - -jobs: - sync: - name: Sync forked repo - runs-on: ubuntu-latest - - steps: - - name: Checkout production - uses: actions/checkout@v4 - with: - token: ${{ secrets.FORKED_REPO_TOKEN }} - fetch-depth: 0 - ref: production - - - name: Add remote-url - run: | - git remote add forked-repo https://gudusol:${{ secrets.FORKED_REPO_TOKEN }}@github.com/gudusol/mopl - git config user.name gudusol - git config user.email ${{ secrets.EMAIL }} - - - name: Push changes to forked-repo - run: | - git push -f forked-repo production - - - name: Clean up - run: | - git remote remove forked-repo diff --git a/.gitignore b/.gitignore index 96fab4fe..30d937fe 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,8 @@ yarn-error.log* # Misc .DS_Store *.pem + +CLAUDE.md +AGENTS.md +.claude +.omc diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..a3fd891b --- /dev/null +++ b/.prettierignore @@ -0,0 +1,18 @@ +node_modules +.github +.pnp +.pnp.js +.turbo +.next +out +build +dist +coverage + +apps/native/ios/Pods +apps/native/ios/build +apps/native/android/.gradle +apps/native/android/build +apps/native/android/app/.cxx + +apps/admin/src/routeTree.gen.ts diff --git a/apps/admin/src/apis/controller/concept/index.ts b/apps/admin/src/apis/controller/concept/index.ts index 386bc4ed..c389174a 100644 --- a/apps/admin/src/apis/controller/concept/index.ts +++ b/apps/admin/src/apis/controller/concept/index.ts @@ -16,4 +16,4 @@ export { postConceptCategory, putConcept, putConceptCategory, -}; \ No newline at end of file +}; diff --git a/apps/admin/src/apis/controller/qna/deleteQnaChat.ts b/apps/admin/src/apis/controller/qna/deleteQnaChat.ts index b208a75d..4e7e467e 100644 --- a/apps/admin/src/apis/controller/qna/deleteQnaChat.ts +++ b/apps/admin/src/apis/controller/qna/deleteQnaChat.ts @@ -5,4 +5,3 @@ const deleteQnaChat = () => { }; export default deleteQnaChat; - diff --git a/apps/admin/src/apis/controller/qna/getQna.ts b/apps/admin/src/apis/controller/qna/getQna.ts index a591d7d4..a4537077 100644 --- a/apps/admin/src/apis/controller/qna/getQna.ts +++ b/apps/admin/src/apis/controller/qna/getQna.ts @@ -13,4 +13,3 @@ const getQna = (params?: GetQnaParams) => { }; export default getQna; - diff --git a/apps/admin/src/apis/controller/qna/getQnaById.ts b/apps/admin/src/apis/controller/qna/getQnaById.ts index d5d1e866..6b93b00f 100644 --- a/apps/admin/src/apis/controller/qna/getQnaById.ts +++ b/apps/admin/src/apis/controller/qna/getQnaById.ts @@ -19,4 +19,3 @@ const getQnaById = ({ qnaId, enabled = true }: GetQnaByIdParams) => { }; export default getQnaById; - diff --git a/apps/admin/src/apis/controller/qna/index.ts b/apps/admin/src/apis/controller/qna/index.ts index f7f5e4ed..092ce537 100644 --- a/apps/admin/src/apis/controller/qna/index.ts +++ b/apps/admin/src/apis/controller/qna/index.ts @@ -6,4 +6,3 @@ import putQnaChat from './putQnaChat'; import useSubscribeQna from './useSubscribeQna'; export { deleteQnaChat, getQna, getQnaById, postQnaChat, putQnaChat, useSubscribeQna }; - diff --git a/apps/admin/src/apis/controller/qna/postQnaChat.ts b/apps/admin/src/apis/controller/qna/postQnaChat.ts index ee07f60b..595313a1 100644 --- a/apps/admin/src/apis/controller/qna/postQnaChat.ts +++ b/apps/admin/src/apis/controller/qna/postQnaChat.ts @@ -5,4 +5,3 @@ const postQnaChat = () => { }; export default postQnaChat; - diff --git a/apps/admin/src/apis/controller/qna/putQnaChat.ts b/apps/admin/src/apis/controller/qna/putQnaChat.ts index 1986586b..69153d1b 100644 --- a/apps/admin/src/apis/controller/qna/putQnaChat.ts +++ b/apps/admin/src/apis/controller/qna/putQnaChat.ts @@ -5,4 +5,3 @@ const putQnaChat = () => { }; export default putQnaChat; - diff --git a/apps/admin/src/apis/controller/qna/useSubscribeQna.ts b/apps/admin/src/apis/controller/qna/useSubscribeQna.ts index be6a44fc..7485ddb3 100644 --- a/apps/admin/src/apis/controller/qna/useSubscribeQna.ts +++ b/apps/admin/src/apis/controller/qna/useSubscribeQna.ts @@ -69,12 +69,24 @@ const useSubscribeQna = ({ const onConnectionStatusChangeRef = useRef(onConnectionStatusChange); // 콜백 refs를 최신 값으로 동기화 - useEffect(() => { onChatEventRef.current = onChatEvent; }, [onChatEvent]); - useEffect(() => { onReadStatusEventRef.current = onReadStatusEvent; }, [onReadStatusEvent]); - useEffect(() => { onHeartbeatRef.current = onHeartbeat; }, [onHeartbeat]); - useEffect(() => { onErrorRef.current = onError; }, [onError]); - useEffect(() => { onOpenRef.current = onOpen; }, [onOpen]); - useEffect(() => { onConnectionStatusChangeRef.current = onConnectionStatusChange; }, [onConnectionStatusChange]); + useEffect(() => { + onChatEventRef.current = onChatEvent; + }, [onChatEvent]); + useEffect(() => { + onReadStatusEventRef.current = onReadStatusEvent; + }, [onReadStatusEvent]); + useEffect(() => { + onHeartbeatRef.current = onHeartbeat; + }, [onHeartbeat]); + useEffect(() => { + onErrorRef.current = onError; + }, [onError]); + useEffect(() => { + onOpenRef.current = onOpen; + }, [onOpen]); + useEffect(() => { + onConnectionStatusChangeRef.current = onConnectionStatusChange; + }, [onConnectionStatusChange]); // Refs for stable function references const connectRef = useRef<() => void>(() => {}); diff --git a/apps/admin/src/components/common/Modals/CreatePracticeTestModal.tsx b/apps/admin/src/components/common/Modals/CreatePracticeTestModal.tsx index 29bc84c0..d7d245f3 100644 --- a/apps/admin/src/components/common/Modals/CreatePracticeTestModal.tsx +++ b/apps/admin/src/components/common/Modals/CreatePracticeTestModal.tsx @@ -54,7 +54,7 @@ const CreatePracticeTestModal = ({ onClose }: Props) => { {/* Header */}
-
+
@@ -100,8 +100,7 @@ const CreatePracticeTestModal = ({ onClose }: Props) => {
{ {...register('name', { required: true })} autoFocus /> -

- 이 카테고리에 속한 모든 개념 태그에 적용됩니다. -

+

이 카테고리에 속한 모든 개념 태그에 적용됩니다.

{/* Action Buttons */} diff --git a/apps/admin/src/components/common/Modals/Modal.tsx b/apps/admin/src/components/common/Modals/Modal.tsx index 5ce38569..87829b5d 100644 --- a/apps/admin/src/components/common/Modals/Modal.tsx +++ b/apps/admin/src/components/common/Modals/Modal.tsx @@ -26,11 +26,11 @@ const Modal = ({ isOpen, onClose, children }: ModalProps) => { return createPortal(
e.stopPropagation()}> {children}
diff --git a/apps/admin/src/components/common/Modals/ProgressModal.tsx b/apps/admin/src/components/common/Modals/ProgressModal.tsx index beadef9d..b5845888 100644 --- a/apps/admin/src/components/common/Modals/ProgressModal.tsx +++ b/apps/admin/src/components/common/Modals/ProgressModal.tsx @@ -3,7 +3,7 @@ import dayjs from 'dayjs'; import { InlineProblemViewer, ProblemViewer } from '@repo/pointer-editor-v2'; import { components } from '@schema'; import { parseEditorContent } from '@utils'; -import { Calendar, CheckCircle2, Clock, FileText, Package, X } from 'lucide-react'; +import { FileText, Package, X } from 'lucide-react'; import 'dayjs/locale/ko'; diff --git a/apps/admin/src/components/common/Modals/TagSelectModal.tsx b/apps/admin/src/components/common/Modals/TagSelectModal.tsx index 01be9e2a..7270a83f 100644 --- a/apps/admin/src/components/common/Modals/TagSelectModal.tsx +++ b/apps/admin/src/components/common/Modals/TagSelectModal.tsx @@ -1,5 +1,5 @@ import { getConcept } from '@apis'; -import { Button, Input, Tag } from '@components'; +import { Input, Tag } from '@components'; import { debounce } from 'lodash'; import { useEffect, useState } from 'react'; import { useForm } from 'react-hook-form'; diff --git a/apps/admin/src/components/common/ProblemCard.tsx b/apps/admin/src/components/common/ProblemCard.tsx index 95fd4eb6..a228dcc0 100644 --- a/apps/admin/src/components/common/ProblemCard.tsx +++ b/apps/admin/src/components/common/ProblemCard.tsx @@ -16,7 +16,7 @@ const ProblemCard = ({ title, memo, problemText, - answer, + answer: _answer, onDelete, onClick, }: ProblemCardProps) => { diff --git a/apps/admin/src/components/problem/PracticeTestSelect.tsx b/apps/admin/src/components/problem/PracticeTestSelect.tsx index 4b3c6036..10630e84 100644 --- a/apps/admin/src/components/problem/PracticeTestSelect.tsx +++ b/apps/admin/src/components/problem/PracticeTestSelect.tsx @@ -2,7 +2,7 @@ import { useEffect, useState, useRef } from 'react'; import { getPracticeTest } from '@apis'; import { useForm } from 'react-hook-form'; import { debounce } from 'lodash'; -import { ChevronDown, X, Search, Plus, FileText, Calendar } from 'lucide-react'; +import { ChevronDown, Search, Plus } from 'lucide-react'; interface PracticeTestSelectProps { practiceTest: number | undefined; @@ -61,11 +61,11 @@ const PracticeTestSelect = ({ setIsOpen(false); }; - const handleClear = (e: React.MouseEvent) => { - e.stopPropagation(); - handlePracticeTest(undefined); - setValue('search', ''); - }; + // const handleClear = (e: React.MouseEvent) => { + // e.stopPropagation(); + // handlePracticeTest(undefined); + // setValue('search', ''); + // }; return (
diff --git a/apps/admin/src/contexts/SelectedStudentContext.tsx b/apps/admin/src/contexts/SelectedStudentContext.tsx index a3a49c9b..038dab5b 100644 --- a/apps/admin/src/contexts/SelectedStudentContext.tsx +++ b/apps/admin/src/contexts/SelectedStudentContext.tsx @@ -52,5 +52,3 @@ export const useSelectedStudent = () => { } return context; }; - - diff --git a/apps/admin/src/contexts/SidebarContext.tsx b/apps/admin/src/contexts/SidebarContext.tsx index 63e9f849..e3fe2cc7 100644 --- a/apps/admin/src/contexts/SidebarContext.tsx +++ b/apps/admin/src/contexts/SidebarContext.tsx @@ -29,4 +29,3 @@ export const useSidebar = () => { } return context; }; - diff --git a/apps/admin/src/hooks/index.ts b/apps/admin/src/hooks/index.ts index 52c01225..6f0ed90a 100644 --- a/apps/admin/src/hooks/index.ts +++ b/apps/admin/src/hooks/index.ts @@ -3,6 +3,7 @@ import useNavigation from './useNavigation'; import useProblemEssentialInput from './useProblemEssentialInput'; import useInvalidate from './useInvalidate'; import useEditor from './useEditor'; + import { useSelectedStudent } from '@/contexts/SelectedStudentContext'; export { diff --git a/apps/admin/src/hooks/useInvalidate.ts b/apps/admin/src/hooks/useInvalidate.ts index 50bafe27..74e8819a 100644 --- a/apps/admin/src/hooks/useInvalidate.ts +++ b/apps/admin/src/hooks/useInvalidate.ts @@ -72,7 +72,13 @@ const useInvalidate = () => { [queryClient] ); - return { invalidateAll, invalidateProblemSet, invalidatePublish, invalidateNotice, invalidateQna }; + return { + invalidateAll, + invalidateProblemSet, + invalidatePublish, + invalidateNotice, + invalidateQna, + }; }; export default useInvalidate; diff --git a/apps/admin/src/routes/_GNBLayout/concept-tags/index.tsx b/apps/admin/src/routes/_GNBLayout/concept-tags/index.tsx index 21efd242..d05a6692 100644 --- a/apps/admin/src/routes/_GNBLayout/concept-tags/index.tsx +++ b/apps/admin/src/routes/_GNBLayout/concept-tags/index.tsx @@ -17,11 +17,9 @@ import { Trash2, X, PackageOpen, - FolderOpen, CheckCircle2, Pencil, Filter, - Box, RotateCcw, Tags, } from 'lucide-react'; diff --git a/apps/admin/src/routes/_GNBLayout/problem-set/index.tsx b/apps/admin/src/routes/_GNBLayout/problem-set/index.tsx index efba5987..85a52e43 100644 --- a/apps/admin/src/routes/_GNBLayout/problem-set/index.tsx +++ b/apps/admin/src/routes/_GNBLayout/problem-set/index.tsx @@ -9,7 +9,6 @@ import { Search, Plus, Trash2, - ChevronRight, RotateCcw, Package, FileText, diff --git a/apps/admin/src/routes/_GNBLayout/problem-set/register/index.tsx b/apps/admin/src/routes/_GNBLayout/problem-set/register/index.tsx index 683e585a..3de45ef7 100644 --- a/apps/admin/src/routes/_GNBLayout/problem-set/register/index.tsx +++ b/apps/admin/src/routes/_GNBLayout/problem-set/register/index.tsx @@ -127,10 +127,10 @@ function RouteComponent() { openSearchModal(); }; - const handleAddProblem = (index: number) => { - setCurrentProblemIndex(index); - openSearchModal(); - }; + // const handleAddProblem = (index: number) => { + // setCurrentProblemIndex(index); + // openSearchModal(); + // }; const handleClickDeleteProblem = (index: number) => { setDeleteProblemIndex(index); diff --git a/apps/admin/src/routes/_GNBLayout/problem/$problemId/index.tsx b/apps/admin/src/routes/_GNBLayout/problem/$problemId/index.tsx index 52683cbc..eb46cfa5 100644 --- a/apps/admin/src/routes/_GNBLayout/problem/$problemId/index.tsx +++ b/apps/admin/src/routes/_GNBLayout/problem/$problemId/index.tsx @@ -24,7 +24,6 @@ import { SaveIcon, Sparkles, Hash, - BookOpen, Plus, ChevronRight, Clipboard, diff --git a/apps/admin/src/routes/_GNBLayout/publish/index.tsx b/apps/admin/src/routes/_GNBLayout/publish/index.tsx index 11b5453f..93d6a719 100644 --- a/apps/admin/src/routes/_GNBLayout/publish/index.tsx +++ b/apps/admin/src/routes/_GNBLayout/publish/index.tsx @@ -181,7 +181,7 @@ function RouteComponent() { const handleClickPrevMonth = () => setCurrentMonth(currentMonth.subtract(1, 'month')); const handleClickNextMonth = () => setCurrentMonth(currentMonth.add(1, 'month')); - const handleClickCurrentMonth = () => setCurrentMonth(dayjs().startOf('month')); + // const handleClickCurrentMonth = () => setCurrentMonth(dayjs().startOf('month')); const daysInMonth = currentMonth.daysInMonth(); const firstDayOfMonth = currentMonth.startOf('month').day(); // 1일 요일, 0: Sunday ~ 6: Saturday diff --git a/apps/admin/src/routes/_GNBLayout/publish/register/$publishDate/$studentId/index.tsx b/apps/admin/src/routes/_GNBLayout/publish/register/$publishDate/$studentId/index.tsx index 7c273ec6..3e809832 100644 --- a/apps/admin/src/routes/_GNBLayout/publish/register/$publishDate/$studentId/index.tsx +++ b/apps/admin/src/routes/_GNBLayout/publish/register/$publishDate/$studentId/index.tsx @@ -1,5 +1,5 @@ import { getProblemSetSearch, postPublish } from '@apis'; -import { Button, Header, Input, ProblemPreview } from '@components'; +import { Header, Input, ProblemPreview } from '@components'; import { useInvalidate } from '@hooks'; import { createFileRoute, Link, useRouter } from '@tanstack/react-router'; import { GetProblemSetSearchParams } from '@types'; @@ -8,15 +8,12 @@ import { useForm } from 'react-hook-form'; import { Slide, toast, ToastContainer } from 'react-toastify'; import { Search, - Package, RotateCcw, - ChevronRight, FileText, ChevronDown, ChevronUp, Send, Pencil, - CheckCircle, Circle, CircleCheck, } from 'lucide-react'; diff --git a/apps/admin/src/routes/login/index.tsx b/apps/admin/src/routes/login/index.tsx index b22c2c57..4d9c6cdf 100644 --- a/apps/admin/src/routes/login/index.tsx +++ b/apps/admin/src/routes/login/index.tsx @@ -4,7 +4,7 @@ import { Input } from '@components'; import { useNavigation } from '@hooks'; import { createFileRoute, redirect } from '@tanstack/react-router'; import { tokenStorage } from '@utils'; -import { Mail, Lock, LogIn, Sparkles, Shield } from 'lucide-react'; +import { Mail, Lock, LogIn } from 'lucide-react'; export const Route = createFileRoute('/login/')({ beforeLoad: async () => { diff --git a/apps/admin/src/styles/globals.css b/apps/admin/src/styles/globals.css index 7a77b824..d14fcf8b 100644 --- a/apps/admin/src/styles/globals.css +++ b/apps/admin/src/styles/globals.css @@ -24,7 +24,6 @@ --color-main: #617af9; --color-sub1: #c5ceff; --color-sub2: #e9ebf8; - } /* ========================= */ diff --git a/apps/native/assets/ios-pointer.icon/icon.json b/apps/native/assets/ios-pointer.icon/icon.json index 2a4af23c..4536c8e5 100644 --- a/apps/native/assets/ios-pointer.icon/icon.json +++ b/apps/native/assets/ios-pointer.icon/icon.json @@ -1,40 +1,35 @@ { - "fill" : { - "automatic-gradient" : "display-p3:0.32157,0.41961,0.91765,1.00000" + "fill": { + "automatic-gradient": "display-p3:0.32157,0.41961,0.91765,1.00000" }, - "groups" : [ + "groups": [ { - "layers" : [ + "layers": [ { - "image-name" : "outer.svg", - "name" : "outer" + "image-name": "outer.svg", + "name": "outer" }, { - "image-name" : "inner.svg", - "name" : "inner" + "image-name": "inner.svg", + "name": "inner" } ], - "position" : { - "scale" : 1.3, - "translation-in-points" : [ - 15, - 0 - ] + "position": { + "scale": 1.3, + "translation-in-points": [15, 0] }, - "shadow" : { - "kind" : "neutral", - "opacity" : 0.5 + "shadow": { + "kind": "neutral", + "opacity": 0.5 }, - "translucency" : { - "enabled" : true, - "value" : 0.5 + "translucency": { + "enabled": true, + "value": 0.5 } } ], - "supported-platforms" : { - "circles" : [ - "watchOS" - ], - "squares" : "shared" + "supported-platforms": { + "circles": ["watchOS"], + "squares": "shared" } -} \ No newline at end of file +} diff --git a/apps/native/eslint.config.mjs b/apps/native/eslint.config.mjs index 2450351e..086c665e 100644 --- a/apps/native/eslint.config.mjs +++ b/apps/native/eslint.config.mjs @@ -40,7 +40,8 @@ export default [ patterns: [ { group: ['@/*'], - message: 'Use specific aliases (@components, @theme, @apis, etc.) instead of @/ catch-all.', + message: + 'Use specific aliases (@components, @theme, @apis, etc.) instead of @/ catch-all.', }, ], }, diff --git a/apps/native/metro.config.js b/apps/native/metro.config.js index db6e7198..bee7fe29 100644 --- a/apps/native/metro.config.js +++ b/apps/native/metro.config.js @@ -21,7 +21,7 @@ config.resolver.nodeModulesPaths = [ config.resolver.blockList = [ /ios\/build\/.*/, /android\/build\/.*/, - /apps\/native\/dist\/.*/, // 프로젝트 자체의 dist만 차단 + /apps\/native\/dist\/.*/, // 프로젝트 자체의 dist만 차단 ]; // react-native-css-interop의 jsx-runtime을 직접 resolve @@ -39,11 +39,11 @@ config.resolver.resolveRequest = (context, moduleName, platform) => { filePath: require.resolve('react-native-css-interop/dist/runtime/jsx-dev-runtime.js'), }; } - + if (originalResolveRequest) { return originalResolveRequest(context, moduleName, platform); } return context.resolveRequest(context, moduleName, platform); }; -module.exports = withNativeWind(config, { input: './src/app/providers/global.css' }); \ No newline at end of file +module.exports = withNativeWind(config, { input: './src/app/providers/global.css' }); diff --git a/apps/native/package.json b/apps/native/package.json index 29220e37..16d53cd3 100644 --- a/apps/native/package.json +++ b/apps/native/package.json @@ -9,6 +9,7 @@ "ios": "expo run:ios", "web": "expo start --web --port 3000", "lint": "expo lint", + "typecheck": "tsc --noEmit", "openapi": "pnpm dlx openapi-typescript https://dev.api.math-pointer.com/v3/api-docs --output ./src/types/api/schema.d.ts && prettier --write ./src/types/api/schema.d.ts" }, "dependencies": { diff --git a/apps/native/src/apis/controller/common/qna/useGetSubscribeQna.ts b/apps/native/src/apis/controller/common/qna/useGetSubscribeQna.ts index 99922352..0800b89f 100644 --- a/apps/native/src/apis/controller/common/qna/useGetSubscribeQna.ts +++ b/apps/native/src/apis/controller/common/qna/useGetSubscribeQna.ts @@ -78,12 +78,24 @@ const useSubscribeQna = ({ const onOpenRef = useRef(onOpen); const onConnectionStatusChangeRef = useRef(onConnectionStatusChange); - useEffect(() => { onChatEventRef.current = onChatEvent; }, [onChatEvent]); - useEffect(() => { onReadStatusEventRef.current = onReadStatusEvent; }, [onReadStatusEvent]); - useEffect(() => { onHeartbeatRef.current = onHeartbeat; }, [onHeartbeat]); - useEffect(() => { onErrorRef.current = onError; }, [onError]); - useEffect(() => { onOpenRef.current = onOpen; }, [onOpen]); - useEffect(() => { onConnectionStatusChangeRef.current = onConnectionStatusChange; }, [onConnectionStatusChange]); + useEffect(() => { + onChatEventRef.current = onChatEvent; + }, [onChatEvent]); + useEffect(() => { + onReadStatusEventRef.current = onReadStatusEvent; + }, [onReadStatusEvent]); + useEffect(() => { + onHeartbeatRef.current = onHeartbeat; + }, [onHeartbeat]); + useEffect(() => { + onErrorRef.current = onError; + }, [onError]); + useEffect(() => { + onOpenRef.current = onOpen; + }, [onOpen]); + useEffect(() => { + onConnectionStatusChangeRef.current = onConnectionStatusChange; + }, [onConnectionStatusChange]); // Refs for stable function references (to avoid circular dependencies) const connectRef = useRef<() => void>(() => {}); diff --git a/apps/native/src/apis/controller/common/qna/useGetSubscribeQnaList.ts b/apps/native/src/apis/controller/common/qna/useGetSubscribeQnaList.ts index d1246d87..76bb3eac 100644 --- a/apps/native/src/apis/controller/common/qna/useGetSubscribeQnaList.ts +++ b/apps/native/src/apis/controller/common/qna/useGetSubscribeQnaList.ts @@ -72,11 +72,21 @@ const useSubscribeQnaList = ({ const onOpenRef = useRef(onOpen); const onConnectionStatusChangeRef = useRef(onConnectionStatusChange); - useEffect(() => { onQnaListEventRef.current = onQnaListEvent; }, [onQnaListEvent]); - useEffect(() => { onHeartbeatRef.current = onHeartbeat; }, [onHeartbeat]); - useEffect(() => { onErrorRef.current = onError; }, [onError]); - useEffect(() => { onOpenRef.current = onOpen; }, [onOpen]); - useEffect(() => { onConnectionStatusChangeRef.current = onConnectionStatusChange; }, [onConnectionStatusChange]); + useEffect(() => { + onQnaListEventRef.current = onQnaListEvent; + }, [onQnaListEvent]); + useEffect(() => { + onHeartbeatRef.current = onHeartbeat; + }, [onHeartbeat]); + useEffect(() => { + onErrorRef.current = onError; + }, [onError]); + useEffect(() => { + onOpenRef.current = onOpen; + }, [onOpen]); + useEffect(() => { + onConnectionStatusChangeRef.current = onConnectionStatusChange; + }, [onConnectionStatusChange]); // Refs for stable function references (to avoid circular dependencies) const connectRef = useRef<() => void>(() => {}); diff --git a/apps/native/src/features/student/home/hooks/useCalendarData.ts b/apps/native/src/features/student/home/hooks/useCalendarData.ts index 46e4fe6f..ac905d3c 100644 --- a/apps/native/src/features/student/home/hooks/useCalendarData.ts +++ b/apps/native/src/features/student/home/hooks/useCalendarData.ts @@ -3,7 +3,11 @@ import { useMemo } from 'react'; import { formatDateKey, isSameDay } from '@/utils/date'; import { publishProgressMap } from '../components/ProblemCalendar/constants'; -import { type CalendarCell, type CalendarProgress, type PublishResp } from '../components/ProblemCalendar/types'; +import { + type CalendarCell, + type CalendarProgress, + type PublishResp, +} from '../components/ProblemCalendar/types'; interface UseCalendarDataParams { selectedMonth: Date; @@ -11,7 +15,11 @@ interface UseCalendarDataParams { studyData: PublishResp[]; } -export const useCalendarData = ({ selectedMonth, selectedDate, studyData }: UseCalendarDataParams): CalendarCell[] => { +export const useCalendarData = ({ + selectedMonth, + selectedDate, + studyData, +}: UseCalendarDataParams): CalendarCell[] => { const progressByDate = useMemo(() => { return studyData.reduce>((acc, publish) => { acc[publish.publishAt] = publishProgressMap[publish.progress] ?? 'unavailable'; diff --git a/apps/native/src/features/student/qna/types.ts b/apps/native/src/features/student/qna/types.ts index 44d71296..c55d932e 100644 --- a/apps/native/src/features/student/qna/types.ts +++ b/apps/native/src/features/student/qna/types.ts @@ -294,13 +294,13 @@ export const mapSearchResults = (searchResp: QnASearchResp): SearchResult => { if (searchResp.chatResults?.data) { searchResp.chatResults.data.forEach((chat) => { messages.push({ - id: chat.chatId, - chatRoomId: chat.qnaId, - content: chat.chatContent, - senderName: chat.isMine ? '나' : '상대방', + id: chat.matchedChatId ?? 0, + chatRoomId: chat.qnaId ?? 0, + content: chat.matchedChatPreview ?? '', + senderName: '상대방', senderType: chat.qnaType === 'ADMIN_CHAT' ? 'publisher' : 'teacher', - status: 'asking', - date: formatDateTime(chat.latestMessageTime), + status: chat.qnaStatus === 'RESOLVED' ? 'resolved' : 'asking', + date: formatDateTime(chat.publishDate), matchedKeyword: '', }); }); diff --git a/apps/native/src/features/student/scrap/components/Card/cards/ScrapCard.tsx b/apps/native/src/features/student/scrap/components/Card/cards/ScrapCard.tsx index 9a2bf76a..5c6ac074 100644 --- a/apps/native/src/features/student/scrap/components/Card/cards/ScrapCard.tsx +++ b/apps/native/src/features/student/scrap/components/Card/cards/ScrapCard.tsx @@ -16,15 +16,12 @@ import { ImageWithSkeleton } from '@/components/common'; import type { ScrapListItemProps } from '../types'; import { TooltipPopover, ItemTooltipBox } from '../../Tooltip'; -import { isItemSelected } from '../../../utils/reducer'; +import { isItemSelected, type SelectedItem } from '../../../utils/reducer'; import { formatToMinute } from '../../../utils/formatters/formatToMinute'; import { useCardImageSources } from '../../../hooks'; type ScrapCardExtraProps = { - onMovePress?: (params: { - currentFolderId?: number; - selectedItems: { id: number; type: string }[]; - }) => void; + onMovePress?: (params: { currentFolderId?: number; selectedItems: SelectedItem[] }) => void; }; export const ScrapCard = (props: ScrapListItemProps & ScrapCardExtraProps) => { diff --git a/apps/native/src/features/student/scrap/components/Header/SearchScrapHeader.tsx b/apps/native/src/features/student/scrap/components/Header/SearchScrapHeader.tsx index 2fe7cb97..9e5e6f30 100644 --- a/apps/native/src/features/student/scrap/components/Header/SearchScrapHeader.tsx +++ b/apps/native/src/features/student/scrap/components/Header/SearchScrapHeader.tsx @@ -58,7 +58,7 @@ const SearchScrapHeader = ({ )} {navigateback.canGoBack() ? ( - navigateback.goBack()} className='pl-3 pr-2'> + navigateback.goBack()} className='pr-2 pl-3'> 취소 ) : ( diff --git a/apps/native/src/features/student/scrap/components/Tooltip/TooltipMenuItem.tsx b/apps/native/src/features/student/scrap/components/Tooltip/TooltipMenuItem.tsx index c4829555..e77262bc 100644 --- a/apps/native/src/features/student/scrap/components/Tooltip/TooltipMenuItem.tsx +++ b/apps/native/src/features/student/scrap/components/Tooltip/TooltipMenuItem.tsx @@ -38,7 +38,7 @@ export const TooltipMenuItem = ({ }: TooltipMenuItemProps) => { return ( diff --git a/apps/native/src/features/student/scrap/components/scrap/FilterBar.tsx b/apps/native/src/features/student/scrap/components/scrap/FilterBar.tsx index 3e3b0798..663c423f 100644 --- a/apps/native/src/features/student/scrap/components/scrap/FilterBar.tsx +++ b/apps/native/src/features/student/scrap/components/scrap/FilterBar.tsx @@ -77,7 +77,7 @@ export const FilterBar = ({ ))} {showViewAll && ( - + 전체보기 diff --git a/apps/native/src/features/student/scrap/components/scrap/ProblemSection.tsx b/apps/native/src/features/student/scrap/components/scrap/ProblemSection.tsx index e47122a4..b587a922 100644 --- a/apps/native/src/features/student/scrap/components/scrap/ProblemSection.tsx +++ b/apps/native/src/features/student/scrap/components/scrap/ProblemSection.tsx @@ -36,7 +36,7 @@ export const ProblemSection = ({ {isHovering && ( + className='absolute top-2 right-2 z-10 rounded-full bg-black/50 p-2'> )} @@ -56,7 +56,7 @@ export const ProblemSection = ({ {isHovering && ( + className='absolute top-2 right-2 z-10 rounded-full bg-black/50 p-2'> )} diff --git a/apps/native/src/features/student/scrap/screens/DeletedScrapScreen.tsx b/apps/native/src/features/student/scrap/screens/DeletedScrapScreen.tsx index dba647f3..872252b4 100644 --- a/apps/native/src/features/student/scrap/screens/DeletedScrapScreen.tsx +++ b/apps/native/src/features/student/scrap/screens/DeletedScrapScreen.tsx @@ -103,7 +103,7 @@ const DeletedScrapScreenContent = () => { setSortOrder={setSortOrder} /> - + {isLoading ? ( ) : ( diff --git a/apps/native/src/features/student/scrap/screens/FolderScrapScreen.tsx b/apps/native/src/features/student/scrap/screens/FolderScrapScreen.tsx index eb117710..ed4c6920 100644 --- a/apps/native/src/features/student/scrap/screens/FolderScrapScreen.tsx +++ b/apps/native/src/features/student/scrap/screens/FolderScrapScreen.tsx @@ -133,7 +133,7 @@ const FolderScrapScreenContent = () => { setSortOrder={setSortOrder} /> - + {isLoading ? ( ) : ( diff --git a/apps/native/src/features/student/scrap/screens/ScrapScreen.tsx b/apps/native/src/features/student/scrap/screens/ScrapScreen.tsx index 2b55aa99..92a7fcd5 100644 --- a/apps/native/src/features/student/scrap/screens/ScrapScreen.tsx +++ b/apps/native/src/features/student/scrap/screens/ScrapScreen.tsx @@ -163,7 +163,7 @@ const ScrapScreenContent = () => { /> {recentScrapsData.length > 0 && !reducerState.isSelecting && ( - + 최근 본 {recentScrapsData.map((scrap) => ( @@ -182,7 +182,7 @@ const ScrapScreenContent = () => { setSortOrder={setSortOrder} /> - + {isLoading ? ( ) : ( diff --git a/package.json b/package.json index 356403c9..e7a4806f 100644 --- a/package.json +++ b/package.json @@ -14,8 +14,13 @@ "dev": "turbo dev", "dev:admin": "turbo dev --filter=admin", "lint": "turbo lint", + "typecheck": "turbo run typecheck", "format": "prettier --write \"**/*.{js,ts,tsx,jsx,mjs,hbs,json,css,md}\"", - "svgr:admin": "pnpm dlx @svgr/cli apps/admin/public/svg --out-dir apps/admin/src/assets/svg --no-prettier && prettier --write \"apps/admin/src/assets/svg/**/*.{ts,tsx}\"" + "format:check": "prettier --check \"**/*.{js,ts,tsx,jsx,mjs,hbs,json,css,md}\"", + "svgr:admin": "pnpm dlx @svgr/cli apps/admin/public/svg --out-dir apps/admin/src/assets/svg --no-prettier && prettier --write \"apps/admin/src/assets/svg/**/*.{ts,tsx}\"", + "ci:lint": "turbo lint --filter=admin --filter=@repo/pointer-editor-v2", + "ci:typecheck": "turbo run typecheck --filter=admin --filter=@repo/pointer-editor-v2", + "ci:build": "turbo build --filter=admin --filter=@repo/pointer-editor-v2" }, "devDependencies": { "@typescript-eslint/eslint-plugin": "^8.23.0", diff --git a/packages/pointer-editor-v2/eslint.config.js b/packages/pointer-editor-v2/eslint.config.js index 78105f03..9be4ed31 100644 --- a/packages/pointer-editor-v2/eslint.config.js +++ b/packages/pointer-editor-v2/eslint.config.js @@ -1,14 +1,14 @@ -import js from '@eslint/js' -import globals from 'globals' -import reactHooks from 'eslint-plugin-react-hooks' -import reactRefresh from 'eslint-plugin-react-refresh' -import tseslint from 'typescript-eslint' -import importPlugin from 'eslint-plugin-import' -import { globalIgnores } from 'eslint/config' -import { fileURLToPath } from 'node:url' -import { dirname } from 'node:path' +import js from '@eslint/js'; +import globals from 'globals'; +import reactHooks from 'eslint-plugin-react-hooks'; +import reactRefresh from 'eslint-plugin-react-refresh'; +import tseslint from 'typescript-eslint'; +import importPlugin from 'eslint-plugin-import'; +import { globalIgnores } from 'eslint/config'; +import { fileURLToPath } from 'node:url'; +import { dirname } from 'node:path'; -const __dirname = dirname(fileURLToPath(import.meta.url)) +const __dirname = dirname(fileURLToPath(import.meta.url)); /** * Flat config for the pointer-editor-v2 package. @@ -60,32 +60,34 @@ export default tseslint.config([ * Force consumers to import from the consolidated barrel: `../assets`. * Also ban importing ui/base except inside src/editor/ui. */ - 'no-restricted-imports': ['error', { - paths: [ - { name: '../assets/icon', message: '아이콘은 ../assets 에서만 임포트하세요.' }, - { name: '../../assets/icon', message: '아이콘은 ../assets 에서만 임포트하세요.' }, - { name: '@/editor/assets/icon', message: '아이콘은 ../assets 에서만 임포트하세요.' }, - { name: '@editor/assets/icon', message: '아이콘은 ../assets 에서만 임포트하세요.' }, - ], - patterns: [ - // Disallow any nested path under assets/icon - '**/assets/icon', - '**/assets/icon/*', - // Disallow importing ui/base outside of the ui package - '**/editor/ui/base', - '**/editor/ui/base/*', - // Disallow importing from subpaths under editor/ui (enforce barrel usage) - '**/editor/ui/*', - '**/editor/ui/**', - // Disallow importing from subpaths under editor/utils (enforce barrel usage) - '**/editor/utils/*', - '**/editor/utils/**', - // Disallow importing from subpaths under editor/hooks (enforce barrel usage) - '**/editor/hooks/*', - '**/editor/hooks/**', - ], - }], - + 'no-restricted-imports': [ + 'error', + { + paths: [ + { name: '../assets/icon', message: '아이콘은 ../assets 에서만 임포트하세요.' }, + { name: '../../assets/icon', message: '아이콘은 ../assets 에서만 임포트하세요.' }, + { name: '@/editor/assets/icon', message: '아이콘은 ../assets 에서만 임포트하세요.' }, + { name: '@editor/assets/icon', message: '아이콘은 ../assets 에서만 임포트하세요.' }, + ], + patterns: [ + // Disallow any nested path under assets/icon + '**/assets/icon', + '**/assets/icon/*', + // Disallow importing ui/base outside of the ui package + '**/editor/ui/base', + '**/editor/ui/base/*', + // Disallow importing from subpaths under editor/ui (enforce barrel usage) + '**/editor/ui/*', + '**/editor/ui/**', + // Disallow importing from subpaths under editor/utils (enforce barrel usage) + '**/editor/utils/*', + '**/editor/utils/**', + // Disallow importing from subpaths under editor/hooks (enforce barrel usage) + '**/editor/hooks/*', + '**/editor/hooks/**', + ], + }, + ], }, }, @@ -94,18 +96,18 @@ export default tseslint.config([ files: ['src/editor/ui/**/*.{ts,tsx}'], rules: { // Re-apply only the assets/icon restriction; allow ui/base internally - 'no-restricted-imports': ['error', { - paths: [ - { name: '../assets/icon', message: '아이콘은 ../assets 에서만 임포트하세요.' }, - { name: '../../assets/icon', message: '아이콘은 ../assets 에서만 임포트하세요.' }, - { name: '@/editor/assets/icon', message: '아이콘은 ../assets 에서만 임포트하세요.' }, - { name: '@editor/assets/icon', message: '아이콘은 ../assets 에서만 임포트하세요.' }, - ], - patterns: [ - '**/assets/icon', - '**/assets/icon/*', - ], - }], + 'no-restricted-imports': [ + 'error', + { + paths: [ + { name: '../assets/icon', message: '아이콘은 ../assets 에서만 임포트하세요.' }, + { name: '../../assets/icon', message: '아이콘은 ../assets 에서만 임포트하세요.' }, + { name: '@/editor/assets/icon', message: '아이콘은 ../assets 에서만 임포트하세요.' }, + { name: '@editor/assets/icon', message: '아이콘은 ../assets 에서만 임포트하세요.' }, + ], + patterns: ['**/assets/icon', '**/assets/icon/*'], + }, + ], }, }, @@ -117,4 +119,4 @@ export default tseslint.config([ 'import/no-internal-modules': 'off', }, }, -]) +]); diff --git a/packages/pointer-editor-v2/package.json b/packages/pointer-editor-v2/package.json index 5f40f108..ca9b4854 100644 --- a/packages/pointer-editor-v2/package.json +++ b/packages/pointer-editor-v2/package.json @@ -32,7 +32,7 @@ ], "scripts": { "build": "vite build && tsc -p tsconfig.build.json", - "check-types": "tsc --noEmit", + "typecheck": "tsc --noEmit", "lint": "eslint . --max-warnings 0", "prepublishOnly": "pnpm build", "dev": "vite build --watch" diff --git a/packages/pointer-editor-v2/src/components/InlineProblemViewer.tsx b/packages/pointer-editor-v2/src/components/InlineProblemViewer.tsx index 85fed13f..3c00212e 100644 --- a/packages/pointer-editor-v2/src/components/InlineProblemViewer.tsx +++ b/packages/pointer-editor-v2/src/components/InlineProblemViewer.tsx @@ -1,5 +1,3 @@ -/// - import '../index.css'; import 'katex/dist/katex.min.css'; import * as React from 'react'; diff --git a/packages/pointer-editor-v2/src/components/ProblemEditor.tsx b/packages/pointer-editor-v2/src/components/ProblemEditor.tsx index 8a02db9f..0b0fec69 100644 --- a/packages/pointer-editor-v2/src/components/ProblemEditor.tsx +++ b/packages/pointer-editor-v2/src/components/ProblemEditor.tsx @@ -23,4 +23,4 @@ export const ProblemEditor = ({ />
); -}; \ No newline at end of file +}; diff --git a/packages/pointer-editor-v2/src/components/ProblemEditorModal.tsx b/packages/pointer-editor-v2/src/components/ProblemEditorModal.tsx index ef4f202e..6d13efad 100644 --- a/packages/pointer-editor-v2/src/components/ProblemEditorModal.tsx +++ b/packages/pointer-editor-v2/src/components/ProblemEditorModal.tsx @@ -26,13 +26,15 @@ export const ProblemEditorModal = ({
+ className={`pointer-editor-root pointer-editor-modal-container fixed inset-0 flex h-full w-full items-center justify-center bg-black/30 backdrop-blur-[5px] ${isOpen ? 'modal-open' : 'modal-close'}`}>
e.stopPropagation()} - className={`max-h-[672px] flex h-full w-full max-w-[672px] flex-col rounded-[16px] bg-white shadow-2xl pointer-editor-modal-content ${isOpen ? 'modal-open' : 'modal-close'}`}> + className={`pointer-editor-modal-content flex h-full max-h-[672px] w-full max-w-[672px] flex-col rounded-[16px] bg-white shadow-2xl ${isOpen ? 'modal-open' : 'modal-close'}`}>
에디터
-
- -
diff --git a/packages/pointer-editor-v2/src/editor/PointerEditor.tsx b/packages/pointer-editor-v2/src/editor/PointerEditor.tsx index 421eb33d..09aa23c5 100644 --- a/packages/pointer-editor-v2/src/editor/PointerEditor.tsx +++ b/packages/pointer-editor-v2/src/editor/PointerEditor.tsx @@ -375,10 +375,7 @@ export function PointerEditor({ : {}), }}> {mobileView === 'main' ? ( - + ) : ( ) => { return ( + viewBox='0 0 24 24' + fill='currentColor' + xmlns='http://www.w3.org/2000/svg' + {...props}> - ) + ); } -) +); -AlignCenterIcon.displayName = "AlignCenterIcon" +AlignCenterIcon.displayName = 'AlignCenterIcon'; diff --git a/packages/pointer-editor-v2/src/editor/assets/icon/AlignJustifyIcon.tsx b/packages/pointer-editor-v2/src/editor/assets/icon/AlignJustifyIcon.tsx index e43b3540..1acf23dc 100644 --- a/packages/pointer-editor-v2/src/editor/assets/icon/AlignJustifyIcon.tsx +++ b/packages/pointer-editor-v2/src/editor/assets/icon/AlignJustifyIcon.tsx @@ -1,38 +1,37 @@ -import * as React from "react" +import * as React from 'react'; export const AlignJustifyIcon = React.memo( ({ className, ...props }: React.SVGProps) => { return ( + viewBox='0 0 24 24' + fill='currentColor' + xmlns='http://www.w3.org/2000/svg' + {...props}> - ) + ); } -) +); -AlignJustifyIcon.displayName = "AlignJustifyIcon" +AlignJustifyIcon.displayName = 'AlignJustifyIcon'; diff --git a/packages/pointer-editor-v2/src/editor/assets/icon/AlignRightIcon.tsx b/packages/pointer-editor-v2/src/editor/assets/icon/AlignRightIcon.tsx index af832df4..54671aa1 100644 --- a/packages/pointer-editor-v2/src/editor/assets/icon/AlignRightIcon.tsx +++ b/packages/pointer-editor-v2/src/editor/assets/icon/AlignRightIcon.tsx @@ -1,38 +1,37 @@ -import * as React from "react" +import * as React from 'react'; export const AlignRightIcon = React.memo( ({ className, ...props }: React.SVGProps) => { return ( + viewBox='0 0 24 24' + fill='currentColor' + xmlns='http://www.w3.org/2000/svg' + {...props}> - ) + ); } -) +); -AlignRightIcon.displayName = "AlignRightIcon" +AlignRightIcon.displayName = 'AlignRightIcon'; diff --git a/packages/pointer-editor-v2/src/editor/assets/icon/ArrowLeftIcon.tsx b/packages/pointer-editor-v2/src/editor/assets/icon/ArrowLeftIcon.tsx index e206c681..918ba0b3 100644 --- a/packages/pointer-editor-v2/src/editor/assets/icon/ArrowLeftIcon.tsx +++ b/packages/pointer-editor-v2/src/editor/assets/icon/ArrowLeftIcon.tsx @@ -1,24 +1,23 @@ -import * as React from "react" +import * as React from 'react'; export const ArrowLeftIcon = React.memo( ({ className, ...props }: React.SVGProps) => { return ( + viewBox='0 0 24 24' + fill='currentColor' + xmlns='http://www.w3.org/2000/svg' + {...props}> - ) + ); } -) +); -ArrowLeftIcon.displayName = "ArrowLeftIcon" +ArrowLeftIcon.displayName = 'ArrowLeftIcon'; diff --git a/packages/pointer-editor-v2/src/editor/assets/icon/BanIcon.tsx b/packages/pointer-editor-v2/src/editor/assets/icon/BanIcon.tsx index 052f8ecb..27c32215 100644 --- a/packages/pointer-editor-v2/src/editor/assets/icon/BanIcon.tsx +++ b/packages/pointer-editor-v2/src/editor/assets/icon/BanIcon.tsx @@ -1,26 +1,23 @@ -import * as React from "react" +import * as React from 'react'; -export const BanIcon = React.memo( - ({ className, ...props }: React.SVGProps) => { - return ( - - - - ) - } -) +export const BanIcon = React.memo(({ className, ...props }: React.SVGProps) => { + return ( + + + + ); +}); -BanIcon.displayName = "BanIcon" +BanIcon.displayName = 'BanIcon'; diff --git a/packages/pointer-editor-v2/src/editor/assets/icon/BoldIcon.tsx b/packages/pointer-editor-v2/src/editor/assets/icon/BoldIcon.tsx index 33840fd5..78c7bad9 100644 --- a/packages/pointer-editor-v2/src/editor/assets/icon/BoldIcon.tsx +++ b/packages/pointer-editor-v2/src/editor/assets/icon/BoldIcon.tsx @@ -1,26 +1,23 @@ -import * as React from "react" +import * as React from 'react'; -export const BoldIcon = React.memo( - ({ className, ...props }: React.SVGProps) => { - return ( - - - - ) - } -) +export const BoldIcon = React.memo(({ className, ...props }: React.SVGProps) => { + return ( + + + + ); +}); -BoldIcon.displayName = "BoldIcon" +BoldIcon.displayName = 'BoldIcon'; diff --git a/packages/pointer-editor-v2/src/editor/assets/icon/ChevronDownIcon.tsx b/packages/pointer-editor-v2/src/editor/assets/icon/ChevronDownIcon.tsx index 36c09b05..62d0a337 100644 --- a/packages/pointer-editor-v2/src/editor/assets/icon/ChevronDownIcon.tsx +++ b/packages/pointer-editor-v2/src/editor/assets/icon/ChevronDownIcon.tsx @@ -1,26 +1,25 @@ -import * as React from "react" +import * as React from 'react'; export const ChevronDownIcon = React.memo( ({ className, ...props }: React.SVGProps) => { return ( + viewBox='0 0 24 24' + fill='currentColor' + xmlns='http://www.w3.org/2000/svg' + {...props}> - ) + ); } -) +); -ChevronDownIcon.displayName = "ChevronDownIcon" +ChevronDownIcon.displayName = 'ChevronDownIcon'; diff --git a/packages/pointer-editor-v2/src/editor/assets/icon/CloseIcon.tsx b/packages/pointer-editor-v2/src/editor/assets/icon/CloseIcon.tsx index 5fce8134..c21ea5ad 100644 --- a/packages/pointer-editor-v2/src/editor/assets/icon/CloseIcon.tsx +++ b/packages/pointer-editor-v2/src/editor/assets/icon/CloseIcon.tsx @@ -1,24 +1,21 @@ -import * as React from "react" +import * as React from 'react'; -export const CloseIcon = React.memo( - ({ className, ...props }: React.SVGProps) => { - return ( - - - - ) - } -) +export const CloseIcon = React.memo(({ className, ...props }: React.SVGProps) => { + return ( + + + + ); +}); -CloseIcon.displayName = "CloseIcon" +CloseIcon.displayName = 'CloseIcon'; diff --git a/packages/pointer-editor-v2/src/editor/assets/icon/Code2Icon.tsx b/packages/pointer-editor-v2/src/editor/assets/icon/Code2Icon.tsx index 40921706..462dbdce 100644 --- a/packages/pointer-editor-v2/src/editor/assets/icon/Code2Icon.tsx +++ b/packages/pointer-editor-v2/src/editor/assets/icon/Code2Icon.tsx @@ -1,32 +1,29 @@ -import * as React from "react" +import * as React from 'react'; -export const Code2Icon = React.memo( - ({ className, ...props }: React.SVGProps) => { - return ( - - - - - - ) - } -) +export const Code2Icon = React.memo(({ className, ...props }: React.SVGProps) => { + return ( + + + + + + ); +}); -Code2Icon.displayName = "Code2Icon" +Code2Icon.displayName = 'Code2Icon'; diff --git a/packages/pointer-editor-v2/src/editor/assets/icon/CodeBlockIcon.tsx b/packages/pointer-editor-v2/src/editor/assets/icon/CodeBlockIcon.tsx index 12027f1a..a7e8d51d 100644 --- a/packages/pointer-editor-v2/src/editor/assets/icon/CodeBlockIcon.tsx +++ b/packages/pointer-editor-v2/src/editor/assets/icon/CodeBlockIcon.tsx @@ -1,38 +1,37 @@ -import * as React from "react" +import * as React from 'react'; export const CodeBlockIcon = React.memo( ({ className, ...props }: React.SVGProps) => { return ( + viewBox='0 0 24 24' + fill='currentColor' + xmlns='http://www.w3.org/2000/svg' + {...props}> - ) + ); } -) +); -CodeBlockIcon.displayName = "CodeBlockIcon" +CodeBlockIcon.displayName = 'CodeBlockIcon'; diff --git a/packages/pointer-editor-v2/src/editor/assets/icon/CornerDownLeftIcon.tsx b/packages/pointer-editor-v2/src/editor/assets/icon/CornerDownLeftIcon.tsx index a739cca8..49ca0cfc 100644 --- a/packages/pointer-editor-v2/src/editor/assets/icon/CornerDownLeftIcon.tsx +++ b/packages/pointer-editor-v2/src/editor/assets/icon/CornerDownLeftIcon.tsx @@ -1,26 +1,25 @@ -import * as React from "react" +import * as React from 'react'; export const CornerDownLeftIcon = React.memo( ({ className, ...props }: React.SVGProps) => { return ( + viewBox='0 0 24 24' + fill='currentColor' + xmlns='http://www.w3.org/2000/svg' + {...props}> - ) + ); } -) +); -CornerDownLeftIcon.displayName = "CornerDownLeftIcon" +CornerDownLeftIcon.displayName = 'CornerDownLeftIcon'; diff --git a/packages/pointer-editor-v2/src/editor/assets/icon/ExternalLinkIcon.tsx b/packages/pointer-editor-v2/src/editor/assets/icon/ExternalLinkIcon.tsx index cfe92b47..7b409509 100644 --- a/packages/pointer-editor-v2/src/editor/assets/icon/ExternalLinkIcon.tsx +++ b/packages/pointer-editor-v2/src/editor/assets/icon/ExternalLinkIcon.tsx @@ -1,28 +1,27 @@ -import * as React from "react" +import * as React from 'react'; export const ExternalLinkIcon = React.memo( ({ className, ...props }: React.SVGProps) => { return ( + viewBox='0 0 24 24' + fill='currentColor' + xmlns='http://www.w3.org/2000/svg' + {...props}> - ) + ); } -) +); -ExternalLinkIcon.displayName = "ExternalLinkIcon" +ExternalLinkIcon.displayName = 'ExternalLinkIcon'; diff --git a/packages/pointer-editor-v2/src/editor/assets/icon/HighlighterIcon.tsx b/packages/pointer-editor-v2/src/editor/assets/icon/HighlighterIcon.tsx index edc5a67b..3333bd98 100644 --- a/packages/pointer-editor-v2/src/editor/assets/icon/HighlighterIcon.tsx +++ b/packages/pointer-editor-v2/src/editor/assets/icon/HighlighterIcon.tsx @@ -1,26 +1,25 @@ -import * as React from "react" +import * as React from 'react'; export const HighlighterIcon = React.memo( ({ className, ...props }: React.SVGProps) => { return ( + viewBox='0 0 24 24' + fill='currentColor' + xmlns='http://www.w3.org/2000/svg' + {...props}> - ) + ); } -) +); -HighlighterIcon.displayName = "HighlighterIcon" +HighlighterIcon.displayName = 'HighlighterIcon'; diff --git a/packages/pointer-editor-v2/src/editor/assets/icon/ImagePlusIcon.tsx b/packages/pointer-editor-v2/src/editor/assets/icon/ImagePlusIcon.tsx index 5184d3d4..c379adf6 100644 --- a/packages/pointer-editor-v2/src/editor/assets/icon/ImagePlusIcon.tsx +++ b/packages/pointer-editor-v2/src/editor/assets/icon/ImagePlusIcon.tsx @@ -1,26 +1,25 @@ -import * as React from "react" +import * as React from 'react'; export const ImagePlusIcon = React.memo( ({ className, ...props }: React.SVGProps) => { return ( + viewBox='0 0 24 24' + fill='currentColor' + xmlns='http://www.w3.org/2000/svg' + {...props}> - ) + ); } -) +); -ImagePlusIcon.displayName = "ImagePlusIcon" +ImagePlusIcon.displayName = 'ImagePlusIcon'; diff --git a/packages/pointer-editor-v2/src/editor/assets/icon/ItalicIcon.tsx b/packages/pointer-editor-v2/src/editor/assets/icon/ItalicIcon.tsx index 7d7a79eb..ec0e8468 100644 --- a/packages/pointer-editor-v2/src/editor/assets/icon/ItalicIcon.tsx +++ b/packages/pointer-editor-v2/src/editor/assets/icon/ItalicIcon.tsx @@ -1,24 +1,21 @@ -import * as React from "react" +import * as React from 'react'; -export const ItalicIcon = React.memo( - ({ className, ...props }: React.SVGProps) => { - return ( - - - - ) - } -) +export const ItalicIcon = React.memo(({ className, ...props }: React.SVGProps) => { + return ( + + + + ); +}); -ItalicIcon.displayName = "ItalicIcon" +ItalicIcon.displayName = 'ItalicIcon'; diff --git a/packages/pointer-editor-v2/src/editor/assets/icon/LinkIcon.tsx b/packages/pointer-editor-v2/src/editor/assets/icon/LinkIcon.tsx index f653770f..02b4c262 100644 --- a/packages/pointer-editor-v2/src/editor/assets/icon/LinkIcon.tsx +++ b/packages/pointer-editor-v2/src/editor/assets/icon/LinkIcon.tsx @@ -1,28 +1,25 @@ -import * as React from "react" +import * as React from 'react'; -export const LinkIcon = React.memo( - ({ className, ...props }: React.SVGProps) => { - return ( - - - - - ) - } -) +export const LinkIcon = React.memo(({ className, ...props }: React.SVGProps) => { + return ( + + + + + ); +}); -LinkIcon.displayName = "LinkIcon" +LinkIcon.displayName = 'LinkIcon'; diff --git a/packages/pointer-editor-v2/src/editor/assets/icon/ListIcon.tsx b/packages/pointer-editor-v2/src/editor/assets/icon/ListIcon.tsx index 046830c0..b11edd1d 100644 --- a/packages/pointer-editor-v2/src/editor/assets/icon/ListIcon.tsx +++ b/packages/pointer-editor-v2/src/editor/assets/icon/ListIcon.tsx @@ -1,56 +1,53 @@ -import * as React from "react" +import * as React from 'react'; -export const ListIcon = React.memo( - ({ className, ...props }: React.SVGProps) => { - return ( - - - - - - - - - ) - } -) +export const ListIcon = React.memo(({ className, ...props }: React.SVGProps) => { + return ( + + + + + + + + + ); +}); -ListIcon.displayName = "ListIcon" +ListIcon.displayName = 'ListIcon'; diff --git a/packages/pointer-editor-v2/src/editor/assets/icon/ListOrderedIcon.tsx b/packages/pointer-editor-v2/src/editor/assets/icon/ListOrderedIcon.tsx index ca153d13..249b7b33 100644 --- a/packages/pointer-editor-v2/src/editor/assets/icon/ListOrderedIcon.tsx +++ b/packages/pointer-editor-v2/src/editor/assets/icon/ListOrderedIcon.tsx @@ -1,56 +1,55 @@ -import * as React from "react" +import * as React from 'react'; export const ListOrderedIcon = React.memo( ({ className, ...props }: React.SVGProps) => { return ( + viewBox='0 0 24 24' + fill='currentColor' + xmlns='http://www.w3.org/2000/svg' + {...props}> - ) + ); } -) +); -ListOrderedIcon.displayName = "ListOrderedIcon" +ListOrderedIcon.displayName = 'ListOrderedIcon'; diff --git a/packages/pointer-editor-v2/src/editor/assets/icon/ListTodoIcon.tsx b/packages/pointer-editor-v2/src/editor/assets/icon/ListTodoIcon.tsx index 61c3d61b..66435aab 100644 --- a/packages/pointer-editor-v2/src/editor/assets/icon/ListTodoIcon.tsx +++ b/packages/pointer-editor-v2/src/editor/assets/icon/ListTodoIcon.tsx @@ -1,50 +1,47 @@ -import * as React from "react" +import * as React from 'react'; -export const ListTodoIcon = React.memo( - ({ className, ...props }: React.SVGProps) => { - return ( - - - - - - - - ) - } -) +export const ListTodoIcon = React.memo(({ className, ...props }: React.SVGProps) => { + return ( + + + + + + + + ); +}); -ListTodoIcon.displayName = "ListTodoIcon" +ListTodoIcon.displayName = 'ListTodoIcon'; diff --git a/packages/pointer-editor-v2/src/editor/assets/icon/MoonStarIcon.tsx b/packages/pointer-editor-v2/src/editor/assets/icon/MoonStarIcon.tsx index a49f02c1..a1ea730d 100644 --- a/packages/pointer-editor-v2/src/editor/assets/icon/MoonStarIcon.tsx +++ b/packages/pointer-editor-v2/src/editor/assets/icon/MoonStarIcon.tsx @@ -1,30 +1,27 @@ -import * as React from "react" +import * as React from 'react'; -export const MoonStarIcon = React.memo( - ({ className, ...props }: React.SVGProps) => { - return ( - - - - - ) - } -) +export const MoonStarIcon = React.memo(({ className, ...props }: React.SVGProps) => { + return ( + + + + + ); +}); -MoonStarIcon.displayName = "MoonStarIcon" +MoonStarIcon.displayName = 'MoonStarIcon'; diff --git a/packages/pointer-editor-v2/src/editor/assets/icon/Redo2Icon.tsx b/packages/pointer-editor-v2/src/editor/assets/icon/Redo2Icon.tsx index 2b7760fa..34657287 100644 --- a/packages/pointer-editor-v2/src/editor/assets/icon/Redo2Icon.tsx +++ b/packages/pointer-editor-v2/src/editor/assets/icon/Redo2Icon.tsx @@ -1,26 +1,23 @@ -import * as React from "react" +import * as React from 'react'; -export const Redo2Icon = React.memo( - ({ className, ...props }: React.SVGProps) => { - return ( - - - - ) - } -) +export const Redo2Icon = React.memo(({ className, ...props }: React.SVGProps) => { + return ( + + + + ); +}); -Redo2Icon.displayName = "Redo2Icon" +Redo2Icon.displayName = 'Redo2Icon'; diff --git a/packages/pointer-editor-v2/src/editor/assets/icon/StrikeIcon.tsx b/packages/pointer-editor-v2/src/editor/assets/icon/StrikeIcon.tsx index 6616929d..2cca3a2a 100644 --- a/packages/pointer-editor-v2/src/editor/assets/icon/StrikeIcon.tsx +++ b/packages/pointer-editor-v2/src/editor/assets/icon/StrikeIcon.tsx @@ -1,28 +1,25 @@ -import * as React from "react" +import * as React from 'react'; -export const StrikeIcon = React.memo( - ({ className, ...props }: React.SVGProps) => { - return ( - - - - - ) - } -) +export const StrikeIcon = React.memo(({ className, ...props }: React.SVGProps) => { + return ( + + + + + ); +}); -StrikeIcon.displayName = "StrikeIcon" +StrikeIcon.displayName = 'StrikeIcon'; diff --git a/packages/pointer-editor-v2/src/editor/assets/icon/SubscriptIcon.tsx b/packages/pointer-editor-v2/src/editor/assets/icon/SubscriptIcon.tsx index 5d1d11d3..effd1ec6 100644 --- a/packages/pointer-editor-v2/src/editor/assets/icon/SubscriptIcon.tsx +++ b/packages/pointer-editor-v2/src/editor/assets/icon/SubscriptIcon.tsx @@ -1,38 +1,37 @@ -import * as React from "react" +import * as React from 'react'; export const SubscriptIcon = React.memo( ({ className, ...props }: React.SVGProps) => { return ( + viewBox='0 0 24 24' + fill='currentColor' + xmlns='http://www.w3.org/2000/svg' + {...props}> - ) + ); } -) +); -SubscriptIcon.displayName = "SubscriptIcon" +SubscriptIcon.displayName = 'SubscriptIcon'; diff --git a/packages/pointer-editor-v2/src/editor/assets/icon/SunIcon.tsx b/packages/pointer-editor-v2/src/editor/assets/icon/SunIcon.tsx index 25c6cb4e..3abb6cfa 100644 --- a/packages/pointer-editor-v2/src/editor/assets/icon/SunIcon.tsx +++ b/packages/pointer-editor-v2/src/editor/assets/icon/SunIcon.tsx @@ -1,58 +1,55 @@ -import * as React from "react" +import * as React from 'react'; -export const SunIcon = React.memo( - ({ className, ...props }: React.SVGProps) => { - return ( - - - - - - - - - - - - ) - } -) +export const SunIcon = React.memo(({ className, ...props }: React.SVGProps) => { + return ( + + + + + + + + + + + + ); +}); -SunIcon.displayName = "SunIcon" +SunIcon.displayName = 'SunIcon'; diff --git a/packages/pointer-editor-v2/src/editor/assets/icon/TrashIcon.tsx b/packages/pointer-editor-v2/src/editor/assets/icon/TrashIcon.tsx index d928994e..8701df76 100644 --- a/packages/pointer-editor-v2/src/editor/assets/icon/TrashIcon.tsx +++ b/packages/pointer-editor-v2/src/editor/assets/icon/TrashIcon.tsx @@ -1,26 +1,23 @@ -import * as React from "react" +import * as React from 'react'; -export const TrashIcon = React.memo( - ({ className, ...props }: React.SVGProps) => { - return ( - - - - ) - } -) +export const TrashIcon = React.memo(({ className, ...props }: React.SVGProps) => { + return ( + + + + ); +}); -TrashIcon.displayName = "TrashIcon" +TrashIcon.displayName = 'TrashIcon'; diff --git a/packages/pointer-editor-v2/src/editor/assets/icon/UnderlineIcon.tsx b/packages/pointer-editor-v2/src/editor/assets/icon/UnderlineIcon.tsx index 8563129c..f71c8bf3 100644 --- a/packages/pointer-editor-v2/src/editor/assets/icon/UnderlineIcon.tsx +++ b/packages/pointer-editor-v2/src/editor/assets/icon/UnderlineIcon.tsx @@ -1,26 +1,25 @@ -import * as React from "react" +import * as React from 'react'; export const UnderlineIcon = React.memo( ({ className, ...props }: React.SVGProps) => { return ( + viewBox='0 0 24 24' + fill='currentColor' + xmlns='http://www.w3.org/2000/svg' + {...props}> - ) + ); } -) +); -UnderlineIcon.displayName = "UnderlineIcon" +UnderlineIcon.displayName = 'UnderlineIcon'; diff --git a/packages/pointer-editor-v2/src/editor/assets/icon/Undo2Icon.tsx b/packages/pointer-editor-v2/src/editor/assets/icon/Undo2Icon.tsx index bef8d3d7..5aebf9f1 100644 --- a/packages/pointer-editor-v2/src/editor/assets/icon/Undo2Icon.tsx +++ b/packages/pointer-editor-v2/src/editor/assets/icon/Undo2Icon.tsx @@ -1,26 +1,23 @@ -import * as React from "react" +import * as React from 'react'; -export const Undo2Icon = React.memo( - ({ className, ...props }: React.SVGProps) => { - return ( - - - - ) - } -) +export const Undo2Icon = React.memo(({ className, ...props }: React.SVGProps) => { + return ( + + + + ); +}); -Undo2Icon.displayName = "Undo2Icon" +Undo2Icon.displayName = 'Undo2Icon'; diff --git a/packages/pointer-editor-v2/src/editor/assets/index.ts b/packages/pointer-editor-v2/src/editor/assets/index.ts index 870bbf65..af77d84e 100644 --- a/packages/pointer-editor-v2/src/editor/assets/index.ts +++ b/packages/pointer-editor-v2/src/editor/assets/index.ts @@ -1 +1 @@ -export * from './icon'; \ No newline at end of file +export * from './icon'; diff --git a/packages/pointer-editor-v2/src/editor/extensions/image-paste-upload.ts b/packages/pointer-editor-v2/src/editor/extensions/image-paste-upload.ts index 2afed710..efe5cf98 100644 --- a/packages/pointer-editor-v2/src/editor/extensions/image-paste-upload.ts +++ b/packages/pointer-editor-v2/src/editor/extensions/image-paste-upload.ts @@ -40,15 +40,17 @@ export const ImagePasteUpload = Extension.create({ for (const file of images) { const pos = view.state.selection.from; - upload(file).then((url) => { - const imageNode = view.state.schema.nodes.image; - if (!imageNode) return; - const node = imageNode.create({ src: url }); - const tr = view.state.tr.insert(pos, node); - view.dispatch(tr); - }).catch((err) => { - console.error('Paste image upload failed:', err); - }); + upload(file) + .then((url) => { + const imageNode = view.state.schema.nodes.image; + if (!imageNode) return; + const node = imageNode.create({ src: url }); + const tr = view.state.tr.insert(pos, node); + view.dispatch(tr); + }) + .catch((err) => { + console.error('Paste image upload failed:', err); + }); } return true; diff --git a/packages/pointer-editor-v2/src/editor/nodes/horizontal-rule-node/horizontal-rule-node-extension.ts b/packages/pointer-editor-v2/src/editor/nodes/horizontal-rule-node/horizontal-rule-node-extension.ts index de282086..25b7bc35 100644 --- a/packages/pointer-editor-v2/src/editor/nodes/horizontal-rule-node/horizontal-rule-node-extension.ts +++ b/packages/pointer-editor-v2/src/editor/nodes/horizontal-rule-node/horizontal-rule-node-extension.ts @@ -1,14 +1,14 @@ -import { mergeAttributes } from "@tiptap/react" -import TiptapHorizontalRule from "@tiptap/extension-horizontal-rule" +import { mergeAttributes } from '@tiptap/react'; +import TiptapHorizontalRule from '@tiptap/extension-horizontal-rule'; export const HorizontalRule = TiptapHorizontalRule.extend({ renderHTML() { return [ - "div", - mergeAttributes(this.options.HTMLAttributes, { "data-type": this.name }), - ["hr"], - ] + 'div', + mergeAttributes(this.options.HTMLAttributes, { 'data-type': this.name }), + ['hr'], + ]; }, -}) +}); -export default HorizontalRule +export default HorizontalRule; diff --git a/packages/pointer-editor-v2/src/editor/nodes/image-ocr-node/image-ocr-node-extension.ts b/packages/pointer-editor-v2/src/editor/nodes/image-ocr-node/image-ocr-node-extension.ts index 612913f9..5935a941 100644 --- a/packages/pointer-editor-v2/src/editor/nodes/image-ocr-node/image-ocr-node-extension.ts +++ b/packages/pointer-editor-v2/src/editor/nodes/image-ocr-node/image-ocr-node-extension.ts @@ -82,7 +82,7 @@ export const ImageOCRNode = Node.create({ upload: undefined, onError: undefined, onSuccess: undefined, - ocrApiCall: async () => ({}) as unknown as ((data: any) => Promise), // eslint-disable-line @typescript-eslint/no-explicit-any + ocrApiCall: async () => ({}) as unknown as (data: any) => Promise, // eslint-disable-line @typescript-eslint/no-explicit-any HTMLAttributes: {}, }; }, diff --git a/packages/pointer-editor-v2/src/editor/nodes/image-ocr-node/image-ocr-node.tsx b/packages/pointer-editor-v2/src/editor/nodes/image-ocr-node/image-ocr-node.tsx index e7006904..c13d5ee6 100644 --- a/packages/pointer-editor-v2/src/editor/nodes/image-ocr-node/image-ocr-node.tsx +++ b/packages/pointer-editor-v2/src/editor/nodes/image-ocr-node/image-ocr-node.tsx @@ -266,15 +266,18 @@ export const ImageOCRNode: React.FC = (props) => { const inputRef = React.useRef(null); const extension = props.extension; - const uploadOptions: UploadOptions = { - maxSize, - limit, - accept, - upload: extension.options.upload, - onSuccess: extension.options.onSuccess, - onError: extension.options.onError, - ocrApiCall: extension.options.ocrApiCall, - }; + const uploadOptions: UploadOptions = React.useMemo( + () => ({ + maxSize, + limit, + accept, + upload: extension.options.upload, + onSuccess: extension.options.onSuccess, + onError: extension.options.onError, + ocrApiCall: extension.options.ocrApiCall, + }), + [maxSize, limit, accept, extension.options] + ); const { fileItems, uploadFiles, removeFileItem, clearAllFiles } = useFileUpload(uploadOptions); diff --git a/packages/pointer-editor-v2/src/editor/nodes/image-upload-node/index.ts b/packages/pointer-editor-v2/src/editor/nodes/image-upload-node/index.ts index 2510a62f..8d4d9201 100644 --- a/packages/pointer-editor-v2/src/editor/nodes/image-upload-node/index.ts +++ b/packages/pointer-editor-v2/src/editor/nodes/image-upload-node/index.ts @@ -1 +1 @@ -export * from "./image-upload-node-extension" +export * from './image-upload-node-extension'; diff --git a/packages/pointer-editor-v2/src/editor/ui/answer-box-dropdown-menu/AnswerBoxDropdownMenu.tsx b/packages/pointer-editor-v2/src/editor/ui/answer-box-dropdown-menu/AnswerBoxDropdownMenu.tsx index 9fc1d5b5..68d9a30b 100644 --- a/packages/pointer-editor-v2/src/editor/ui/answer-box-dropdown-menu/AnswerBoxDropdownMenu.tsx +++ b/packages/pointer-editor-v2/src/editor/ui/answer-box-dropdown-menu/AnswerBoxDropdownMenu.tsx @@ -25,8 +25,7 @@ import { } from '../base'; export interface AnswerBoxDropdownMenuProps - extends Omit, - UseAnswerBoxDropdownMenuConfig { + extends Omit, UseAnswerBoxDropdownMenuConfig { /** * Whether to render the dropdown menu in a portal * @default false diff --git a/packages/pointer-editor-v2/src/editor/ui/base/badge/Badge.tsx b/packages/pointer-editor-v2/src/editor/ui/base/badge/Badge.tsx index 2fc4df44..ee15a3ac 100644 --- a/packages/pointer-editor-v2/src/editor/ui/base/badge/Badge.tsx +++ b/packages/pointer-editor-v2/src/editor/ui/base/badge/Badge.tsx @@ -1,21 +1,21 @@ -import * as React from "react" -import "./badge-colors.scss" -import "./badge-group.scss" -import "./badge.scss" +import * as React from 'react'; +import './badge-colors.scss'; +import './badge-group.scss'; +import './badge.scss'; export interface BadgeProps extends React.HTMLAttributes { - variant?: "ghost" | "white" | "gray" | "green" | "default" - size?: "default" | "small" - appearance?: "default" | "subdued" | "emphasized" - trimText?: boolean + variant?: 'ghost' | 'white' | 'gray' | 'green' | 'default'; + size?: 'default' | 'small'; + appearance?: 'default' | 'subdued' | 'emphasized'; + trimText?: boolean; } export const Badge = React.forwardRef( ( { variant, - size = "default", - appearance = "default", + size = 'default', + appearance = 'default', trimText = false, className, children, @@ -26,19 +26,18 @@ export const Badge = React.forwardRef( return (
+ data-text-trim={trimText ? 'on' : 'off'} + {...props}> {children}
- ) + ); } -) +); -Badge.displayName = "Badge" +Badge.displayName = 'Badge'; -export default Badge +export default Badge; diff --git a/packages/pointer-editor-v2/src/editor/ui/base/badge/index.ts b/packages/pointer-editor-v2/src/editor/ui/base/badge/index.ts index 9d37d5fc..9c8edca2 100644 --- a/packages/pointer-editor-v2/src/editor/ui/base/badge/index.ts +++ b/packages/pointer-editor-v2/src/editor/ui/base/badge/index.ts @@ -1 +1 @@ -export * from "./Badge" +export * from './Badge'; diff --git a/packages/pointer-editor-v2/src/editor/ui/base/button/index.ts b/packages/pointer-editor-v2/src/editor/ui/base/button/index.ts index 67837012..8b166a86 100644 --- a/packages/pointer-editor-v2/src/editor/ui/base/button/index.ts +++ b/packages/pointer-editor-v2/src/editor/ui/base/button/index.ts @@ -1 +1 @@ -export * from "./Button" +export * from './Button'; diff --git a/packages/pointer-editor-v2/src/editor/ui/base/card/index.ts b/packages/pointer-editor-v2/src/editor/ui/base/card/index.ts index 1ae2698c..ca0b0604 100644 --- a/packages/pointer-editor-v2/src/editor/ui/base/card/index.ts +++ b/packages/pointer-editor-v2/src/editor/ui/base/card/index.ts @@ -1 +1 @@ -export * from "./Card" +export * from './Card'; diff --git a/packages/pointer-editor-v2/src/editor/ui/base/dropdown-menu/index.ts b/packages/pointer-editor-v2/src/editor/ui/base/dropdown-menu/index.ts index 669b8f29..8aadf2fa 100644 --- a/packages/pointer-editor-v2/src/editor/ui/base/dropdown-menu/index.ts +++ b/packages/pointer-editor-v2/src/editor/ui/base/dropdown-menu/index.ts @@ -1 +1 @@ -export * from "./DropdownMenu" +export * from './DropdownMenu'; diff --git a/packages/pointer-editor-v2/src/editor/ui/base/input/index.ts b/packages/pointer-editor-v2/src/editor/ui/base/input/index.ts index bdc4010c..ba9fe7eb 100644 --- a/packages/pointer-editor-v2/src/editor/ui/base/input/index.ts +++ b/packages/pointer-editor-v2/src/editor/ui/base/input/index.ts @@ -1 +1 @@ -export * from "./Input" +export * from './Input'; diff --git a/packages/pointer-editor-v2/src/editor/ui/base/popover/index.ts b/packages/pointer-editor-v2/src/editor/ui/base/popover/index.ts index 00be84b7..8f473de4 100644 --- a/packages/pointer-editor-v2/src/editor/ui/base/popover/index.ts +++ b/packages/pointer-editor-v2/src/editor/ui/base/popover/index.ts @@ -1 +1 @@ -export * from "./Popover" +export * from './Popover'; diff --git a/packages/pointer-editor-v2/src/editor/ui/base/separator/index.ts b/packages/pointer-editor-v2/src/editor/ui/base/separator/index.ts index 15d30a45..6e974799 100644 --- a/packages/pointer-editor-v2/src/editor/ui/base/separator/index.ts +++ b/packages/pointer-editor-v2/src/editor/ui/base/separator/index.ts @@ -1 +1 @@ -export * from "./Separator" +export * from './Separator'; diff --git a/packages/pointer-editor-v2/src/editor/ui/base/spacer/Spacer.tsx b/packages/pointer-editor-v2/src/editor/ui/base/spacer/Spacer.tsx index 8de96002..1c00d775 100644 --- a/packages/pointer-editor-v2/src/editor/ui/base/spacer/Spacer.tsx +++ b/packages/pointer-editor-v2/src/editor/ui/base/spacer/Spacer.tsx @@ -1,28 +1,23 @@ -"use client" +'use client'; -import * as React from "react" +import * as React from 'react'; -export type SpacerOrientation = "horizontal" | "vertical" +export type SpacerOrientation = 'horizontal' | 'vertical'; export interface SpacerProps extends React.HTMLAttributes { - orientation?: SpacerOrientation - size?: string | number + orientation?: SpacerOrientation; + size?: string | number; } -export function Spacer({ - orientation = "horizontal", - size, - style = {}, - ...props -}: SpacerProps) { +export function Spacer({ orientation = 'horizontal', size, style = {}, ...props }: SpacerProps) { const computedStyle = { ...style, - ...(orientation === "horizontal" && !size && { flex: 1 }), + ...(orientation === 'horizontal' && !size && { flex: 1 }), ...(size && { - width: orientation === "vertical" ? "1px" : size, - height: orientation === "horizontal" ? "1px" : size, + width: orientation === 'vertical' ? '1px' : size, + height: orientation === 'horizontal' ? '1px' : size, }), - } + }; - return
+ return
; } diff --git a/packages/pointer-editor-v2/src/editor/ui/base/spacer/index.ts b/packages/pointer-editor-v2/src/editor/ui/base/spacer/index.ts index 4775c3c4..fb621457 100644 --- a/packages/pointer-editor-v2/src/editor/ui/base/spacer/index.ts +++ b/packages/pointer-editor-v2/src/editor/ui/base/spacer/index.ts @@ -1 +1 @@ -export * from "./Spacer" +export * from './Spacer'; diff --git a/packages/pointer-editor-v2/src/editor/ui/base/toolbar/Toolbar.tsx b/packages/pointer-editor-v2/src/editor/ui/base/toolbar/Toolbar.tsx index ab431900..05e3f17d 100644 --- a/packages/pointer-editor-v2/src/editor/ui/base/toolbar/Toolbar.tsx +++ b/packages/pointer-editor-v2/src/editor/ui/base/toolbar/Toolbar.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { Separator } from '../separator'; import './toolbar.scss'; import { cn } from '../../../utils'; -import { useMenuNavigation, useComposedRef } from '../../../hooks'; +import { useMenuNavigation, useComposedRef } from '../../../hooks'; type BaseProps = React.HTMLAttributes; diff --git a/packages/pointer-editor-v2/src/editor/ui/base/toolbar/index.ts b/packages/pointer-editor-v2/src/editor/ui/base/toolbar/index.ts index 462ff9f1..7c643033 100644 --- a/packages/pointer-editor-v2/src/editor/ui/base/toolbar/index.ts +++ b/packages/pointer-editor-v2/src/editor/ui/base/toolbar/index.ts @@ -1 +1 @@ -export * from "./Toolbar" +export * from './Toolbar'; diff --git a/packages/pointer-editor-v2/src/editor/ui/base/tooltip/index.ts b/packages/pointer-editor-v2/src/editor/ui/base/tooltip/index.ts index f3f90275..7594a8f0 100644 --- a/packages/pointer-editor-v2/src/editor/ui/base/tooltip/index.ts +++ b/packages/pointer-editor-v2/src/editor/ui/base/tooltip/index.ts @@ -1 +1 @@ -export * from "./Tooltip" +export * from './Tooltip'; diff --git a/packages/pointer-editor-v2/src/editor/ui/blockquote-button/useBlockquote.ts b/packages/pointer-editor-v2/src/editor/ui/blockquote-button/useBlockquote.ts index ab018329..6f112b11 100644 --- a/packages/pointer-editor-v2/src/editor/ui/blockquote-button/useBlockquote.ts +++ b/packages/pointer-editor-v2/src/editor/ui/blockquote-button/useBlockquote.ts @@ -11,12 +11,7 @@ import { useTiptapEditor } from '../../hooks'; import { BlockquoteIcon } from '../../assets'; // --- UI Utils --- -import { - findNodePosition, - isNodeInSchema, - isNodeTypeSelected, - isValidPosition, -} from '../../utils'; +import { findNodePosition, isNodeInSchema, isNodeTypeSelected, isValidPosition } from '../../utils'; export const BLOCKQUOTE_SHORTCUT_KEY = 'mod+shift+b'; diff --git a/packages/pointer-editor-v2/src/editor/ui/code-block-button/useCodeBlock.ts b/packages/pointer-editor-v2/src/editor/ui/code-block-button/useCodeBlock.ts index d3988b8a..905e8ae8 100644 --- a/packages/pointer-editor-v2/src/editor/ui/code-block-button/useCodeBlock.ts +++ b/packages/pointer-editor-v2/src/editor/ui/code-block-button/useCodeBlock.ts @@ -8,12 +8,7 @@ import { NodeSelection, TextSelection } from '@tiptap/pm/state'; import { useTiptapEditor } from '../../hooks'; // --- Lib --- -import { - findNodePosition, - isNodeInSchema, - isNodeTypeSelected, - isValidPosition, -} from '../../utils'; +import { findNodePosition, isNodeInSchema, isNodeTypeSelected, isValidPosition } from '../../utils'; // --- Icons --- import { CodeBlockIcon } from '../../assets'; diff --git a/packages/pointer-editor-v2/src/editor/ui/color-highlight-button/ColorHighlightButton.tsx b/packages/pointer-editor-v2/src/editor/ui/color-highlight-button/ColorHighlightButton.tsx index 7c9c604d..1520f90e 100644 --- a/packages/pointer-editor-v2/src/editor/ui/color-highlight-button/ColorHighlightButton.tsx +++ b/packages/pointer-editor-v2/src/editor/ui/color-highlight-button/ColorHighlightButton.tsx @@ -18,8 +18,7 @@ import { Button, Badge } from '../base'; import './color-highlight-button.scss'; export interface ColorHighlightButtonProps - extends Omit, - UseColorHighlightConfig { + extends Omit, UseColorHighlightConfig { /** * Optional text to display alongside the icon. */ diff --git a/packages/pointer-editor-v2/src/editor/ui/color-highlight-popover/ColorHighlightPopover.tsx b/packages/pointer-editor-v2/src/editor/ui/color-highlight-popover/ColorHighlightPopover.tsx index 39a5b3c2..d0511dc4 100644 --- a/packages/pointer-editor-v2/src/editor/ui/color-highlight-popover/ColorHighlightPopover.tsx +++ b/packages/pointer-editor-v2/src/editor/ui/color-highlight-popover/ColorHighlightPopover.tsx @@ -42,7 +42,8 @@ export interface ColorHighlightPopoverContentProps { } export interface ColorHighlightPopoverProps - extends Omit, + extends + Omit, Pick { /** * Optional colors to use in the highlight popover. diff --git a/packages/pointer-editor-v2/src/editor/ui/heading-button/useHeading.ts b/packages/pointer-editor-v2/src/editor/ui/heading-button/useHeading.ts index f2bec94c..d2096d4c 100644 --- a/packages/pointer-editor-v2/src/editor/ui/heading-button/useHeading.ts +++ b/packages/pointer-editor-v2/src/editor/ui/heading-button/useHeading.ts @@ -8,12 +8,7 @@ import { NodeSelection, TextSelection } from '@tiptap/pm/state'; import { useTiptapEditor } from '../../hooks'; // --- Lib --- -import { - findNodePosition, - isNodeInSchema, - isNodeTypeSelected, - isValidPosition, -} from '../../utils'; +import { findNodePosition, isNodeInSchema, isNodeTypeSelected, isValidPosition } from '../../utils'; // --- Icons --- import { AnswerBoxOneColIcon, AnswerBoxThreeColsIcon, AnswerBoxFiveColsIcon } from '../../assets'; diff --git a/packages/pointer-editor-v2/src/editor/ui/heading-dropdown-menu/HeadingDropdownMenu.tsx b/packages/pointer-editor-v2/src/editor/ui/heading-dropdown-menu/HeadingDropdownMenu.tsx index 37e88ef9..6cffe228 100644 --- a/packages/pointer-editor-v2/src/editor/ui/heading-dropdown-menu/HeadingDropdownMenu.tsx +++ b/packages/pointer-editor-v2/src/editor/ui/heading-dropdown-menu/HeadingDropdownMenu.tsx @@ -25,8 +25,7 @@ import { } from '../base'; export interface HeadingDropdownMenuProps - extends Omit, - UseHeadingDropdownMenuConfig { + extends Omit, UseHeadingDropdownMenuConfig { /** * Whether to render the dropdown menu in a portal * @default false diff --git a/packages/pointer-editor-v2/src/editor/ui/image-ocr-button/index.ts b/packages/pointer-editor-v2/src/editor/ui/image-ocr-button/index.ts index 8469e188..4071104f 100644 --- a/packages/pointer-editor-v2/src/editor/ui/image-ocr-button/index.ts +++ b/packages/pointer-editor-v2/src/editor/ui/image-ocr-button/index.ts @@ -1 +1 @@ -export * from './ImageOCRButton'; \ No newline at end of file +export * from './ImageOCRButton'; diff --git a/packages/pointer-editor-v2/src/editor/ui/image-upload-button/ImageUploadButton.tsx b/packages/pointer-editor-v2/src/editor/ui/image-upload-button/ImageUploadButton.tsx index 94cf6490..307d87cb 100644 --- a/packages/pointer-editor-v2/src/editor/ui/image-upload-button/ImageUploadButton.tsx +++ b/packages/pointer-editor-v2/src/editor/ui/image-upload-button/ImageUploadButton.tsx @@ -43,6 +43,7 @@ export const ImageUploadButton = React.forwardRef