diff --git a/apps/extension/src/api/axios.ts b/apps/extension/src/api/axios.ts index e357869..9d957d1 100644 --- a/apps/extension/src/api/axios.ts +++ b/apps/extension/src/api/axios.ts @@ -14,3 +14,33 @@ export const postArticles = async (payload: { const response = await apiRequest.post('/api/v1/articles', payload); return response.data; }; + +export const postCategories = async (payload: { categoryName: string }) => { + const response = await apiRequest.post('/api/v1/categories', payload); + return response.data; +}; + +export const patchCategories = async ({ + categoryId, + categoryName, +}: { + categoryId: number; + categoryName: string; +}) => { + const response = await apiRequest.patch(`/api/v1/categories/${categoryId}`, { + categoryName, + }); + return response.data; +}; + +export const deleteCategories = async ({ + categoryId, +}: { + categoryId: number; +}) => { + const response = await apiRequest.delete( + `/api/v1/categories/${categoryId}`, + {} + ); + return response.data; +}; diff --git a/apps/extension/src/api/axiosInstance.ts b/apps/extension/src/api/axiosInstance.ts index 77adb0d..b874810 100644 --- a/apps/extension/src/api/axiosInstance.ts +++ b/apps/extension/src/api/axiosInstance.ts @@ -1,4 +1,5 @@ import axios from 'axios'; +import { useState } from 'react'; const apiRequest = axios.create({ baseURL: import.meta.env.VITE_BASE_URL, @@ -14,9 +15,9 @@ const fetchToken = async (email?: string) => { params: { email }, } ); - const newToken = response.data.token; + const newToken = response.data.data.token; chrome.storage.local.set({ jwtToken: newToken }, () => { - console.log('Token saved to chrome storage'); + console.log('Token saved to chrome storage다시', newToken); }); return newToken; }; @@ -25,15 +26,27 @@ apiRequest.interceptors.request.use(async (config) => { const noAuthNeeded = ['/api/v1/auth/token', '/api/v1/auth/signup']; const isNoAuth = noAuthNeeded.some((url) => config.url?.includes(url)); - if (!isNoAuth) { - let token = - 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJwaW5iYWNrIiwiaWQiOiJhOTA1NGFjOS03MTg0LTQ3NjktYWY4Mi1jNGViYTg0YzYxYTIiLCJzdWIiOiJBY2Nlc3NUb2tlbiIsImV4cCI6MTc1MjgwMDY1Nn0.hXti-Jlnhg8mRoPl5nB8Vi8UV6HPdZYAtgtpTuqtH39lQWle8T5GlX0ug0nNVUqu5B_Pyzafck7lhfXN6ArHOA'; + if (isNoAuth) return config; - if (!token || token === 'undefined') { - token = await fetchToken('test@gmail.com'); - } - config.headers.Authorization = `Bearer ${token}`; + const email = await new Promise((resolve) => { + chrome.storage.local.get('email', (result) => { + resolve(result.email); + }); + }); + + let token = await new Promise((resolve) => { + chrome.storage.local.get('jwtToken', (result) => { + resolve(result.jwtToken); + }); + }); + + // 토큰 없으면 fetchToken 호출 + if (!token || token === 'undefined') { + console.log(email, '여기야'); + token = await fetchToken(email); } + + config.headers.Authorization = `Bearer ${token}`; return config; }); diff --git a/apps/extension/src/api/queries.ts b/apps/extension/src/api/queries.ts index aa05e41..7dc8e8e 100644 --- a/apps/extension/src/api/queries.ts +++ b/apps/extension/src/api/queries.ts @@ -1,4 +1,10 @@ -import { getCategoriesDash, postArticles } from './axios'; +import { + getCategoriesDash, + postArticles, + postCategories, + patchCategories, + deleteCategories, +} from './axios'; import { useQuery, useMutation } from '@tanstack/react-query'; export const useGetCategoriesDash = () => { return useQuery({ @@ -12,3 +18,26 @@ export const usePostArticles = () => { mutationFn: postArticles, }); }; + +export const usePostCategories = () => { + return useMutation({ + mutationFn: postCategories, + }); +}; + +interface PatchCategoryParams { + categoryId: number; + categoryName: string; +} + +export const usePatchCategories = () => { + return useMutation({ + mutationFn: patchCategories, + }); +}; + +export const useDeleteCategories = () => { + return useMutation({ + mutationFn: deleteCategories, + }); +}; diff --git a/apps/extension/src/background.ts b/apps/extension/src/background.ts index 9117722..5aa0490 100644 --- a/apps/extension/src/background.ts +++ b/apps/extension/src/background.ts @@ -9,9 +9,12 @@ chrome.runtime.onInstalled.addListener((details) => { if (details.reason === 'install') { chrome.identity.getProfileUserInfo(function (info) { console.log('google email:', info.email); + chrome.storage.local.set({ email: info.email }, () => { + console.log('Token saved!', info.email); + }); setTimeout(() => { chrome.tabs.create({ - url: `http://localhost:5180/onboarding?email=${info.email}`, + url: `http://localhost:5173/onboarding?email=${info.email}`, }); }, 1000); }); @@ -23,7 +26,7 @@ chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => { const { url, title } = message.payload; chrome.storage.local.set({ savedBookmark: url }, () => { - console.log('📦 storage 저장 완료:', url); + console.log('📦 storage 저장 완료:'); }); chrome.bookmarks.create( @@ -43,7 +46,7 @@ chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => { error: chrome.runtime.lastError.message, }); } else { - console.log('📦 북마크 저장 완료:', newBookmark); + console.log('📦 북마크 저장 완료:'); sendResponse({ success: true, data: newBookmark }); } } diff --git a/apps/extension/src/components/modalPop/ModalPop.tsx b/apps/extension/src/components/modalPop/ModalPop.tsx index 5d45032..f899c4f 100644 --- a/apps/extension/src/components/modalPop/ModalPop.tsx +++ b/apps/extension/src/components/modalPop/ModalPop.tsx @@ -1,16 +1,22 @@ -import { useState, useEffect } from 'react'; import { CategoryDropDown, CommonBtn, InfoBox, TextArea, - TextFieldPopup, TimePicker, ToggleButton, } from '@pinback/design-system/ui'; +import { useState, useEffect } from 'react'; import ModalHeader from './ModalHeader'; import { POP_TEXTAREA_MAX_LENGTH } from '@constants/index'; -import { useGetCategoriesDash, usePostArticles } from '@api/queries'; +import { TextFieldPopup } from '@pinback/design-system/ui'; +import { + useGetCategoriesDash, + usePostArticles, + usePostCategories, + usePatchCategories, + useDeleteCategories, +} from '@api/queries'; import { useGetRemindTime } from '../../api/modalQueries'; import { fomatToday } from '@pinback/design-system/utils'; @@ -25,7 +31,34 @@ interface Category { categoryName: string; unreadCount: number; } + const ModalPop = ({ urlInfo, imgInfo, titleInfo, desInfo }: ModalPopProps) => { + const [memo, setMemo] = useState(''); + const { mutate: postArticle } = usePostArticles(); + const { mutate: postCategories } = usePostCategories(); + const { mutate: patchCategories } = usePatchCategories(); + const { mutate: deleteCategories } = useDeleteCategories(); + const { data: categoriesData } = useGetCategoriesDash(); + const { + data: remindTimeData, + isLoading, + error, + } = useGetRemindTime(fomatToday(new Date())); + useEffect(() => { + if (remindTimeData?.data) { + const { remindDate, remindTime } = remindTimeData.data; + + const formattedDate = remindDate.replace(/-/g, ''); + const formattedTime = remindTime.slice(0, 5).replace(':', ''); + + setFormState((prev) => ({ + ...prev, + date: formattedDate, + time: formattedTime, + })); + } + }, [remindTimeData]); + const [formState, setFormState] = useState({ date: '', dateError: '', @@ -33,20 +66,17 @@ const ModalPop = ({ urlInfo, imgInfo, titleInfo, desInfo }: ModalPopProps) => { timeError: '', }); const [categories, setCategories] = useState(['']); - const [memo, setMemo] = useState(''); - const { mutate: postArticle } = usePostArticles(); - const { - data: remindTime, - isLoading, - error, - } = useGetRemindTime(fomatToday(new Date())); + const [categoryPopupMode, setCategoryPopupMode] = useState< + 'edit' | 'add' | 'delete' | '' + >(''); + const [selectedCategory, setSelectedCategory] = useState(''); + const [matchId, setMatchedId] = useState(null); + const [editCategoryIndex, setEditCategoryIndex] = useState( + null + ); + const [isAskingDelete, setIsAskingDelete] = useState(false); - if (error) { - console.error('Error fetching remind time:', error); - return
Error loading remind time
; - } - const { data: categoriesData } = useGetCategoriesDash(); useEffect(() => { if (categoriesData) { const categoryNames: string[] = categoriesData.data.categories.map( @@ -55,11 +85,6 @@ const ModalPop = ({ urlInfo, imgInfo, titleInfo, desInfo }: ModalPopProps) => { setCategories(categoryNames); } }, [categoriesData]); - const [categoryPopupMode, setCategoryPopupMode] = useState< - 'edit' | 'add' | '' - >(''); - const [selectedCategory, setSelectedCategory] = useState(''); - const [matchId, setMatchedId] = useState(null); useEffect(() => { if (categoriesData?.data?.categories && selectedCategory) { @@ -70,10 +95,96 @@ const ModalPop = ({ urlInfo, imgInfo, titleInfo, desInfo }: ModalPopProps) => { } }, [selectedCategory, categoriesData]); + const handlePopupClose = () => { + setCategoryPopupMode(''); + setIsAskingDelete(false); + }; + const handlePopupConfirm = (newCategory?: string) => { + if (!newCategory) return; + + if (categoryPopupMode === 'add') { + postCategories( + { categoryName: newCategory }, + { + onSuccess: (res) => { + setCategories((prev) => [...prev, newCategory]); + setSelectedCategory(newCategory); + handlePopupClose(); + }, + onError: (err: any) => { + const message = err?.response?.data?.message; + alert('❌ 저장 실패:' + err.response?.data.message); + }, + } + ); + } + }; + const handlePopupEdit = (newCategory?: string) => { + if (!newCategory) return; + if (categoryPopupMode === 'edit' && editCategoryIndex !== null) { + setSelectedCategory(newCategory); + handlePopupClose(); + + patchCategories( + { + categoryId: + categoriesData.data.categories[editCategoryIndex].categoryId, + categoryName: newCategory, + }, + { + onSuccess: (res) => { + setCategories((prev) => [...prev, newCategory]); + setSelectedCategory(newCategory); + location.reload(); + handlePopupClose(); + }, + onError: (err: any) => { + const message = err?.response?.data?.message; + alert('❌ 등록 실패:' + err.response?.data.message); + }, + } + ); + } + }; + const handlePopupDelete = () => { + setSelectedCategory(''); + if (categoryPopupMode === 'edit' && editCategoryIndex !== null) { + handlePopupClose(); + deleteCategories( + { + categoryId: + categoriesData.data.categories[editCategoryIndex].categoryId, + }, + { + onSuccess: (res) => { + location.reload(); + handlePopupClose(); + }, + onError: (err: any) => { + const message = err?.response?.data?.message; + alert('❌ 삭제 실패:' + err.response?.data.message); + }, + } + ); + } + }; + + if (error) { + console.error('Error fetching remind time:', error); + return
Error loading remind time
; + } + const handleSave = () => { + const remindTimeFormatted = `${formState.date.slice(0, 4)}-${formState.date.slice(4, 6)}-${formState.date.slice(6, 8)}T${formState.time.slice(0, 2)}:${formState.time.slice(2, 4)}:00`; + + const defaultCategoryId = + categoriesData?.data?.categories?.[0]?.categoryId ?? null; + const categoryIdToUse = matchId ?? defaultCategoryId; + chrome.storage.local.set({ savedTitle: titleInfo }, () => { console.log('📦 storage 저장 완료:', titleInfo); }); + chrome.runtime.sendMessage( { type: 'SAVE_BOOKMARK', @@ -86,21 +197,22 @@ const ModalPop = ({ urlInfo, imgInfo, titleInfo, desInfo }: ModalPopProps) => { console.log('✅ 응답 받음:', response); } ); + postArticle( { url: urlInfo, - categoryId: matchId, + categoryId: categoryIdToUse, memo: memo, - remindTime: fomatToday(new Date()), + remindTime: remindTimeFormatted, }, { onSuccess: (data) => { console.log('✅ 저장 성공:', data); - // TODO : 저장 시. 창 원래 닫아야하나 우선 개발 중이라 열어두었습니당 - // window.close(); + // window.close(); // 최종 배포 시 주석 해제 }, - onError: (error) => { - console.error('❌ 저장 실패:', error); + onError: (error: any) => { + const message = error?.response?.data?.message; + alert('❌ 저장 실패:' + message); }, } ); @@ -118,36 +230,22 @@ const ModalPop = ({ urlInfo, imgInfo, titleInfo, desInfo }: ModalPopProps) => { })); }; - const handleCategoryChange = (value: string) => { + const handleCategoryChange = (value: string, index?: number) => { + console.log(index, value); if (value === 'edit') { + setEditCategoryIndex(index ?? null); + setSelectedCategory(value); setCategoryPopupMode('edit'); } else if (value === 'create') { setCategoryPopupMode('add'); } else { setSelectedCategory(value); console.log(value); + console.log(value); setCategoryPopupMode(''); } }; - const handlePopupClose = () => { - setCategoryPopupMode(''); - }; - - const handlePopupConfirm = (newCategory?: string) => { - if (!newCategory) return; - if (categoryPopupMode === 'add') { - setCategories((prev) => [...prev, newCategory]); - setSelectedCategory(newCategory); - } else if (categoryPopupMode === 'edit') { - setCategories((prev) => - prev.map((cat) => (cat === selectedCategory ? newCategory : cat)) - ); - setSelectedCategory(newCategory); - } - handlePopupClose(); - }; - const truncateText = (text: string, maxLength: number = 18): string => text.length > maxLength ? `${text.slice(0, maxLength)}...` : text; @@ -219,18 +317,14 @@ const ModalPop = ({ urlInfo, imgInfo, titleInfo, desInfo }: ModalPopProps) => { {categoryPopupMode && ( setIsAskingDelete(true)} existingCategories={categories} onCancel={handlePopupClose} + onEdit={handlePopupEdit} onConfirm={handlePopupConfirm} - onDelete={() => { - setCategories((prev) => - prev.filter((cat) => cat !== selectedCategory) - ); - setSelectedCategory(''); - handlePopupClose(); - }} + onDelete={handlePopupDelete} /> )} diff --git a/apps/extension/src/content.ts b/apps/extension/src/content.ts index f9da6cd..ce370a4 100644 --- a/apps/extension/src/content.ts +++ b/apps/extension/src/content.ts @@ -5,5 +5,6 @@ window.addEventListener('message', (event) => { type: 'SET_TOKEN', token: event.data.token, }); + console.log(event.data.token, '여기'); } }); diff --git a/packages/design-system/src/components/category_dropdown/CategoryDropDown.tsx b/packages/design-system/src/components/category_dropdown/CategoryDropDown.tsx index 939e3aa..62c9547 100644 --- a/packages/design-system/src/components/category_dropdown/CategoryDropDown.tsx +++ b/packages/design-system/src/components/category_dropdown/CategoryDropDown.tsx @@ -25,15 +25,11 @@ const categoryFontVariants = cva('text-black', { size: 'large', }, }); -interface CategoryDropDownProps { - size?: 'large' | 'medium'; - categories: string[]; -} interface CategoryDropDownProps { size?: 'large' | 'medium'; categories: string[]; - onSelect?: (value: string) => void; + onSelect?: (value: string, index?: number) => void; } const CategoryDropDown = ({ @@ -94,7 +90,7 @@ const CategoryDropDown = ({ className="relative h-[1.8rem] w-[1.8rem]" onClick={(e) => { e.stopPropagation(); - onSelect?.('edit'); + onSelect?.('edit', index); setIsDropDownOpen(false); }} > diff --git a/packages/design-system/src/components/textfieldPopup/TextfieldPopup.tsx b/packages/design-system/src/components/textfieldPopup/TextfieldPopup.tsx index 63b179f..e3eff00 100644 --- a/packages/design-system/src/components/textfieldPopup/TextfieldPopup.tsx +++ b/packages/design-system/src/components/textfieldPopup/TextfieldPopup.tsx @@ -7,10 +7,12 @@ type Mode = 'add' | 'edit' | 'delete'; interface TextfieldPopupProps { mode: Mode; value?: string; - existingCategories?: string[]; // 중복 확인용 + existingCategories?: string[]; onCancel?: () => void; + onEdit?: (value?: string) => void; onConfirm?: (value?: string) => void; - onDelete?: () => void; + onDelete?: (value?: string) => void; + onAskDeleteConfirm?: () => void; } const TextfieldPopup = ({ @@ -20,6 +22,8 @@ const TextfieldPopup = ({ onCancel, onConfirm, onDelete, + onEdit, + onAskDeleteConfirm, }: TextfieldPopupProps) => { const inputRef = useRef(null); const [isError, setIsError] = useState(false); @@ -42,7 +46,6 @@ const TextfieldPopup = ({ return false; } - // 현재 수정 모드라면 동일한 값은 허용 const isSameAsInitial = input === value.trim(); const isDuplicate = existingCategories.includes(input); @@ -62,7 +65,17 @@ const TextfieldPopup = ({ onConfirm?.(getInputValue()); } }; - + const handleEdit = () => { + if (validate()) { + onEdit?.(getInputValue()); + } + }; + const handleDelete = () => { + onAskDeleteConfirm?.(); + if (validate()) { + onDelete?.(getInputValue()); + } + }; const renderForm = (heading: string, showDelete?: boolean) => (
{mode === 'edit' && ( @@ -90,14 +103,14 @@ const TextfieldPopup = ({ size="Xsmall" type="white" text="삭제" - onClick={onDelete} + onClick={handleDelete} /> ) : ( @@ -121,7 +134,7 @@ const TextfieldPopup = ({
); - const renderContent = () => { + const renderContent = (mode: string) => { switch (mode) { case 'add': return renderForm('새로운 카테고리 추가하기'); @@ -160,7 +173,7 @@ const TextfieldPopup = ({ return (
- {renderContent()} + {renderContent(mode)}
); diff --git a/packages/design-system/src/components/timePicker/TimePicker.tsx b/packages/design-system/src/components/timePicker/TimePicker.tsx index 0cea34c..37afdd4 100644 --- a/packages/design-system/src/components/timePicker/TimePicker.tsx +++ b/packages/design-system/src/components/timePicker/TimePicker.tsx @@ -61,7 +61,7 @@ const TimePicker = ({ size, specie, value, onChange }: TimePickerProps) => { const handleChange = (e: React.ChangeEvent) => { const raw = e.target.value; - const onlyDigits = raw.replace(/\D/g, ''); + const onlyDigits = raw.replace(/\D/g, ''); // 숫자만 남기기 if (isDeletingRef.current) { onChange(onlyDigits); @@ -71,14 +71,38 @@ const TimePicker = ({ size, specie, value, onChange }: TimePickerProps) => { if (specie === 'date') { const formatted = formatDate(onlyDigits); const errorMsg = validateDate(onlyDigits); - onChange(formatted, errorMsg ?? undefined); + onChange(onlyDigits, errorMsg ?? undefined); + console.log(formatted); } else { const formatted = formatTime(onlyDigits); const errorMsg = validateTime(onlyDigits); - onChange(formatted, errorMsg ?? undefined); + onChange(onlyDigits, errorMsg ?? undefined); + console.log(formatted); } }; + const displayValue = + specie === 'time' + ? formatDisplayTime(value) // 우리가 만들 함수 + : formatDisplayDate(value); // ex: 20250719 → 2025-07-19 + function formatDisplayTime(raw: string): string { + if (raw.length !== 4) { + return raw; + } + const hour = parseInt(raw.slice(0, 2), 10); + const minute = raw.slice(2); + const period = hour < 12 ? '오전' : '오후'; + const hour12 = hour % 12 === 0 ? 12 : hour % 12; + + return `${period} ${String(hour12).padStart(2, '0')}:${minute}`; + } + function formatDisplayDate(raw: string): string { + if (raw.length !== 8) { + return raw; + } + return `${raw.slice(0, 4)}-${raw.slice(4, 6)}-${raw.slice(6, 8)}`; + } + return (
{ >>>>>> origin/develop version: 4.1.11(vite@7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@1.10.2)) '@tanstack/react-query': specifier: ^5.81.5 version: 5.81.5(react@19.1.0) +<<<<<<< HEAD +======= ======= version: 4.1.11(vite@7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)) +>>>>>>> origin/develop >>>>>>> origin/develop axios: specifier: ^1.10.0 @@ -190,7 +196,7 @@ importers: version: 19.1.6(@types/react@19.1.8) '@vitejs/plugin-react-swc': specifier: ^3.10.2 - version: 3.10.2(@swc/helpers@0.5.17)(vite@7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)) + version: 3.10.2(@swc/helpers@0.5.17)(vite@7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@1.10.2)) autoprefixer: specifier: ^10.4.21 version: 10.4.21(postcss@8.5.6) @@ -223,14 +229,13 @@ importers: version: 8.35.0(eslint@8.57.1)(typescript@5.8.3) vite: specifier: ^7.0.0 - version: 7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3) version: 7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@1.10.2) vite-plugin-chrome-extension: specifier: ^0.0.7 version: 0.0.7 vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.8.3)(vite@7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)) + version: 5.1.4(typescript@5.8.3)(vite@7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@1.10.2)) apps/landing: dependencies: @@ -239,7 +244,7 @@ importers: version: link:../../packages/design-system '@tailwindcss/vite': specifier: ^4.1.11 - version: 4.1.11(vite@7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)) + version: 4.1.11(vite@7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@1.10.2)) '@tanstack/react-query': specifier: ^5.81.5 version: 5.81.5(react@19.1.0) @@ -249,6 +254,9 @@ importers: axios: specifier: ^1.10.0 version: 1.10.0 + class-variance-authority: + specifier: ^0.7.1 + version: 0.7.1 eslint: specifier: ^8.44.0 version: 8.57.1 @@ -285,7 +293,7 @@ importers: version: link:../../config/typescript '@pivanov/vite-plugin-svg-sprite': specifier: ^3.0.0 - version: 3.1.1(vite@7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)) + version: 3.1.1(vite@7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@1.10.2)) '@types/react': specifier: ^19.1.8 version: 19.1.8 @@ -294,7 +302,7 @@ importers: version: 19.1.6(@types/react@19.1.8) '@vitejs/plugin-react-swc': specifier: ^3.10.2 - version: 3.10.2(@swc/helpers@0.5.17)(vite@7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)) + version: 3.10.2(@swc/helpers@0.5.17)(vite@7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@1.10.2)) eslint-plugin-react-hooks: specifier: ^5.2.0 version: 5.2.0(eslint@8.57.1) @@ -312,10 +320,10 @@ importers: version: 8.35.0(eslint@8.57.1)(typescript@5.8.3) vite: specifier: ^7.0.0 - version: 7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3) + version: 7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@1.10.2) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.8.3)(vite@7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)) + version: 5.1.4(typescript@5.8.3)(vite@7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@1.10.2)) config/eslint: devDependencies: @@ -393,13 +401,13 @@ importers: version: link:../../config/typescript '@pivanov/vite-plugin-svg-sprite': specifier: ^3.0.0 - version: 3.1.1(vite@7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)) + version: 3.1.1(vite@7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@1.10.2)) '@tailwindcss/postcss': specifier: ^4.1.10 version: 4.1.11 '@tailwindcss/vite': specifier: ^4.1.11 - version: 4.1.11(vite@7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)) + version: 4.1.11(vite@7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@1.10.2)) '@turbo/gen': specifier: ^1.12.4 version: 1.13.4(@swc/core@1.12.7(@swc/helpers@0.5.17))(@types/node@20.19.2)(typescript@5.8.3) @@ -414,7 +422,7 @@ importers: version: 19.1.6(@types/react@19.1.8) '@vitejs/plugin-react': specifier: ^4.5.2 - version: 4.6.0(vite@7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)) + version: 4.6.0(vite@7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@1.10.2)) tailwind-merge: specifier: ^3.3.1 version: 3.3.1 @@ -429,7 +437,7 @@ importers: version: 5.8.3 vite: specifier: ^7.0.0 - version: 7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3) + version: 7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@1.10.2) packages: @@ -2737,6 +2745,10 @@ packages: ======= >>>>>>> origin/develop + i@0.3.7: + resolution: {integrity: sha512-FYz4wlXgkQwIPqhzC5TdNMLSE5+GS1IIDJZY/1ZiEPCT2S3COUVZeT5OW4BmW4r5LHLQuOosSwsvnroG9GR59Q==} + engines: {node: '>=0.4'} + iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} @@ -4194,6 +4206,10 @@ packages: ======= >>>>>>> origin/develop + yaml@1.10.2: + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + engines: {node: '>= 6'} + yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} @@ -4839,12 +4855,12 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 - '@pivanov/vite-plugin-svg-sprite@3.1.1(vite@7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3))': + '@pivanov/vite-plugin-svg-sprite@3.1.1(vite@7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@1.10.2))': dependencies: cheerio: 1.1.0 chokidar: 4.0.3 svgo: 4.0.0 - vite: 7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3) + vite: 7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@1.10.2) '@pkgr/core@0.2.7': {} @@ -5222,12 +5238,12 @@ snapshots: postcss: 8.5.6 tailwindcss: 4.1.11 - '@tailwindcss/vite@4.1.11(vite@7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3))': + '@tailwindcss/vite@4.1.11(vite@7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@1.10.2))': dependencies: '@tailwindcss/node': 4.1.11 '@tailwindcss/oxide': 4.1.11 tailwindcss: 4.1.11 - vite: 7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3) + vite: 7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@1.10.2) '@tanstack/query-core@5.81.5': {} @@ -5559,15 +5575,15 @@ snapshots: '@ungap/structured-clone@1.3.0': {} - '@vitejs/plugin-react-swc@3.10.2(@swc/helpers@0.5.17)(vite@7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3))': + '@vitejs/plugin-react-swc@3.10.2(@swc/helpers@0.5.17)(vite@7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@1.10.2))': dependencies: '@rolldown/pluginutils': 1.0.0-beta.11 '@swc/core': 1.12.7(@swc/helpers@0.5.17) - vite: 7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3) + vite: 7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@1.10.2) transitivePeerDependencies: - '@swc/helpers' - '@vitejs/plugin-react@4.6.0(vite@7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3))': + '@vitejs/plugin-react@4.6.0(vite@7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@1.10.2))': dependencies: '@babel/core': 7.27.7 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.27.7) @@ -5575,7 +5591,7 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.19 '@types/babel__core': 7.20.5 react-refresh: 0.17.0 - vite: 7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3) + vite: 7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@1.10.2) transitivePeerDependencies: - supports-color @@ -8127,28 +8143,62 @@ snapshots: validate-npm-package-name@5.0.1: {} + vite-plugin-chrome-extension@0.0.7: + dependencies: + ajv: 6.12.6 + array-flat-polyfill: 1.0.1 + chalk: 4.1.2 + cheerio: 1.1.0 + convert-source-map: 1.9.0 + cosmiconfig: 6.0.0 + fs-extra: 8.1.0 + glob: 7.2.3 + jsonpath-plus: 4.0.0 + lodash.difference: 4.5.0 + lodash.flatten: 4.4.0 + lodash.get: 4.4.2 + mem: 6.1.1 + prettier: 1.19.1 + rollup: 2.79.2 + slash: 3.0.0 + vite: 2.9.18 + webextension-polyfill: 0.6.0 + transitivePeerDependencies: + - less + - sass + - stylus + vite-plugin-svgr@4.3.0(rollup@4.44.1)(typescript@5.8.3)(vite@7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@1.10.2)): dependencies: '@rollup/pluginutils': 5.2.0(rollup@4.44.1) '@svgr/core': 8.1.0(typescript@5.8.3) '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.8.3)) - vite: 7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3) + vite: 7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@1.10.2) transitivePeerDependencies: - rollup - supports-color - typescript - vite-tsconfig-paths@5.1.4(typescript@5.8.3)(vite@7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)): + vite-tsconfig-paths@5.1.4(typescript@5.8.3)(vite@7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@1.10.2)): dependencies: debug: 4.4.1 globrex: 0.1.2 tsconfck: 3.1.6(typescript@5.8.3) optionalDependencies: - vite: 7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3) + vite: 7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@1.10.2) transitivePeerDependencies: - supports-color - typescript + vite@2.9.18: + dependencies: + esbuild: 0.14.54 + postcss: 8.5.6 + resolve: 1.22.10 + rollup: 2.77.3 + optionalDependencies: + fsevents: 2.3.3 + vite@7.0.0(@types/node@20.19.2)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.43.1)(tsx@4.20.3)(yaml@1.10.2): dependencies: esbuild: 0.25.5 @@ -8164,6 +8214,7 @@ snapshots: lightningcss: 1.30.1 terser: 5.43.1 tsx: 4.20.3 + yaml: 1.10.2 wcwidth@1.0.1: dependencies: @@ -8256,8 +8307,7 @@ snapshots: yallist@5.0.0: {} - yaml@1.10.2: - optional: true + yaml@1.10.2: {} yargs-parser@21.1.1: {}