From eefe0e2f846003f733124abf0d4870fb2e1f601e Mon Sep 17 00:00:00 2001 From: jllee000 Date: Thu, 17 Jul 2025 08:11:45 +0900 Subject: [PATCH 01/17] =?UTF-8?q?feat:=20=ED=81=AC=EB=A1=AC=20=EC=8A=A4?= =?UTF-8?q?=ED=86=A0=EB=A6=AC=EC=A7=80=EC=97=90=20=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/client/index.html | 1 - apps/extension/public/manifest.json | 4 +- apps/extension/src/App.tsx | 4 +- apps/extension/src/api/apiFetch.ts | 26 +++ apps/extension/src/api/axiosInstance.ts | 19 +- apps/extension/src/background.ts | 3 +- .../src/components/modalPop/ModalPop.tsx | 182 +++++++++--------- apps/extension/vite.config.ts | 2 +- .../category_dropdown/CategoryDropDown.tsx | 12 +- tsconfig.json | 26 +++ 10 files changed, 166 insertions(+), 113 deletions(-) create mode 100644 apps/extension/src/api/apiFetch.ts create mode 100644 tsconfig.json diff --git a/apps/client/index.html b/apps/client/index.html index fcb3ac29..0dfa48a5 100644 --- a/apps/client/index.html +++ b/apps/client/index.html @@ -2,7 +2,6 @@ - Vite + React + TS diff --git a/apps/extension/public/manifest.json b/apps/extension/public/manifest.json index e947eb58..ce5004fc 100644 --- a/apps/extension/public/manifest.json +++ b/apps/extension/public/manifest.json @@ -12,9 +12,7 @@ "identity", "identity.email", "scripting", - "bookmarks", - "http://*/", - "https://*/" + "bookmarks" ], "host_permissions": [""], "icons": { diff --git a/apps/extension/src/App.tsx b/apps/extension/src/App.tsx index f43834c5..d6aa82e9 100644 --- a/apps/extension/src/App.tsx +++ b/apps/extension/src/App.tsx @@ -38,7 +38,9 @@ const App = () => { setTitle(imageUrl?.title ?? ''); setDescription(imageUrl?.description ?? ''); setImgUrl(imageUrl?.image ?? ''); - localStorage.setItem('titleSave', title); + chrome.storage.local.set({ titleSave: title }, () => { + console.log('Title saved to chrome storage'); + }); } }); }, []); diff --git a/apps/extension/src/api/apiFetch.ts b/apps/extension/src/api/apiFetch.ts new file mode 100644 index 00000000..f6ec0816 --- /dev/null +++ b/apps/extension/src/api/apiFetch.ts @@ -0,0 +1,26 @@ +import apiRequest from './axiosInstance'; + +export const makeCategories = async () => { + try { + const result = await new Promise<{ jwtToken?: string }>((resolve) => { + chrome.storage.local.get(['jwtToken'], resolve); + }); + const token = result.jwtToken || ''; + + const response = await apiRequest.post( + '/api/v1/categories', + { + categoryName: '만들어질카테고리일까', + }, + { + headers: { + Authorization: `Bearer ${token}`, + }, + } + ); + return response; + } catch (error) { + console.log('signup error: ' + JSON.stringify(error)); + throw error; + } +}; diff --git a/apps/extension/src/api/axiosInstance.ts b/apps/extension/src/api/axiosInstance.ts index 6826f891..79ddcc8d 100644 --- a/apps/extension/src/api/axiosInstance.ts +++ b/apps/extension/src/api/axiosInstance.ts @@ -15,23 +15,20 @@ const fetchToken = async (email?: string) => { } ); const newToken = response.data.token; - localStorage.setItem('jwtToken', newToken); - return newToken; -}; -const getChromeToken = async (): Promise => { - return new Promise((resolve) => { - chrome.storage.local.get(['jwtToken'], (result) => { - resolve(result.jwtToken ?? null); - }); + chrome.storage.local.set({ jwtToken: newToken }, () => { + console.log('Token saved to chrome storage'); }); + return newToken; }; apiRequest.interceptors.request.use(async (config) => { - const noAuthNeeded = ['/api/v1/auth/token', '/api/v1/auth/signin']; + const noAuthNeeded = ['/api/v1/auth/token', '/api/v1/auth/signup']; const isNoAuth = noAuthNeeded.some((url) => config.url?.includes(url)); if (!isNoAuth) { - let token = await getChromeToken(); + let token = + 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJwaW5iYWNrIiwiaWQiOiIwNDkzMDRjZC03YzY4LTRmZjEtYmI3NC1mYmQ2MGM3MGI4MjIiLCJzdWIiOiJBY2Nlc3NUb2tlbiIsImV4cCI6MTc1MjczNjU1MX0.QJQE6AljQOlhvQ3g6ioBCvPXaOudmJEcdGmkDbnstK1TWodE67rSnyuPW19ZP5GQzyzLaOkFhaGEv-Fi5M0yCA'; + if (!token || token === 'undefined') { token = await fetchToken('test@gmail.com'); } @@ -44,7 +41,7 @@ apiRequest.interceptors.response.use( (response) => response, async (error) => { const originalRequest = error.config; - const noAuthNeeded = ['/api/v1/auth/token', '/api/v1/auth/signin']; + const noAuthNeeded = ['/api/v1/auth/token', '/api/v1/auth/signup']; const isNoAuth = noAuthNeeded.some((url) => originalRequest.url?.includes(url) ); diff --git a/apps/extension/src/background.ts b/apps/extension/src/background.ts index 60920287..6fa030f6 100644 --- a/apps/extension/src/background.ts +++ b/apps/extension/src/background.ts @@ -9,7 +9,6 @@ chrome.runtime.onInstalled.addListener((details) => { if (details.reason === 'install') { chrome.identity.getProfileUserInfo(function (info) { console.log('google email:', info.email); - setTimeout(() => { chrome.tabs.create({ url: `http://localhost:5180/onboarding?email=${info.email}`, @@ -28,7 +27,7 @@ chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => { chrome.bookmarks.create( { - title: localStorage.getItem('titleSave') ?? '핀백 저장소', + title: '핀백 저장소', url: url, parentId: '1', }, diff --git a/apps/extension/src/components/modalPop/ModalPop.tsx b/apps/extension/src/components/modalPop/ModalPop.tsx index 5c432feb..706b11f4 100644 --- a/apps/extension/src/components/modalPop/ModalPop.tsx +++ b/apps/extension/src/components/modalPop/ModalPop.tsx @@ -18,107 +18,105 @@ interface ModalPopProps { } const ModalPop = ({ urlInfo, imgInfo, titleInfo, desInfo }: ModalPopProps) => { - { - const handleSave = () => { - chrome.runtime.sendMessage( - { - type: 'SAVE_BOOKMARK', - payload: { - url: urlInfo, - title: '저장할 페이지 이름', - }, + const handleSave = () => { + chrome.runtime.sendMessage( + { + type: 'SAVE_BOOKMARK', + payload: { + url: urlInfo, + title: '저장할 페이지 이름', }, - (response) => { - console.log('✅ 응답 받음:', response); - } - ); - window.close(); - }; - const [formState, setFormState] = useState({ - date: '', - dateError: '', - time: '', - timeError: '', - }); - const truncateText = (text: string, maxLength: number = 18): string => { - return text.length > maxLength ? `${text.slice(0, maxLength)}...` : text; - }; + }, + (response) => { + console.log('✅ 응답 받음:', response); + } + ); + window.close(); + }; + const [formState, setFormState] = useState({ + date: '', + dateError: '', + time: '', + timeError: '', + }); + const truncateText = (text: string, maxLength: number = 18): string => { + return text.length > maxLength ? `${text.slice(0, maxLength)}...` : text; + }; - const handleFieldChange = ( - field: 'date' | 'time', - value: string, - errorMessage?: string - ) => { - setFormState((prev) => ({ - ...prev, - [field]: value, - [`${field}Error`]: errorMessage ?? '', - })); - }; + const handleFieldChange = ( + field: 'date' | 'time', + value: string, + errorMessage?: string + ) => { + setFormState((prev) => ({ + ...prev, + [field]: value, + [`${field}Error`]: errorMessage ?? '', + })); + }; - return ( -
-
- window.close()} /> -
- -
-
-

카테고리

- +
+ window.close()} /> +
+ +
+
+

카테고리

+ +
+
+

메모

+