idea-manager 1.3.4 → 1.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -0
- package/.next/app-path-routes-manifest.json +24 -0
- package/.next/build-manifest.json +20 -0
- package/.next/diagnostics/build-diagnostics.json +6 -0
- package/.next/diagnostics/framework.json +1 -0
- package/.next/export-marker.json +6 -0
- package/.next/images-manifest.json +67 -0
- package/.next/next-minimal-server.js.nft.json +1 -0
- package/.next/next-server.js.nft.json +1 -0
- package/.next/package.json +1 -0
- package/.next/prerender-manifest.json +85 -0
- package/.next/react-loadable-manifest.json +1 -0
- package/.next/required-server-files.js +325 -0
- package/.next/required-server-files.json +325 -0
- package/.next/routes-manifest.json +209 -0
- package/.next/server/app/_global-error/page.js +3 -0
- package/.next/server/app/_global-error/page.js.nft.json +1 -0
- package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -0
- package/.next/server/app/_global-error.html +2 -0
- package/.next/server/app/_global-error.meta +16 -0
- package/.next/server/app/_global-error.rsc +12 -0
- package/.next/server/app/_global-error.segments/_full.segment.rsc +12 -0
- package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +5 -0
- package/.next/server/app/_global-error.segments/_global-error.segment.rsc +4 -0
- package/.next/server/app/_global-error.segments/_head.segment.rsc +5 -0
- package/.next/server/app/_global-error.segments/_index.segment.rsc +4 -0
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -0
- package/.next/server/app/_not-found/page.js +6 -0
- package/.next/server/app/_not-found/page.js.nft.json +1 -0
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -0
- package/.next/server/app/_not-found.html +5 -0
- package/.next/server/app/_not-found.meta +16 -0
- package/.next/server/app/_not-found.rsc +17 -0
- package/.next/server/app/_not-found.segments/_full.segment.rsc +17 -0
- package/.next/server/app/_not-found.segments/_head.segment.rsc +6 -0
- package/.next/server/app/_not-found.segments/_index.segment.rsc +6 -0
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +5 -0
- package/.next/server/app/_not-found.segments/_not-found.segment.rsc +4 -0
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +5 -0
- package/.next/server/app/api/archive/route.js +83 -0
- package/.next/server/app/api/archive/route.js.nft.json +1 -0
- package/.next/server/app/api/archive/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/filesystem/route.js +1 -0
- package/.next/server/app/api/filesystem/route.js.nft.json +1 -0
- package/.next/server/app/api/filesystem/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/filesystem/tree/route.js +1 -0
- package/.next/server/app/api/filesystem/tree/route.js.nft.json +1 -0
- package/.next/server/app/api/filesystem/tree/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/global-memo/route.js +77 -0
- package/.next/server/app/api/global-memo/route.js.nft.json +1 -0
- package/.next/server/app/api/global-memo/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/health/route.js +1 -0
- package/.next/server/app/api/health/route.js.nft.json +1 -0
- package/.next/server/app/api/health/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/projects/[id]/apply-distribute/route.js +97 -0
- package/.next/server/app/api/projects/[id]/apply-distribute/route.js.nft.json +1 -0
- package/.next/server/app/api/projects/[id]/apply-distribute/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/projects/[id]/auto-distribute/route.js +45 -0
- package/.next/server/app/api/projects/[id]/auto-distribute/route.js.nft.json +1 -0
- package/.next/server/app/api/projects/[id]/auto-distribute/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/projects/[id]/brainstorm/route.js +77 -0
- package/.next/server/app/api/projects/[id]/brainstorm/route.js.nft.json +1 -0
- package/.next/server/app/api/projects/[id]/brainstorm/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/projects/[id]/git-sync/route.js +77 -0
- package/.next/server/app/api/projects/[id]/git-sync/route.js.nft.json +1 -0
- package/.next/server/app/api/projects/[id]/git-sync/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/projects/[id]/route.js +77 -0
- package/.next/server/app/api/projects/[id]/route.js.nft.json +1 -0
- package/.next/server/app/api/projects/[id]/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/projects/[id]/sub-projects/[subId]/route.js +91 -0
- package/.next/server/app/api/projects/[id]/sub-projects/[subId]/route.js.nft.json +1 -0
- package/.next/server/app/api/projects/[id]/sub-projects/[subId]/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/projects/[id]/sub-projects/[subId]/tasks/[taskId]/chat/route.js +22 -0
- package/.next/server/app/api/projects/[id]/sub-projects/[subId]/tasks/[taskId]/chat/route.js.nft.json +1 -0
- package/.next/server/app/api/projects/[id]/sub-projects/[subId]/tasks/[taskId]/chat/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/projects/[id]/sub-projects/[subId]/tasks/[taskId]/prompt/route.js +77 -0
- package/.next/server/app/api/projects/[id]/sub-projects/[subId]/tasks/[taskId]/prompt/route.js.nft.json +1 -0
- package/.next/server/app/api/projects/[id]/sub-projects/[subId]/tasks/[taskId]/prompt/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/projects/[id]/sub-projects/[subId]/tasks/[taskId]/route.js +83 -0
- package/.next/server/app/api/projects/[id]/sub-projects/[subId]/tasks/[taskId]/route.js.nft.json +1 -0
- package/.next/server/app/api/projects/[id]/sub-projects/[subId]/tasks/[taskId]/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/projects/[id]/sub-projects/[subId]/tasks/route.js +83 -0
- package/.next/server/app/api/projects/[id]/sub-projects/[subId]/tasks/route.js.nft.json +1 -0
- package/.next/server/app/api/projects/[id]/sub-projects/[subId]/tasks/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/projects/[id]/sub-projects/route.js +91 -0
- package/.next/server/app/api/projects/[id]/sub-projects/route.js.nft.json +1 -0
- package/.next/server/app/api/projects/[id]/sub-projects/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/projects/route.js +77 -0
- package/.next/server/app/api/projects/route.js.nft.json +1 -0
- package/.next/server/app/api/projects/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/sync/route.js +77 -0
- package/.next/server/app/api/sync/route.js.nft.json +1 -0
- package/.next/server/app/api/sync/route_client-reference-manifest.js +1 -0
- package/.next/server/app/index.html +5 -0
- package/.next/server/app/index.meta +14 -0
- package/.next/server/app/index.rsc +21 -0
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +9 -0
- package/.next/server/app/index.segments/_full.segment.rsc +21 -0
- package/.next/server/app/index.segments/_head.segment.rsc +6 -0
- package/.next/server/app/index.segments/_index.segment.rsc +6 -0
- package/.next/server/app/index.segments/_tree.segment.rsc +5 -0
- package/.next/server/app/page.js +23 -0
- package/.next/server/app/page.js.nft.json +1 -0
- package/.next/server/app/page_client-reference-manifest.js +1 -0
- package/.next/server/app/projects/[id]/page.js +6 -0
- package/.next/server/app/projects/[id]/page.js.nft.json +1 -0
- package/.next/server/app/projects/[id]/page_client-reference-manifest.js +1 -0
- package/.next/server/app-paths-manifest.json +24 -0
- package/.next/server/chunks/445.js +22 -0
- package/.next/server/chunks/471.js +13 -0
- package/.next/server/chunks/482.js +1 -0
- package/.next/server/chunks/806.js +77 -0
- package/.next/server/chunks/813.js +1 -0
- package/.next/server/functions-config-manifest.json +4 -0
- package/.next/server/interception-route-rewrite-manifest.js +1 -0
- package/.next/server/middleware-build-manifest.js +1 -0
- package/.next/server/middleware-manifest.json +6 -0
- package/.next/server/middleware-react-loadable-manifest.js +1 -0
- package/.next/server/next-font-manifest.js +1 -0
- package/.next/server/next-font-manifest.json +1 -0
- package/.next/server/pages/404.html +5 -0
- package/.next/server/pages/500.html +2 -0
- package/.next/server/pages-manifest.json +4 -0
- package/.next/server/server-reference-manifest.js +1 -0
- package/.next/server/server-reference-manifest.json +1 -0
- package/.next/server/webpack-runtime.js +1 -0
- package/.next/static/chunks/151-332d463cd8bd4db6.js +1 -0
- package/.next/static/chunks/4bd1b696-096d35a2bd1da3af.js +1 -0
- package/.next/static/chunks/794-37dad9bbc14b04b8.js +2 -0
- package/.next/static/chunks/app/_global-error/page-fd75b71b49e9729e.js +1 -0
- package/.next/static/chunks/app/_not-found/page-abee8833f317bce2.js +1 -0
- package/.next/static/chunks/app/api/archive/route-fd75b71b49e9729e.js +1 -0
- package/.next/static/chunks/app/api/filesystem/route-fd75b71b49e9729e.js +1 -0
- package/.next/static/chunks/app/api/filesystem/tree/route-fd75b71b49e9729e.js +1 -0
- package/.next/static/chunks/app/api/global-memo/route-fd75b71b49e9729e.js +1 -0
- package/.next/static/chunks/app/api/health/route-fd75b71b49e9729e.js +1 -0
- package/.next/static/chunks/app/api/projects/[id]/apply-distribute/route-fd75b71b49e9729e.js +1 -0
- package/.next/static/chunks/app/api/projects/[id]/auto-distribute/route-fd75b71b49e9729e.js +1 -0
- package/.next/static/chunks/app/api/projects/[id]/brainstorm/route-fd75b71b49e9729e.js +1 -0
- package/.next/static/chunks/app/api/projects/[id]/git-sync/route-fd75b71b49e9729e.js +1 -0
- package/.next/static/chunks/app/api/projects/[id]/route-fd75b71b49e9729e.js +1 -0
- package/.next/static/chunks/app/api/projects/[id]/sub-projects/[subId]/route-fd75b71b49e9729e.js +1 -0
- package/.next/static/chunks/app/api/projects/[id]/sub-projects/[subId]/tasks/[taskId]/chat/route-fd75b71b49e9729e.js +1 -0
- package/.next/static/chunks/app/api/projects/[id]/sub-projects/[subId]/tasks/[taskId]/prompt/route-fd75b71b49e9729e.js +1 -0
- package/.next/static/chunks/app/api/projects/[id]/sub-projects/[subId]/tasks/[taskId]/route-fd75b71b49e9729e.js +1 -0
- package/.next/static/chunks/app/api/projects/[id]/sub-projects/[subId]/tasks/route-fd75b71b49e9729e.js +1 -0
- package/.next/static/chunks/app/api/projects/[id]/sub-projects/route-fd75b71b49e9729e.js +1 -0
- package/.next/static/chunks/app/api/projects/route-fd75b71b49e9729e.js +1 -0
- package/.next/static/chunks/app/api/sync/route-fd75b71b49e9729e.js +1 -0
- package/.next/static/chunks/app/layout-52917f6c941a9818.js +1 -0
- package/.next/static/chunks/app/page-6bd6387a28d57acb.js +18 -0
- package/.next/static/chunks/app/projects/[id]/page-822db6c758e612c4.js +1 -0
- package/.next/static/chunks/framework-75892d61b920805f.js +1 -0
- package/.next/static/chunks/main-app-35159df8e1c56fc3.js +1 -0
- package/.next/static/chunks/main-f1d55fffd3cc9809.js +5 -0
- package/.next/static/chunks/next/dist/client/components/builtin/app-error-fd75b71b49e9729e.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/forbidden-fd75b71b49e9729e.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/global-error-25a0b2af2b25843d.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/not-found-fd75b71b49e9729e.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-fd75b71b49e9729e.js +1 -0
- package/.next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
- package/.next/static/chunks/webpack-046a553649a22885.js +1 -0
- package/.next/static/css/cd2b29b661e5554a.css +3 -0
- package/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
- package/.next/static/media/747892c23ea88013-s.woff2 +0 -0
- package/.next/static/media/8d697b304b401681-s.woff2 +0 -0
- package/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
- package/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
- package/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
- package/.next/static/pg-uaAz_0WfqjOVXsPpiN/_buildManifest.js +1 -0
- package/.next/static/pg-uaAz_0WfqjOVXsPpiN/_ssgManifest.js +1 -0
- package/.next/trace +3 -0
- package/.next/trace-build +1 -0
- package/.next/types/app/api/archive/route.ts +350 -0
- package/.next/types/app/api/filesystem/route.ts +350 -0
- package/.next/types/app/api/filesystem/tree/route.ts +350 -0
- package/.next/types/app/api/global-memo/route.ts +350 -0
- package/.next/types/app/api/health/route.ts +350 -0
- package/.next/types/app/api/projects/[id]/apply-distribute/route.ts +350 -0
- package/.next/types/app/api/projects/[id]/auto-distribute/route.ts +350 -0
- package/.next/types/app/api/projects/[id]/brainstorm/route.ts +350 -0
- package/.next/types/app/api/projects/[id]/git-sync/route.ts +350 -0
- package/.next/types/app/api/projects/[id]/route.ts +350 -0
- package/.next/types/app/api/projects/[id]/sub-projects/[subId]/route.ts +350 -0
- package/.next/types/app/api/projects/[id]/sub-projects/[subId]/tasks/[taskId]/chat/route.ts +350 -0
- package/.next/types/app/api/projects/[id]/sub-projects/[subId]/tasks/[taskId]/prompt/route.ts +350 -0
- package/.next/types/app/api/projects/[id]/sub-projects/[subId]/tasks/[taskId]/route.ts +350 -0
- package/.next/types/app/api/projects/[id]/sub-projects/[subId]/tasks/route.ts +350 -0
- package/.next/types/app/api/projects/[id]/sub-projects/route.ts +350 -0
- package/.next/types/app/api/projects/route.ts +350 -0
- package/.next/types/app/api/sync/route.ts +350 -0
- package/.next/types/app/layout.ts +86 -0
- package/.next/types/app/page.ts +86 -0
- package/.next/types/app/projects/[id]/page.ts +86 -0
- package/.next/types/package.json +1 -0
- package/.next/types/routes.d.ts +91 -0
- package/.next/types/validator.ts +241 -0
- package/package.json +6 -3
- package/src/cli.ts +1 -1
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[974],{3915:(e,t,r)=>{Promise.resolve().then(r.bind(r,5918))},5918:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>G});var s=r(5155),a=r(2115);let n={id:"dashboard",type:"dashboard"};function o(e){return e.some(e=>"dashboard"===e.id)?e:[n,...e]}function i(e,t){switch(t.type){case"OPEN_PROJECT":{let r=e.tabs.find(e=>e.projectId===t.projectId);if(r)return{tabs:e.tabs.map(e=>e.id===r.id?{...e,initialSubId:t.initialSubId,initialTaskId:t.initialTaskId}:e),activeTabId:r.id};let s={id:t.projectId,type:"project",projectId:t.projectId,projectName:t.projectName,initialSubId:t.initialSubId,initialTaskId:t.initialTaskId};return{tabs:[...e.tabs,s],activeTabId:s.id}}case"CLOSE_TAB":{if("dashboard"===t.tabId)return e;let r=e.tabs.findIndex(e=>e.id===t.tabId),s=e.tabs.filter(e=>e.id!==t.tabId),a=e.activeTabId;return e.activeTabId===t.tabId&&(a=s[Math.max(0,r-1)]?.id||"dashboard"),{tabs:o(s),activeTabId:a}}case"SET_ACTIVE":return{...e,activeTabId:t.tabId};case"UPDATE_TAB_NAME":return{...e,tabs:e.tabs.map(e=>e.id===t.tabId?{...e,projectName:t.name}:e)};case"CONSUME_INITIAL":return{...e,tabs:e.tabs.map(e=>e.id===t.tabId?{...e,initialSubId:void 0,initialTaskId:void 0}:e)};case"HYDRATE":return{tabs:o(t.state.tabs),activeTabId:t.state.activeTabId};default:return e}}let l="im-tabs",d={tabs:[n],activeTabId:"dashboard"};function c(){return d}let u=(0,a.createContext)(null);function x(){let e=(0,a.useContext)(u);if(!e)throw Error("useTabContext must be used within TabProvider");return e}function m({children:e}){let[t,r]=(0,a.useReducer)(i,void 0,c);(0,a.useEffect)(()=>{try{let e=localStorage.getItem(l);if(e){let t=JSON.parse(e);r({type:"HYDRATE",state:{tabs:o(t.tabs),activeTabId:t.activeTabId}})}}catch{}},[]),(0,a.useEffect)(()=>{localStorage.setItem(l,JSON.stringify(t))},[t]),(0,a.useEffect)(()=>{let e=t.tabs.find(e=>e.id===t.activeTabId);if(!e)return;let r="dashboard"===e.type?"/":`/projects/${e.projectId}`;window.location.pathname!==r&&window.history.replaceState(null,"",r)},[t.activeTabId,t.tabs]),(0,a.useEffect)(()=>{let e=window.location.pathname.match(/^\/projects\/(.+)$/);if(e){let s=e[1];t.tabs.some(e=>e.projectId===s)?r({type:"SET_ACTIVE",tabId:s}):fetch(`/api/projects/${s}`).then(e=>e.ok?e.json():null).then(e=>{e&&r({type:"OPEN_PROJECT",projectId:s,projectName:e.name})})}let s=sessionStorage.getItem("im-open-project");s&&(sessionStorage.removeItem("im-open-project"),fetch(`/api/projects/${s}`).then(e=>e.ok?e.json():null).then(e=>{e&&r({type:"OPEN_PROJECT",projectId:s,projectName:e.name})}))},[]);let n=(0,a.useCallback)((e,t,s,a)=>{r({type:"OPEN_PROJECT",projectId:e,projectName:t,initialSubId:s,initialTaskId:a})},[]),d=(0,a.useCallback)(e=>{r({type:"CLOSE_TAB",tabId:e})},[]),x=(0,a.useCallback)(e=>{r({type:"SET_ACTIVE",tabId:e})},[]),m=(0,a.useCallback)((e,t)=>{r({type:"UPDATE_TAB_NAME",tabId:e,name:t})},[]),p=(0,a.useCallback)(e=>{r({type:"CONSUME_INITIAL",tabId:e})},[]),h=(0,a.useCallback)(()=>{let e=t.tabs.findIndex(e=>e.id===t.activeTabId),s=t.tabs[(e+1)%t.tabs.length];s&&r({type:"SET_ACTIVE",tabId:s.id})},[t.tabs,t.activeTabId]),f=(0,a.useCallback)(()=>{let e=t.tabs.findIndex(e=>e.id===t.activeTabId),s=t.tabs[(e-1+t.tabs.length)%t.tabs.length];s&&r({type:"SET_ACTIVE",tabId:s.id})},[t.tabs,t.activeTabId]);return(0,a.useEffect)(()=>{let e=e=>{e.ctrlKey&&"Tab"===e.key&&(e.preventDefault(),e.shiftKey?f():h())};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[h,f]),(0,s.jsx)(u.Provider,{value:{state:t,openProject:n,closeTab:d,setActiveTab:x,updateTabName:m,consumeInitial:p,nextTab:h,prevTab:f},children:e})}function p(){let{state:e,setActiveTab:t,closeTab:r}=x();return(0,s.jsx)("div",{className:"tab-bar",children:e.tabs.map(a=>{let n=e.activeTabId===a.id,o="dashboard"===a.type;return(0,s.jsxs)("div",{onClick:()=>t(a.id),onMouseDown:e=>{1!==e.button||o||(e.preventDefault(),r(a.id))},className:`tab-item ${n?"tab-item-active":""}`,children:[(0,s.jsx)("span",{className:"truncate",children:o?"Dashboard":a.projectName||"Project"}),!o&&(0,s.jsx)("button",{onClick:e=>{e.stopPropagation(),r(a.id)},className:"tab-close",children:"\xd7"})]},a.id)})})}function h({onSelect:e,onCancel:t,initialPath:r}){let[n,o]=(0,a.useState)(null),[i,l]=(0,a.useState)(!0),[d,c]=(0,a.useState)(null),u=(0,a.useCallback)(async e=>{l(!0),c(null);try{let t=e?`?path=${encodeURIComponent(e)}`:"",r=await fetch(`/api/filesystem${t}`);if(r.ok)o(await r.json());else{let e=await r.json();c(e.error||"불러오기 실패")}}catch{c("불러오기 실패")}finally{l(!1)}},[]);return(0,a.useEffect)(()=>{u(r)},[u,r]),(0,s.jsx)("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/50",onClick:t,children:(0,s.jsxs)("div",{className:"bg-card border border-border rounded-lg shadow-xl w-[520px] max-h-[70vh] flex flex-col",onClick:e=>e.stopPropagation(),children:[(0,s.jsxs)("div",{className:"flex items-center justify-between px-4 py-3 border-b border-border",children:[(0,s.jsx)("h3",{className:"text-sm font-semibold",children:"프로젝트 폴더 선택"}),(0,s.jsx)("button",{onClick:t,className:"text-muted-foreground hover:text-foreground text-lg leading-none",children:"\xd7"})]}),(0,s.jsx)("div",{className:"px-4 py-2 border-b border-border bg-muted",children:(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("span",{className:"text-xs text-muted-foreground shrink-0",children:"경로:"}),(0,s.jsx)("span",{className:"text-xs font-mono truncate flex-1",title:n?.current,children:n?.current||"..."}),n?.isProject&&(0,s.jsx)("span",{className:"text-xs text-success shrink-0 font-medium",children:"프로젝트 감지"})]})}),(0,s.jsx)("div",{className:"flex-1 overflow-y-auto min-h-0",children:i?(0,s.jsx)("div",{className:"p-8 text-center text-muted-foreground text-sm",children:"불러오는 중..."}):d?(0,s.jsx)("div",{className:"p-8 text-center text-destructive text-sm",children:d}):(0,s.jsxs)("div",{className:"py-1",children:[n?.parent&&(0,s.jsxs)("button",{onClick:()=>u(n.parent),className:"w-full text-left px-4 py-2 text-sm hover:bg-muted transition-colors flex items-center gap-2 text-muted-foreground",children:[(0,s.jsx)("span",{children:"↑"}),(0,s.jsx)("span",{children:".."})]}),n?.dirs.length===0&&(0,s.jsx)("div",{className:"px-4 py-6 text-center text-muted-foreground text-xs",children:"하위 폴더가 없습니다"}),n?.dirs.map(e=>(0,s.jsxs)("button",{onClick:()=>u(e.path),className:"w-full text-left px-4 py-2 text-sm hover:bg-muted transition-colors flex items-center gap-2",children:[(0,s.jsx)("span",{className:"text-muted-foreground",children:"\uD83D\uDCC1"}),(0,s.jsx)("span",{children:e.name})]},e.path))]})}),(0,s.jsxs)("div",{className:"flex items-center justify-end gap-2 px-4 py-3 border-t border-border",children:[(0,s.jsx)("button",{onClick:t,className:"px-3 py-1.5 text-xs text-muted-foreground hover:text-foreground transition-colors",children:"취소"}),(0,s.jsx)("button",{onClick:()=>n&&e(n.current),disabled:!n,className:"px-4 py-1.5 text-xs bg-primary hover:bg-primary-hover text-white rounded-md transition-colors disabled:opacity-50",children:"이 폴더 선택"})]})]})})}function f({open:e,title:t,description:r,confirmLabel:n="Confirm",cancelLabel:o="Cancel",variant:i="default",onConfirm:l,onCancel:d}){let c=(0,a.useRef)(null),u=(0,a.useRef)(null);(0,a.useEffect)(()=>{e&&c.current?.focus()},[e]);let x=(0,a.useCallback)(t=>{e&&("Escape"===t.key&&d(),"Enter"===t.key&&l())},[e,d,l]);return((0,a.useEffect)(()=>(window.addEventListener("keydown",x),()=>window.removeEventListener("keydown",x)),[x]),e)?(0,s.jsx)("div",{ref:u,onClick:e=>{e.target===u.current&&d()},className:"fixed inset-0 z-50 flex items-center justify-center",style:{background:"rgba(0,0,0,0.5)",backdropFilter:"blur(2px)"},children:(0,s.jsxs)("div",{className:"bg-card border border-border rounded-xl shadow-2xl shadow-black/40 w-full max-w-sm mx-4 animate-dialog-in",children:[(0,s.jsxs)("div",{className:"p-5",children:[(0,s.jsx)("h3",{className:"text-sm font-semibold text-foreground",children:t}),r&&(0,s.jsx)("p",{className:"text-xs text-muted-foreground mt-1.5 leading-relaxed",children:r})]}),(0,s.jsxs)("div",{className:"flex justify-end gap-2 px-5 pb-4",children:[(0,s.jsx)("button",{onClick:d,className:"px-3 py-1.5 text-xs text-muted-foreground hover:text-foreground bg-muted hover:bg-card-hover border border-border rounded-md transition-colors",children:o}),(0,s.jsx)("button",{ref:c,onClick:l,className:`px-3 py-1.5 text-xs text-white rounded-md transition-colors ${"danger"===i?"bg-destructive hover:bg-destructive/80":"bg-primary hover:bg-primary-hover"}`,children:n})]})]})}):null}let b=[{key:"active",label:"Active"},{key:"all",label:"All"},{key:"today",label:"Today"},{key:"archive",label:"Archive"}];function g({value:e,onChange:t}){let[r,n]=(0,a.useState)(!1);return((0,a.useEffect)(()=>n(!0),[]),r)?(0,s.jsx)("div",{className:"flex gap-1 bg-muted rounded-lg p-1",children:b.map(r=>(0,s.jsx)("button",{onClick:()=>t(r.key),className:`px-4 py-1.5 text-sm rounded-md transition-all ${e===r.key?"bg-card text-foreground shadow-sm font-medium":"text-muted-foreground hover:text-foreground"}`,children:r.label},r.key))}):null}let j={idea:"\uD83D\uDCA1",writing:"✏️",submitted:"\uD83D\uDE80",testing:"\uD83E\uDDEA",done:"✅",problem:"\uD83D\uDD34"};function y({subProject:e,projectName:t,onClick:r}){let{active_count:a,pending_count:n,done_count:o,problem_count:i,task_count:l,preview_tasks:d,last_activity:c}=e;return(0,s.jsxs)("div",{onClick:r,className:"p-4 bg-card hover:bg-card-hover border border-border rounded-xl cursor-pointer transition-all group hover:border-muted-foreground/30 hover:shadow-md hover:shadow-black/20",children:[(0,s.jsxs)("div",{className:"flex items-start justify-between mb-2",children:[(0,s.jsx)("h3",{className:"text-sm font-semibold group-hover:text-primary transition-colors truncate flex-1",children:e.name}),(0,s.jsx)("span",{className:"text-xs text-muted-foreground ml-2 flex-shrink-0",children:t})]}),d.length>0&&(0,s.jsx)("div",{className:"space-y-1 mb-3",children:d.map((e,t)=>(0,s.jsxs)("div",{className:"flex items-center gap-2 text-xs",children:[(0,s.jsx)("span",{className:"flex-shrink-0",children:j[e.status]}),(0,s.jsx)("span",{className:`truncate ${"done"===e.status?"text-muted-foreground line-through":"text-foreground"}`,children:e.title})]},t))}),(0,s.jsxs)("div",{className:"flex items-center justify-between text-xs text-muted-foreground",children:[(0,s.jsxs)("div",{className:"flex items-center gap-3",children:[a>0&&(0,s.jsxs)("span",{className:"text-primary",children:["active ",a]}),n>0&&(0,s.jsxs)("span",{children:["pending ",n]}),o>0&&(0,s.jsxs)("span",{className:"text-success",children:["done ",o]}),i>0&&(0,s.jsxs)("span",{className:"text-destructive",children:["problem ",i]}),0===l&&(0,s.jsx)("span",{children:"no tasks"})]}),c&&(0,s.jsx)("span",{children:function(e){if(!e)return"";let t=Math.floor((Date.now()-new Date(e).getTime())/6e4);if(t<1)return"just now";if(t<60)return`${t}m ago`;let r=Math.floor(t/60);if(r<24)return`${r}h ago`;let s=Math.floor(r/24);return`${s}d ago`}(c)})]})]})}function v(){let e,{state:t,openProject:r,closeTab:n}=x(),o="dashboard"===t.activeTabId,[i,l]=(0,a.useState)([]),[d,c]=(0,a.useState)([]),[u,m]=(0,a.useState)(!1),[p,b]=(0,a.useState)(""),[j,v]=(0,a.useState)(""),[N,k]=(0,a.useState)(""),[w,C]=(0,a.useState)(!0),[S,T]=(0,a.useState)(!1),[I,E]=(0,a.useState)(null),[$,_]=(0,a.useState)([]),[P,D]=(0,a.useState)(""),[A,O]=(0,a.useState)(!1),[R,L]=(0,a.useState)(null),[M,J]=(0,a.useState)(!1),[F,K]=(0,a.useState)(""),[z,U]=(0,a.useState)(""),[B,G]=(0,a.useState)(()=>"true"===localStorage.getItem("im-memo-open")),V=(0,a.useRef)(null),[H,W]=(0,a.useState)(()=>localStorage.getItem("im-dashboard-tab")||"active"),X=(0,a.useCallback)(async()=>{let e=await fetch("/api/projects"),t=await e.json(),r=await Promise.all(t.map(async e=>{let t=await fetch(`/api/projects/${e.id}/sub-projects`),r=await t.json();return{...e,subProjects:r}}));l(r);let s=[];for(let e of r)for(let t of e.subProjects)if(t.task_count>0){let r=await fetch(`/api/projects/${e.id}/sub-projects/${t.id}/tasks`);for(let a of(await r.json()))a.is_today&&s.push({...a,projectName:e.name,subProjectName:t.name})}c(s),C(!1)},[]);(0,a.useEffect)(()=>{X(),fetch("/api/global-memo").then(e=>e.json()).then(e=>D(e.content||""))},[X]),(0,a.useEffect)(()=>{o&&!w&&X()},[o]);let Y=(0,a.useCallback)(async()=>{let e=await fetch("/api/archive");_((await e.json()).map(e=>{let t=i.find(t=>t.id===e.project_id),r=t?.subProjects.find(t=>t.id===e.sub_project_id);return{...e,projectName:t?.name,subProjectName:r?.name}}))},[i]),q=async()=>{O(!0),K("");let e=await fetch("/api/sync");L(await e.json())},Q=async e=>{J(!0),K("");try{let t=await fetch("/api/sync",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({action:e,repoUrl:z})}),r=await t.json();if(t.ok){if(K(r.message||"Success"),"init"===e){let e=await fetch("/api/sync").then(e=>e.json());L(e)}"pull"===e&&X()}else K(`Error: ${r.error}`)}catch{K("Error: request failed")}J(!1)},Z=async e=>{if(e.preventDefault(),!p.trim())return;let t=await fetch("/api/projects",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:p.trim(),description:j.trim(),project_path:N.trim()||void 0})});if(t.ok){let e=await t.json();b(""),v(""),k(""),m(!1),r(e.id,e.name)}},ee=async()=>{I&&(await fetch(`/api/projects/${I}`,{method:"DELETE"}),n(I),E(null),X())},et={idea:"\uD83D\uDCA1",writing:"✏️",submitted:"\uD83D\uDE80",testing:"\uD83E\uDDEA",done:"✅",problem:"\uD83D\uDD34"};return(0,s.jsxs)("div",{className:"h-full overflow-y-auto p-8 w-full max-w-5xl mx-auto",children:[(0,s.jsxs)("header",{className:"flex items-center justify-between mb-6",children:[(0,s.jsx)("div",{children:(0,s.jsxs)("h1",{className:"text-2xl font-bold tracking-tight",children:["IM ",(0,s.jsx)("span",{className:"text-muted-foreground font-normal text-sm ml-2",children:"Idea Manager v2"})]})}),(0,s.jsxs)("div",{className:"flex items-center gap-3",children:[(0,s.jsx)(g,{value:H,onChange:e=>{W(e),localStorage.setItem("im-dashboard-tab",e),"archive"===e&&Y()}}),(0,s.jsx)("button",{onClick:q,className:"px-3 py-2 text-sm border rounded-lg transition-colors bg-muted hover:bg-card-hover text-muted-foreground border-border",title:"DB Sync via Git",children:"Sync"}),(0,s.jsx)("button",{onClick:()=>{let e=!B;G(e),localStorage.setItem("im-memo-open",String(e))},className:`px-3 py-2 text-sm border rounded-lg transition-colors ${B?"bg-accent/15 text-accent border-accent/30 hover:bg-accent/25":"bg-muted hover:bg-card-hover text-muted-foreground border-border"}`,title:"Quick memo",children:"Memo"}),(0,s.jsx)("button",{onClick:()=>m(!u),className:"px-4 py-2 bg-primary hover:bg-primary-hover text-white rounded-lg transition-colors font-medium text-sm",children:"+ Project"})]})]}),B&&(0,s.jsxs)("div",{className:"mb-6 bg-card rounded-lg border border-border overflow-hidden",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between px-4 py-2 border-b border-border",children:[(0,s.jsx)("span",{className:"text-xs font-medium text-muted-foreground uppercase tracking-wider",children:"Quick Memo"}),(0,s.jsx)("span",{className:"text-[10px] text-muted-foreground",children:"auto-saved"})]}),(0,s.jsx)("textarea",{value:P,onChange:e=>{var t;D(t=e.target.value),V.current&&clearTimeout(V.current),V.current=setTimeout(()=>{fetch("/api/global-memo",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({content:t})})},500)},placeholder:"자유롭게 메모하세요...",className:"w-full bg-transparent px-4 py-3 text-sm text-foreground resize-none focus:outline-none leading-relaxed font-mono min-h-[150px] max-h-[400px]",style:{height:Math.max(150,Math.min(400,(P.split("\n").length+1)*22))}})]}),u&&(0,s.jsxs)("form",{onSubmit:Z,className:"mb-6 p-5 bg-card rounded-lg border border-border",children:[(0,s.jsx)("input",{type:"text",placeholder:"Project name",value:p,onChange:e=>b(e.target.value),className:"w-full bg-input border border-border rounded-lg px-4 py-2.5 mb-3 focus:border-primary focus:outline-none text-foreground",autoFocus:!0}),(0,s.jsx)("input",{type:"text",placeholder:"Description (optional)",value:j,onChange:e=>v(e.target.value),className:"w-full bg-input border border-border rounded-lg px-4 py-2.5 mb-3 focus:border-primary focus:outline-none text-foreground"}),(0,s.jsx)("div",{className:"mb-4",children:(0,s.jsx)("button",{type:"button",onClick:()=>T(!0),className:"w-full bg-input border border-border rounded-lg px-4 py-2.5 text-left text-sm hover:border-primary transition-colors",children:N?(0,s.jsx)("span",{className:"font-mono text-foreground",children:N}):(0,s.jsx)("span",{className:"text-muted-foreground",children:"Project folder (optional)"})})}),(0,s.jsxs)("div",{className:"flex gap-2 justify-end",children:[(0,s.jsx)("button",{type:"button",onClick:()=>m(!1),className:"px-4 py-2 text-muted-foreground hover:text-foreground transition-colors text-sm",children:"Cancel"}),(0,s.jsx)("button",{type:"submit",className:"px-4 py-2 bg-primary hover:bg-primary-hover text-white rounded-lg transition-colors text-sm",children:"Create"})]})]}),w?(0,s.jsx)("div",{className:"text-center text-muted-foreground py-20",children:"Loading..."}):"archive"===H?0===$.length?(0,s.jsxs)("div",{className:"text-center py-20 text-muted-foreground",children:[(0,s.jsx)("p",{className:"text-lg mb-2",children:"No archived tasks"}),(0,s.jsx)("p",{className:"text-sm",children:"Archived tasks will appear here"})]}):(0,s.jsx)("div",{className:"space-y-2",children:$.map(e=>(0,s.jsxs)("div",{className:"flex items-center gap-3 p-3 bg-card border border-border rounded-lg transition-colors group",children:[(0,s.jsx)("span",{className:"text-sm",children:et[e.status]}),(0,s.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,s.jsx)("span",{className:"text-sm font-medium",children:e.title}),(0,s.jsxs)("span",{className:"text-xs text-muted-foreground ml-2",children:[e.projectName,e.subProjectName?` / ${e.subProjectName}`:""]}),e.description&&(0,s.jsx)("p",{className:"text-xs text-muted-foreground mt-0.5 truncate",children:e.description})]}),(0,s.jsxs)("div",{className:"flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity",children:[(0,s.jsx)("button",{onClick:async()=>{await fetch("/api/archive",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({taskId:e.id,action:"restore"})}),Y(),X()},className:"px-2 py-1 text-xs text-primary hover:bg-primary/10 rounded transition-colors",children:"Restore"}),(0,s.jsx)("button",{onClick:async()=>{await fetch("/api/archive",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({taskId:e.id,action:"delete"})}),Y()},className:"px-2 py-1 text-xs text-destructive hover:bg-destructive/10 rounded transition-colors",children:"Delete"})]})]},e.id))}):"today"===H?0===d.length?(0,s.jsxs)("div",{className:"text-center py-20 text-muted-foreground",children:[(0,s.jsx)("p",{className:"text-lg mb-2",children:"No tasks marked for today"}),(0,s.jsx)("p",{className:"text-sm",children:"Mark tasks with the Today button in task detail"})]}):(0,s.jsx)("div",{className:"space-y-2",children:d.map(e=>(0,s.jsxs)("div",{onClick:()=>r(e.project_id,e.projectName,e.sub_project_id,e.id),className:"flex items-center gap-3 p-3 bg-card hover:bg-card-hover border border-border rounded-lg cursor-pointer transition-colors",children:[(0,s.jsx)("span",{className:"text-sm",children:et[e.status]}),(0,s.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,s.jsx)("span",{className:"text-sm font-medium",children:e.title}),(0,s.jsxs)("span",{className:"text-xs text-muted-foreground ml-2",children:[e.projectName," / ",e.subProjectName]})]})]},e.id))}):(0,s.jsx)(s.Fragment,{children:"all"===H?0===i.length?(0,s.jsxs)("div",{className:"text-center py-20",children:[(0,s.jsx)("p",{className:"text-muted-foreground text-lg mb-2",children:"No projects yet"}),(0,s.jsx)("p",{className:"text-muted-foreground text-sm",children:"Click + Project to get started"})]}):(0,s.jsx)("div",{className:"space-y-6",children:i.map(e=>(0,s.jsxs)("div",{children:[(0,s.jsxs)("div",{className:"flex items-center justify-between mb-3",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2 cursor-pointer hover:text-primary transition-colors",onClick:()=>r(e.id,e.name),children:[(0,s.jsx)("h2",{className:"text-sm font-semibold",children:e.name}),e.project_path&&(0,s.jsx)("span",{className:"text-xs text-muted-foreground font-mono truncate max-w-48",children:e.project_path})]}),(0,s.jsx)("button",{onClick:t=>{var r;return r=e.id,void(t.stopPropagation(),E(r))},className:"text-xs text-muted-foreground hover:text-destructive transition-colors",children:"Delete"})]}),0===e.subProjects.length?(0,s.jsxs)("div",{className:"text-xs text-muted-foreground py-4 text-center border border-dashed border-border rounded-lg",children:["No sub-projects."," ",(0,s.jsx)("span",{className:"text-primary cursor-pointer hover:underline",onClick:()=>r(e.id,e.name),children:"Open project"})," ","to add one."]}):(0,s.jsx)("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3",children:e.subProjects.map(t=>(0,s.jsx)(y,{subProject:t,projectName:e.name,onClick:()=>r(e.id,e.name,t.id)},t.id))})]},e.id))}):0===(e=(()=>{let e=[];for(let t of i)for(let r of t.subProjects)"active"===H?(r.active_count>0||r.problem_count>0)&&e.push({sp:r,projectName:t.name,projectId:t.id}):"all"===H&&e.push({sp:r,projectName:t.name,projectId:t.id});return e.sort((e,t)=>t.sp.active_count+t.sp.problem_count-(e.sp.active_count+e.sp.problem_count)),e})()).length?(0,s.jsxs)("div",{className:"text-center py-20 text-muted-foreground",children:[(0,s.jsx)("p",{className:"text-lg mb-2",children:"No active tasks"}),(0,s.jsx)("p",{className:"text-sm",children:"Submit tasks to see them here"})]}):(0,s.jsx)("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3",children:e.map(({sp:e,projectName:t,projectId:a})=>(0,s.jsx)(y,{subProject:e,projectName:t,onClick:()=>{let s=i.find(e=>e.id===a);r(a,s?.name||t,e.id)}},e.id))})}),S&&(0,s.jsx)(h,{onSelect:e=>{k(e),T(!1)},onCancel:()=>T(!1)}),A&&(0,s.jsxs)("div",{className:"fixed inset-0 z-50 flex items-center justify-center",children:[(0,s.jsx)("div",{className:"absolute inset-0 bg-black/60 backdrop-blur-sm",onClick:()=>O(!1)}),(0,s.jsxs)("div",{className:"relative bg-card border border-border rounded-xl shadow-2xl w-[480px] animate-dialog-in",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between px-5 py-3 border-b border-border",children:[(0,s.jsx)("h3",{className:"text-sm font-semibold",children:"DB Sync"}),(0,s.jsx)("button",{onClick:()=>O(!1),className:"text-muted-foreground hover:text-foreground text-lg px-1",children:"x"})]}),(0,s.jsxs)("div",{className:"p-5 space-y-4",children:[null===R?(0,s.jsx)("p",{className:"text-sm text-muted-foreground",children:"Loading..."}):R.initialized?(0,s.jsxs)("div",{className:"space-y-3",children:[(0,s.jsxs)("div",{className:"text-xs space-y-1",children:[(0,s.jsxs)("p",{children:[(0,s.jsx)("span",{className:"text-muted-foreground",children:"Remote:"})," ",(0,s.jsx)("span",{className:"font-mono",children:R.remoteUrl||"none"})]}),(0,s.jsxs)("p",{children:[(0,s.jsx)("span",{className:"text-muted-foreground",children:"Last sync:"})," ",R.lastCommit||"never"]})]}),(0,s.jsxs)("div",{className:"flex gap-2",children:[(0,s.jsx)("button",{onClick:()=>Q("push"),disabled:M,className:"flex-1 px-4 py-2 text-sm bg-primary text-white rounded-lg hover:bg-primary-hover transition-colors disabled:opacity-50",children:M?"...":"Push"}),(0,s.jsx)("button",{onClick:()=>Q("pull"),disabled:M,className:"flex-1 px-4 py-2 text-sm bg-muted text-foreground border border-border rounded-lg hover:bg-card-hover transition-colors disabled:opacity-50",children:M?"...":"Pull"})]})]}):(0,s.jsxs)("div",{className:"space-y-3",children:[(0,s.jsx)("p",{className:"text-sm text-muted-foreground",children:"Git 저장소 URL을 입력하세요."}),(0,s.jsx)("input",{value:z,onChange:e=>U(e.target.value),placeholder:"https://github.com/user/repo.git",className:"w-full bg-input border border-border rounded-lg px-3 py-2 text-sm focus:border-primary focus:outline-none text-foreground"}),(0,s.jsx)("button",{onClick:()=>Q("init"),disabled:M||!z.trim(),className:"w-full px-4 py-2 text-sm bg-primary text-white rounded-lg hover:bg-primary-hover transition-colors disabled:opacity-50",children:M?"Initializing...":"Initialize"})]}),F&&(0,s.jsx)("p",{className:`text-xs ${F.startsWith("Error")?"text-destructive":"text-success"}`,children:F})]})]})]}),(0,s.jsx)(f,{open:!!I,title:"Delete project?",description:"This will permanently delete the project and all its data.",confirmLabel:"Delete",variant:"danger",onConfirm:ee,onCancel:()=>E(null)})]})}function N({projectId:e,onCollapse:t}){let[r,n]=(0,a.useState)(""),[o,i]=(0,a.useState)(!1),[l,d]=(0,a.useState)(!1),c=(0,a.useRef)(null),u=(0,a.useRef)(null);(0,a.useEffect)(()=>{(async()=>{let t=await fetch(`/api/projects/${e}/brainstorm`);n((await t.json()).content||""),d(!0)})()},[e]);let x=(0,a.useCallback)(async t=>{i(!0),await fetch(`/api/projects/${e}/brainstorm`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({content:t})}),i(!1)},[e]);return l?(0,s.jsxs)("div",{className:"flex flex-col h-full",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between px-4 py-2 border-b border-border",children:[(0,s.jsx)("h2",{className:"text-sm font-medium text-muted-foreground",children:"BRAINSTORMING"}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("span",{className:"text-xs text-muted-foreground",children:o?"저장 중...":r?"저장됨":""}),t&&(0,s.jsx)("button",{onClick:t,className:"text-muted-foreground hover:text-foreground transition-colors text-xs px-1",title:"접기 (B)",children:"\xab"})]})]}),(0,s.jsx)("div",{className:"editor-container",children:(0,s.jsx)("textarea",{ref:u,value:r,onChange:e=>{let t=e.target.value;n(t),c.current&&clearTimeout(c.current),c.current=setTimeout(()=>{x(t)},1e3)},placeholder:`자유롭게 아이디어를 적어보세요...
|
|
2
|
+
|
|
3
|
+
예시:
|
|
4
|
+
- 소셜 로그인을 활용한 사용자 인증
|
|
5
|
+
- 분석 차트가 포함된 대시보드
|
|
6
|
+
- 알림 시스템 필요 (푸시 + 이메일)
|
|
7
|
+
- 다크 모드 지원
|
|
8
|
+
- 모바일 반응형 디자인 중요`,className:"flex-1 w-full p-4 bg-transparent resize-none text-foreground placeholder:text-muted-foreground/40 font-mono text-sm leading-relaxed",spellCheck:!1})})]}):(0,s.jsx)("div",{className:"flex items-center justify-center h-full text-muted-foreground",children:"로딩 중..."})}var k=r(4923),w=r(7256),C=r(9768);let S=[{key:"idea",label:"Idea",icon:"\uD83D\uDCA1",color:"text-muted-foreground"},{key:"writing",label:"Writing",icon:"✏️",color:"text-warning"},{key:"submitted",label:"Submitted",icon:"\uD83D\uDE80",color:"text-primary"},{key:"testing",label:"Testing",icon:"\uD83E\uDDEA",color:"text-accent"},{key:"done",label:"Done",icon:"✅",color:"text-success"},{key:"problem",label:"Problem",icon:"\uD83D\uDD34",color:"text-destructive"}];function T({status:e,onChange:t}){return(0,s.jsx)("div",{className:"flex items-center gap-1",children:S.map(r=>(0,s.jsx)("button",{onClick:()=>t(r.key),title:r.label,className:`px-2 py-1 rounded text-base transition-all ${e===r.key?`${r.color} bg-muted scale-110`:"opacity-40 hover:opacity-80"}`,children:r.icon},r.key))})}function I(e){return S.find(t=>t.key===e)?.icon??""}let E={high:"bg-destructive",medium:"bg-warning",low:"bg-muted-foreground"};function $({subProjects:e,tasks:t,selectedSubId:r,selectedTaskId:n,onSelectSub:o,onSelectTask:i,onCreateSub:l,onDeleteSub:d,onCreateTask:c,onStatusChange:u,onTodayToggle:x,onDeleteTask:m,onReorderSubs:p,onAutoDistribute:h,chatStates:f}){let[b,g]=(0,a.useState)(new Set),[j,y]=(0,a.useState)(null),[v,N]=(0,a.useState)(""),C=(0,k.FR)((0,k.MS)(k.AN,{activationConstraint:{distance:5}}),(0,k.MS)(k.uN,{coordinateGetter:w.JR})),S=e=>{g(t=>{let r=new Set(t);return r.has(e)?r.delete(e):r.add(e),r})},T=e=>{let t=v.trim();t&&(o(e),c(t),N(""),y(null))};return(0,s.jsxs)("div",{className:"flex flex-col h-full",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between px-3 py-2 border-b border-border flex-shrink-0",children:[(0,s.jsx)("h2",{className:"text-xs font-medium text-muted-foreground uppercase tracking-wider",children:"Projects"}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("button",{onClick:()=>{g(e.length>0&&e.every(e=>b.has(e.id))?new Set:new Set(e.map(e=>e.id)))},className:"text-xs text-muted-foreground hover:text-foreground transition-colors",title:e.length>0&&e.every(e=>b.has(e.id))?"Expand all":"Collapse all",children:e.length>0&&e.every(e=>b.has(e.id))?"▶":"▼"}),h&&(0,s.jsx)("button",{onClick:h,className:"text-[10px] px-1.5 py-0.5 bg-accent/15 text-accent border border-accent/30 rounded hover:bg-accent/25 transition-colors",title:"AI auto-distribute brainstorming to tasks",children:"Auto"}),(0,s.jsxs)("button",{onClick:l,className:"text-xs text-muted-foreground hover:text-foreground transition-colors",title:"Add sub-project (N)",children:["+ ",(0,s.jsx)("span",{className:"text-muted-foreground/50",children:"N"})]})]})]}),(0,s.jsxs)("div",{className:"flex-1 overflow-y-auto py-1",children:[0===e.length&&(0,s.jsx)("div",{className:"text-center py-8 text-muted-foreground text-xs",children:"Create a sub-project to get started"}),(0,s.jsx)(k.Mp,{sensors:C,collisionDetection:k.fp,onDragEnd:t=>{let{active:r,over:s}=t;if(!s||r.id===s.id||!p)return;let a=e.findIndex(e=>e.id===r.id),n=e.findIndex(e=>e.id===s.id);if(-1===a||-1===n)return;let o=[...e],[i]=o.splice(a,1);o.splice(n,0,i),p(o.map(e=>e.id))},children:(0,s.jsx)(w.gB,{items:e.map(e=>e.id),strategy:w._G,children:e.map(e=>(0,s.jsx)(_,{sp:e,isSelected:r===e.id,isCollapsed:b.has(e.id),tasks:r===e.id?t:[],selectedTaskId:n,addingTaskFor:j,newTaskTitle:v,onSelectSub:o,onSelectTask:i,onToggleCollapse:S,onDeleteSub:d,onStatusChange:u,onTodayToggle:x,onDeleteTask:m,onAddTask:T,onSetAddingTaskFor:y,onSetNewTaskTitle:N,chatStates:f},e.id))})})]})]})}function _({sp:e,isSelected:t,isCollapsed:r,tasks:a,selectedTaskId:n,addingTaskFor:o,newTaskTitle:i,onSelectSub:l,onSelectTask:d,onToggleCollapse:c,onDeleteSub:u,onStatusChange:x,onTodayToggle:m,onDeleteTask:p,onAddTask:h,onSetAddingTaskFor:f,onSetNewTaskTitle:b,chatStates:g}){let j,{attributes:y,listeners:v,setNodeRef:N,transform:k,transition:S,isDragging:T}=(0,w.gl)({id:e.id}),$={transform:C.Ks.Transform.toString(k),transition:S,opacity:T?.5:1,zIndex:T?10:void 0};return(0,s.jsxs)("div",{ref:N,style:$,className:"mb-0.5",children:[(0,s.jsxs)("div",{onClick:()=>{t?c(e.id):(l(e.id),r&&c(e.id))},className:`flex items-center gap-1.5 px-2 py-1.5 cursor-pointer transition-colors group text-sm ${t?"text-foreground":"text-muted-foreground hover:text-foreground"}`,children:[(0,s.jsx)("span",{...y,...v,className:"w-4 h-4 flex items-center justify-center text-xs text-muted-foreground/40 hover:text-muted-foreground cursor-grab active:cursor-grabbing flex-shrink-0",title:"Drag to reorder",onClick:e=>e.stopPropagation(),children:"⠿"}),(0,s.jsx)("button",{onClick:t=>{t.stopPropagation(),c(e.id)},className:"w-4 h-4 flex items-center justify-center text-xs text-muted-foreground flex-shrink-0",children:r?"▶":"▼"}),(j=0===e.task_count?null:e.problem_count>0?{dotClass:"bg-destructive",label:`${e.problem_count}!`,title:`${e.problem_count} problem`}:e.done_count===e.task_count?{dotClass:"bg-success",label:`${e.done_count}/${e.task_count}`,title:"All done"}:e.done_count>0?{dotClass:"bg-primary",label:`${e.done_count}/${e.task_count}`,title:`${e.done_count} done, ${e.active_count} active`}:e.active_count>0?{dotClass:"bg-warning",label:`${e.active_count}`,title:`${e.active_count} in progress`}:null)?(0,s.jsx)("span",{className:`w-2 h-2 rounded-full ${j.dotClass} flex-shrink-0`,title:j.title}):null,(0,s.jsx)("span",{className:`flex-1 truncate font-medium ${t?"text-primary":""}`,children:e.name}),(0,s.jsxs)("div",{className:"flex items-center gap-1.5",children:[e.task_count>0&&(0,s.jsx)("span",{className:"text-xs text-muted-foreground tabular-nums",children:e.task_count}),(0,s.jsx)("button",{onClick:t=>{t.stopPropagation(),u(e.id)},className:"text-muted-foreground hover:text-destructive opacity-0 group-hover:opacity-100 transition-opacity text-xs",children:"x"})]})]}),!r&&t&&(0,s.jsxs)("div",{className:"ml-3 border-l border-border/50",children:[0===a.length&&!o&&(0,s.jsx)("div",{className:"text-xs text-muted-foreground py-2 pl-4",children:"No tasks"}),a.map(e=>(0,s.jsxs)("div",{onClick:()=>d(e.id),className:`group/task flex items-center gap-1.5 pl-4 pr-2 py-1.5 cursor-pointer transition-colors text-sm border-l-2 ${n===e.id?"bg-card-hover border-l-primary":"border-l-transparent hover:bg-card-hover/50"}`,children:[(0,s.jsx)("button",{onClick:t=>{var r;let s,a;t.stopPropagation();let n=(r=e.status,-1===(a=(s=["idea","writing","submitted","testing","done"]).indexOf(r))?"idea":s[(a+1)%s.length]);x(e.id,n)},className:"flex-shrink-0 text-sm",title:`Status: ${e.status}`,children:I(e.status)}),(0,s.jsx)("span",{className:`tree-priority-dot ${E[e.priority]}`}),(0,s.jsx)("span",{className:`flex-1 truncate ${"done"===e.status?"text-muted-foreground line-through":""}`,children:e.title}),g?.[e.id]==="loading"&&(0,s.jsxs)("span",{className:"flex-shrink-0 flex items-center gap-1 text-[10px] text-warning",title:"AI 응답 대기 중",children:[(0,s.jsx)("span",{className:"inline-block w-1.5 h-1.5 rounded-full bg-warning animate-pulse"}),"AI..."]}),g?.[e.id]==="done"&&(0,s.jsx)("span",{className:"flex-shrink-0 text-[10px] text-success",title:"AI 응답 완료",children:"✓"}),e.is_today&&(0,s.jsx)("button",{onClick:t=>{t.stopPropagation(),m(e.id,!1)},className:"text-xs flex-shrink-0 text-primary",title:"Remove from today",children:"*"}),(0,s.jsx)("button",{onClick:t=>{t.stopPropagation(),p(e.id)},className:"flex-shrink-0 text-muted-foreground/0 group-hover/task:text-muted-foreground hover:!text-destructive transition-colors text-xs px-0.5",title:"Delete task",children:"\xd7"})]},e.id)),o===e.id?(0,s.jsx)("div",{className:"pl-4 pr-2 py-1",children:(0,s.jsx)("input",{type:"text",value:i,onChange:e=>b(e.target.value),onKeyDown:t=>{"Enter"===t.key&&h(e.id),"Escape"===t.key&&(b(""),f(null))},placeholder:"Task title...",className:"w-full bg-input border border-border rounded px-2 py-1 text-sm focus:border-primary focus:outline-none text-foreground",autoFocus:!0})}):(0,s.jsxs)("button",{"data-add-task":!0,onClick:()=>{l(e.id),f(e.id)},className:"pl-4 pr-2 py-1 text-xs text-muted-foreground hover:text-foreground transition-colors text-left w-full",children:["+ Add task ",(0,s.jsx)("span",{className:"text-muted-foreground/50 ml-1",children:"T"})]})]}),!r&&!t&&e.preview_tasks&&e.preview_tasks.length>0&&(0,s.jsx)("div",{className:"ml-3 border-l border-border/50",children:e.preview_tasks.map((t,r)=>(0,s.jsxs)("div",{onClick:()=>l(e.id),className:"flex items-center gap-1.5 pl-4 pr-2 py-1 cursor-pointer text-xs text-muted-foreground hover:text-foreground transition-colors",children:[(0,s.jsx)("span",{className:"flex-shrink-0",children:I(t.status)}),(0,s.jsx)("span",{className:"truncate",children:t.title})]},r))})]})}function P({content:e,onSave:t,onRefine:r,refining:n}){let[o,i]=(0,a.useState)(!1),[l,d]=(0,a.useState)(e),[c,u]=(0,a.useState)(!1),x=(0,a.useRef)(null);(0,a.useEffect)(()=>{d(e)},[e]),(0,a.useEffect)(()=>{o&&x.current&&(x.current.focus(),x.current.style.height="auto",x.current.style.height=x.current.scrollHeight+"px")},[o]);let m=()=>{t(l),i(!1)},p=async()=>{e&&(await navigator.clipboard.writeText(e),u(!0),setTimeout(()=>u(!1),1500))};return(0,s.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between",children:[(0,s.jsx)("h4",{className:"text-xs font-medium text-muted-foreground uppercase tracking-wider",children:"Prompt"}),(0,s.jsxs)("div",{className:"flex items-center gap-1.5",children:[r&&(0,s.jsx)("button",{onClick:r,disabled:n,className:"prompt-action-btn prompt-generate-btn",children:n?"Refining...":"AI Refine"}),!o&&e&&(0,s.jsx)("button",{onClick:p,className:"prompt-action-btn",children:c?"Copied!":"Copy"}),o?(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)("button",{onClick:()=>{d(e),i(!1)},className:"prompt-action-btn",children:"Cancel"}),(0,s.jsx)("button",{onClick:m,className:"prompt-action-btn",style:{color:"hsl(var(--success))"},children:"Save"})]}):(0,s.jsx)("button",{onClick:()=>i(!0),className:"prompt-action-btn",children:"Edit"})]})]}),o?(0,s.jsx)("textarea",{ref:x,value:l,onChange:e=>{d(e.target.value),e.target.style.height="auto",e.target.style.height=e.target.scrollHeight+"px"},onKeyDown:t=>{"Escape"===t.key&&(d(e),i(!1)),(t.metaKey||t.ctrlKey)&&"Enter"===t.key&&m()},className:"prompt-edit-textarea",rows:4,placeholder:"Write your prompt here..."}):e?(0,s.jsx)("div",{className:"prompt-content text-sm",children:e}):(0,s.jsx)("div",{className:"text-sm text-muted-foreground italic py-6 text-center border border-dashed border-border rounded-lg",children:"No prompt yet. Click Edit to write one."})]})}var D=r(8426),A=r(2957);function O({basePath:e,taskStatus:t,onApplyToPrompt:r,onChatStateChange:n}){let[o,i]=(0,a.useState)([]),[l,d]=(0,a.useState)(""),[c,u]=(0,a.useState)(!1),x=(0,a.useRef)(null),m=(0,a.useRef)(null),p=(0,a.useRef)(e);(0,a.useEffect)(()=>{p.current=e,i([]),u(!1)},[e]),(0,a.useEffect)(()=>{"u">typeof Notification&&"default"===Notification.permission&&Notification.requestPermission()},[]);let h=(0,a.useCallback)(()=>{fetch(`${e}/chat`).then(e=>e.json()).then(t=>{p.current===e&&Array.isArray(t)&&i(t)})},[e]);(0,a.useEffect)(()=>{h()},[h]),(0,a.useEffect)(()=>{if("testing"!==t)return;let e=setInterval(h,3e3);return()=>clearInterval(e)},[t,h]),(0,a.useEffect)(()=>{x.current?.scrollIntoView({behavior:"smooth"})},[o]);let f=(0,a.useCallback)(async()=>{let t=l.trim();if(!t||c)return;d(""),u(!0),n?.("loading");let r=`temp-${Date.now()}`,s={id:r,task_id:"",role:"user",content:t,created_at:new Date().toISOString()};i(e=>[...e,s]);try{let s=await fetch(`${e}/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({message:t})});if(p.current!==e)return void n?.("done");if(s.ok){var a;let e=await s.json();i(t=>[...t.filter(e=>e.id!==r),e.userMessage,e.aiMessage]),e.aiMessage?.content&&(a=e.aiMessage.content,document.hasFocus()||"granted"===Notification.permission&&new Notification("IM - AI Response",{body:a.slice(0,120),icon:"/icon-192.png"}))}}catch{}p.current===e&&(u(!1),m.current?.focus()),n?.("done")},[l,c,e,n]);return(0,s.jsxs)("div",{className:"flex flex-col h-full border-t border-border",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between px-3 py-1.5 border-b border-border",children:[(0,s.jsx)("span",{className:"text-xs font-medium text-muted-foreground uppercase tracking-wider",children:"AI Chat"}),"testing"===t&&(0,s.jsxs)("span",{className:"flex items-center gap-1.5 text-xs text-warning",children:[(0,s.jsx)("span",{className:"inline-block w-2 h-2 rounded-full bg-warning animate-pulse"}),"Executing..."]})]}),(0,s.jsxs)("div",{className:"flex-1 overflow-y-auto px-3 py-2 space-y-2 min-h-0",children:[0===o.length&&!c&&(0,s.jsx)("div",{className:"text-sm text-muted-foreground text-center py-4",children:"Ask AI to help refine your task or prompt"}),o.filter(e=>e.content).map(e=>(0,s.jsxs)("div",{className:`flex flex-col ${"user"===e.role?"items-end":"items-start"}`,children:[(0,s.jsx)("div",{className:`max-w-[90%] px-3 py-2 rounded-lg text-sm leading-relaxed ${"user"===e.role?"bg-accent text-white rounded-br-sm whitespace-pre-wrap":"bg-muted text-foreground rounded-bl-sm chat-markdown"}`,children:"assistant"===e.role?(0,s.jsx)(D.oz,{remarkPlugins:[A.A],children:e.content}):e.content}),"assistant"===e.role&&(0,s.jsx)("button",{onClick:()=>r(e.content),className:"text-xs text-muted-foreground hover:text-primary mt-0.5 px-1 transition-colors",children:"Apply to prompt"})]},e.id)),c&&(0,s.jsxs)("div",{className:"flex gap-1 px-2 py-2",children:[(0,s.jsx)("div",{className:"w-1.5 h-1.5 rounded-full bg-muted-foreground animate-bounce",style:{animationDelay:"0ms"}}),(0,s.jsx)("div",{className:"w-1.5 h-1.5 rounded-full bg-muted-foreground animate-bounce",style:{animationDelay:"150ms"}}),(0,s.jsx)("div",{className:"w-1.5 h-1.5 rounded-full bg-muted-foreground animate-bounce",style:{animationDelay:"300ms"}})]}),(0,s.jsx)("div",{ref:x})]}),(0,s.jsxs)("div",{className:"flex gap-1.5 px-2 py-2 border-t border-border",children:[(0,s.jsx)("textarea",{ref:m,value:l,onChange:e=>d(e.target.value),onKeyDown:e=>{"Enter"!==e.key||e.shiftKey||(e.preventDefault(),f())},placeholder:"Ask AI...",rows:1,className:"flex-1 bg-input border border-border rounded-md px-3 py-2 text-sm text-foreground resize-none focus:border-primary focus:outline-none"}),(0,s.jsx)("button",{onClick:f,disabled:!l.trim()||c,className:"px-3 py-2 bg-accent text-white text-sm rounded-md disabled:opacity-40 hover:bg-accent/80 transition-colors flex-shrink-0",children:"Send"})]})]})}function R({task:e,projectId:t,subProjectId:r,onUpdate:n,onDelete:o,onChatStateChange:i}){let[l,d]=(0,a.useState)(e.title),[c,u]=(0,a.useState)(e.description),[x,m]=(0,a.useState)(""),[p,h]=(0,a.useState)(!1),[f,b]=(0,a.useState)(!1),[g,j]=(0,a.useState)(!1),y=`/api/projects/${t}/sub-projects/${r}/tasks/${e.id}`,v=(0,a.useRef)(null);(0,a.useEffect)(()=>{d(e.title),u(e.description),fetch(`${y}/prompt`).then(e=>e.json()).then(e=>m(e.content||""))},[e.id,e.title,e.description,y]);let N=(0,a.useCallback)(()=>{let t=l.trim();t&&t!==e.title?n({title:t}):d(e.title),b(!1)},[l,e.title,n]),k=(0,a.useCallback)(()=>{c!==e.description&&n({description:c})},[c,e.description,n]),w=(0,a.useCallback)(async e=>{m(e),await fetch(`${y}/prompt`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({content:e,prompt_type:"manual"})})},[y]),C=(0,a.useCallback)(async()=>{h(!0);try{let t=await fetch(`${y}/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({message:`Please refine and improve this prompt for a coding assistant. Current prompt: ${x||"(empty - generate one based on the task)"}. Task: ${e.title}. Description: ${e.description}. Output ONLY the improved prompt text, nothing else.`})});if(t.ok){let e=await t.json(),r=e.aiMessage?.content||"";r&&await w(r)}}catch{}h(!1)},[y,x,e.title,e.description,w]),S=(0,a.useCallback)(async e=>{await w(e)},[w]);return(0,s.jsxs)("div",{className:"flex flex-col h-full",children:[(0,s.jsxs)("div",{className:"px-4 py-3 border-b border-border flex-shrink-0 space-y-2",children:[f?(0,s.jsx)("input",{value:l,onChange:e=>d(e.target.value),onBlur:N,onKeyDown:t=>{"Enter"===t.key&&N(),"Escape"===t.key&&(d(e.title),b(!1))},className:"w-full bg-transparent text-lg font-semibold border-b border-primary focus:outline-none pb-1 text-foreground",autoFocus:!0}):(0,s.jsx)("h2",{onClick:()=>b(!0),className:"text-lg font-semibold cursor-text hover:text-primary transition-colors",children:e.title}),(0,s.jsxs)("div",{className:"flex items-center gap-3 flex-wrap",children:[(0,s.jsx)(T,{status:e.status,onChange:e=>n({status:e})}),(0,s.jsx)("div",{className:"flex items-center gap-1",children:["high","medium","low"].map(t=>(0,s.jsx)("button",{onClick:()=>n({priority:t}),className:`px-2 py-0.5 text-xs rounded transition-colors ${e.priority===t?"high"===t?"bg-destructive/20 text-destructive":"medium"===t?"bg-warning/20 text-warning":"bg-muted text-muted-foreground":"text-muted-foreground/40 hover:text-muted-foreground"}`,children:t},t))}),(0,s.jsx)("button",{onClick:()=>n({is_today:!e.is_today}),className:`text-xs px-2 py-0.5 rounded transition-colors ${e.is_today?"bg-primary/20 text-primary":"text-muted-foreground hover:text-foreground"}`,children:e.is_today?"Today *":"Mark today"}),(0,s.jsx)("span",{className:"text-border",children:"|"}),(0,s.jsxs)("button",{onClick:()=>j(!0),className:`text-xs px-2 py-0.5 rounded transition-colors border ${x?"bg-accent/15 text-accent border-accent/30 hover:bg-accent/25":"text-muted-foreground border-border hover:text-foreground hover:border-muted-foreground"}`,children:["Prompt",x?" *":""]}),(0,s.jsx)("button",{onClick:o,className:"text-xs text-muted-foreground hover:text-destructive transition-colors ml-auto",children:"Delete"})]}),(0,s.jsx)("textarea",{value:c,onChange:e=>u(e.target.value),onBlur:k,placeholder:"Background, conditions, notes...",className:"w-full bg-input border border-border rounded-lg px-3 py-2 text-sm focus:border-primary focus:outline-none text-foreground resize-y leading-relaxed min-h-[3.5rem] max-h-[300px]",rows:2})]}),(0,s.jsx)("div",{className:"flex-1 min-h-0",children:(0,s.jsx)(O,{basePath:y,taskStatus:e.status,onApplyToPrompt:S,onChatStateChange:i?t=>i(e.id,t):void 0})}),g&&(0,s.jsx)("div",{ref:v,onClick:e=>{e.target===v.current&&j(!1)},className:"fixed inset-0 z-50 flex items-center justify-center",style:{background:"rgba(0,0,0,0.5)",backdropFilter:"blur(2px)"},children:(0,s.jsxs)("div",{className:"bg-card border border-border rounded-xl shadow-2xl shadow-black/40 w-full max-w-2xl mx-4 max-h-[80vh] flex flex-col animate-dialog-in",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between px-5 py-3 border-b border-border",children:[(0,s.jsx)("h3",{className:"text-sm font-semibold text-foreground",children:"Prompt"}),(0,s.jsx)("button",{onClick:()=>j(!1),className:"text-muted-foreground hover:text-foreground transition-colors text-sm",children:"Close"})]}),(0,s.jsx)("div",{className:"flex-1 overflow-y-auto p-5",children:(0,s.jsx)(P,{content:x,onSave:w,onRefine:C,refining:p})})]})})]})}function L({open:e,content:t,onSave:r,onClose:n}){let[o,i]=(0,a.useState)(t),l=(0,a.useRef)(null);return((0,a.useEffect)(()=>{e&&(i(t),setTimeout(()=>l.current?.focus(),50))},[e,t]),(0,a.useEffect)(()=>{if(!e)return;let t=e=>{"Escape"===e.key&&n(),(e.metaKey||e.ctrlKey)&&"Enter"===e.key&&(e.preventDefault(),r(o))};return window.addEventListener("keydown",t),()=>window.removeEventListener("keydown",t)},[e,o,r,n]),e)?(0,s.jsxs)("div",{className:"fixed inset-0 z-50 flex items-center justify-center",children:[(0,s.jsx)("div",{className:"absolute inset-0 bg-black/60 backdrop-blur-sm",onClick:n}),(0,s.jsxs)("div",{className:"relative bg-card border border-border rounded-xl shadow-2xl w-[640px] max-h-[80vh] flex flex-col animate-dialog-in",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between px-5 py-3 border-b border-border",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("h3",{className:"text-sm font-semibold",children:"AI Policy"}),(0,s.jsx)("p",{className:"text-xs text-muted-foreground mt-0.5",children:"AI 채팅과 프롬프트 다듬기에 항상 포함되는 프로젝트 컨텍스트"})]}),(0,s.jsx)("button",{onClick:n,className:"text-muted-foreground hover:text-foreground text-lg px-1",children:"x"})]}),(0,s.jsx)("div",{className:"flex-1 p-4 overflow-y-auto",children:(0,s.jsx)("textarea",{ref:l,value:o,onChange:e=>i(e.target.value),placeholder:`프로젝트 컨텍스트와 AI 지침을 작성하세요.
|
|
9
|
+
|
|
10
|
+
예시:
|
|
11
|
+
- 이 프로젝트는 JABIS 스마트워크 시스템입니다
|
|
12
|
+
- 기술 스택: React + TypeScript + Vite (monorepo)
|
|
13
|
+
- DB: PostgreSQL (jabis 스키마)
|
|
14
|
+
- 한국어로 응답할 것
|
|
15
|
+
- 코드 제안 시 기존 컨벤션을 따를 것`,className:"w-full bg-input border border-border rounded-lg px-4 py-3 text-sm text-foreground resize-none focus:border-primary focus:outline-none leading-relaxed font-mono min-h-[300px]"})}),(0,s.jsxs)("div",{className:"flex items-center justify-between px-5 py-3 border-t border-border",children:[(0,s.jsx)("span",{className:"text-xs text-muted-foreground",children:"Cmd+Enter to save"}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("button",{onClick:n,className:"px-3 py-1.5 text-xs text-muted-foreground hover:text-foreground border border-border rounded-md transition-colors",children:"Cancel"}),(0,s.jsx)("button",{onClick:()=>r(o),className:"px-3 py-1.5 text-xs bg-primary text-white rounded-md hover:bg-primary-hover transition-colors",children:"Save"})]})]})]})]}):null}let M={success:{icon:"✅",color:"text-success"},error:{icon:"❌",color:"text-destructive"},"no-git":{icon:"➖",color:"text-muted-foreground"},"no-path":{icon:"➖",color:"text-muted-foreground"}};function J({open:e,results:t,onClose:r}){let n=(0,a.useRef)(null);if((0,a.useEffect)(()=>{if(!e)return;let t=e=>{"Escape"===e.key&&r()};return window.addEventListener("keydown",t),()=>window.removeEventListener("keydown",t)},[e,r]),!e)return null;let o=t.filter(e=>"success"===e.status).length,i=t.filter(e=>"error"===e.status).length,l=t.filter(e=>"no-git"===e.status||"no-path"===e.status).length;return(0,s.jsx)("div",{ref:n,onClick:e=>{e.target===n.current&&r()},className:"fixed inset-0 z-50 flex items-center justify-center",style:{background:"rgba(0,0,0,0.5)",backdropFilter:"blur(2px)"},children:(0,s.jsxs)("div",{className:"bg-card border border-border rounded-xl shadow-2xl shadow-black/40 w-full max-w-md mx-4 animate-dialog-in",children:[(0,s.jsxs)("div",{className:"p-5 border-b border-border",children:[(0,s.jsx)("h3",{className:"text-sm font-semibold text-foreground",children:"Git Sync Results"}),(0,s.jsxs)("p",{className:"text-xs text-muted-foreground mt-1",children:[o," synced, ",i," failed, ",l," skipped"]})]}),(0,s.jsx)("div",{className:"max-h-64 overflow-y-auto p-3 space-y-1.5",children:0===t.length?(0,s.jsx)("p",{className:"text-xs text-muted-foreground text-center py-4",children:"No projects with linked folders"}):t.map(e=>{let t=M[e.status];return(0,s.jsxs)("div",{className:"flex items-start gap-2 p-2 rounded-lg bg-muted/50",children:[(0,s.jsx)("span",{className:"text-sm flex-shrink-0",children:t.icon}),(0,s.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,s.jsx)("div",{className:"text-xs font-medium truncate",children:e.projectName}),(0,s.jsx)("div",{className:`text-xs ${t.color} truncate`,title:e.message,children:e.message})]})]},e.projectId)})}),(0,s.jsx)("div",{className:"flex justify-end px-5 pb-4 pt-2",children:(0,s.jsx)("button",{onClick:r,className:"px-3 py-1.5 text-xs text-muted-foreground hover:text-foreground bg-muted hover:bg-card-hover border border-border rounded-md transition-colors",children:"Close"})})]})})}let F={ts:"TS",tsx:"TX",js:"JS",jsx:"JX",json:"{}",md:"MD",css:"CS",scss:"SC",html:"HT",svg:"SV",png:"PN",jpg:"JP",py:"PY",go:"GO",rs:"RS",java:"JA",sql:"SQ",sh:"SH",yml:"YM",yaml:"YM",toml:"TM",xml:"XM",txt:"TX",env:"EN",lock:"LK",gitignore:"GI"};function K({rootPath:e,onClose:t}){let[r,n]=(0,a.useState)({}),[o,i]=(0,a.useState)(new Set([e])),l=(0,a.useRef)(null),d=(0,a.useCallback)(async e=>{n(t=>({...t,[e]:{entries:[],loaded:!1,loading:!0}}));try{let t=await fetch(`/api/filesystem/tree?path=${encodeURIComponent(e)}`);if(!t.ok)throw Error("Failed to load");let r=await t.json();n(t=>({...t,[e]:{entries:r.entries,loaded:!0,loading:!1}}))}catch{n(t=>({...t,[e]:{entries:[],loaded:!0,loading:!1,error:"Failed to load"}}))}},[]);(0,a.useEffect)(()=>{d(e)},[e,d]),(0,a.useEffect)(()=>{let e=e=>{"Escape"===e.key&&t()};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[t]);let c=(e,t)=>{let a=r[e];return a?a.loading?(0,s.jsx)("div",{className:"flex items-center gap-2 py-1",style:{paddingLeft:16*t+12},children:(0,s.jsx)("span",{className:"text-xs text-muted-foreground animate-pulse",children:"Loading..."})}):a.error?(0,s.jsx)("div",{className:"flex items-center gap-2 py-1",style:{paddingLeft:16*t+12},children:(0,s.jsx)("span",{className:"text-xs text-destructive",children:a.error})}):0===a.entries.length?(0,s.jsx)("div",{className:"flex items-center gap-2 py-1",style:{paddingLeft:16*t+12},children:(0,s.jsx)("span",{className:"text-xs text-muted-foreground italic",children:"Empty"})}):a.entries.map(e=>{var a,n;let l="directory"===e.type,u=o.has(e.path);return(0,s.jsxs)("div",{children:[(0,s.jsx)("div",{className:`flex items-center gap-1.5 py-[3px] pr-3 cursor-pointer transition-colors hover:bg-card-hover group ${l?"text-foreground":"text-muted-foreground"}`,style:{paddingLeft:16*t+12},onClick:()=>{var t;return l&&(t=e.path,void i(e=>{let s=new Set(e);return s.has(t)?s.delete(t):(s.add(t),r[t]?.loaded||r[t]?.loading||d(t)),s}))},children:l?(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)("span",{className:"w-4 text-center text-xs text-muted-foreground flex-shrink-0",children:u?"▼":"▶"}),(0,s.jsx)("span",{className:"text-sm flex-shrink-0",children:u?"\uD83D\uDCC2":"\uD83D\uDCC1"}),(0,s.jsx)("span",{className:"text-sm truncate flex-1 font-medium",children:e.name})]}):(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)("span",{className:"w-4 flex-shrink-0"}),(0,s.jsx)("span",{className:"text-[10px] font-mono w-5 text-center flex-shrink-0 text-muted-foreground/70",children:(a=e.extension)?F[a]||a.slice(0,2).toUpperCase():"--"}),(0,s.jsx)("span",{className:"text-sm truncate flex-1",children:e.name}),void 0!==e.size&&(0,s.jsx)("span",{className:"text-[10px] text-muted-foreground/50 tabular-nums flex-shrink-0",children:(n=e.size)<1024?`${n}B`:n<1048576?`${(n/1024).toFixed(0)}K`:`${(n/1048576).toFixed(1)}M`})]})}),l&&u&&c(e.path,t+1)]},e.path)}):null},u=e.split("/").pop()||e;return(0,s.jsxs)("div",{ref:l,className:"fixed inset-0 z-50 flex justify-end",onClick:e=>{e.target===l.current&&t()},children:[(0,s.jsx)("div",{className:"absolute inset-0 bg-black/40 backdrop-blur-[2px]"}),(0,s.jsxs)("div",{className:"relative w-[420px] max-w-[85vw] h-full bg-card border-l border-border shadow-2xl flex flex-col animate-drawer-in",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between px-4 py-3 border-b border-border flex-shrink-0",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2 min-w-0",children:[(0,s.jsx)("span",{className:"text-base",children:"\uD83D\uDCC2"}),(0,s.jsxs)("div",{className:"min-w-0",children:[(0,s.jsx)("h2",{className:"text-sm font-semibold truncate",children:u}),(0,s.jsx)("p",{className:"text-[10px] text-muted-foreground font-mono truncate",children:e})]})]}),(0,s.jsx)("button",{onClick:t,className:"text-muted-foreground hover:text-foreground transition-colors text-lg px-1",title:"Close (ESC)",children:"\xd7"})]}),(0,s.jsx)("div",{className:"flex-1 overflow-y-auto py-2",children:c(e,0)}),(0,s.jsx)("div",{className:"px-4 py-2 border-t border-border flex-shrink-0",children:(0,s.jsx)("p",{className:"text-[10px] text-muted-foreground",children:"ESC to close"})})]})]})}function z({open:e,projectId:t,onClose:r,onApplied:n}){let[o,i]=(0,a.useState)(!1),[l,d]=(0,a.useState)(!1),[c,u]=(0,a.useState)(null),[x,m]=(0,a.useState)([]),[p,h]=(0,a.useState)(new Set);(0,a.useEffect)(()=>{e&&(m([]),u(null),h(new Set),f())},[e]),(0,a.useEffect)(()=>{if(!e)return;let t=e=>{"Escape"===e.key&&r()};return window.addEventListener("keydown",t),()=>window.removeEventListener("keydown",t)},[e,r]);let f=async()=>{i(!0),u(null);try{let e=await fetch(`/api/projects/${t}/auto-distribute`,{method:"POST"}),r=await e.json();if(!e.ok){let e=r.raw?`
|
|
16
|
+
|
|
17
|
+
AI 응답:
|
|
18
|
+
${r.raw}`:"";u((r.error||"Failed to get distribution")+e);return}m(r.distributions||[])}catch{u("AI 호출에 실패했습니다.")}finally{i(!1)}},b=async()=>{let e=x.filter(e=>e.tasks.length>0);if(0!==e.length){d(!0);try{let s=await fetch(`/api/projects/${t}/apply-distribute`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({distributions:e})});if(s.ok)n(),r();else{let e=await s.json();u(e.error||"Failed to apply")}}catch{u("적용에 실패했습니다.")}finally{d(!1)}}},g=x.reduce((e,t)=>e+t.tasks.length,0);return e?(0,s.jsxs)("div",{className:"fixed inset-0 z-50 flex items-center justify-center",children:[(0,s.jsx)("div",{className:"absolute inset-0 bg-black/60 backdrop-blur-sm",onClick:r}),(0,s.jsxs)("div",{className:"relative bg-card border border-border rounded-xl shadow-2xl w-[720px] max-h-[85vh] flex flex-col animate-dialog-in",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between px-5 py-3 border-b border-border",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("h3",{className:"text-sm font-semibold",children:"Auto Distribute"}),(0,s.jsx)("p",{className:"text-xs text-muted-foreground mt-0.5",children:"AI가 브레인스토밍을 분석하여 태스크를 분배합니다"})]}),(0,s.jsx)("button",{onClick:r,className:"text-muted-foreground hover:text-foreground text-lg px-1",children:"x"})]}),(0,s.jsxs)("div",{className:"flex-1 overflow-y-auto p-4",children:[o&&(0,s.jsxs)("div",{className:"flex flex-col items-center justify-center py-16 gap-3",children:[(0,s.jsx)("div",{className:"w-6 h-6 border-2 border-primary border-t-transparent rounded-full animate-spin"}),(0,s.jsx)("p",{className:"text-sm text-muted-foreground",children:"AI가 분석 중..."})]}),c&&(0,s.jsxs)("div",{className:"bg-danger/10 border border-danger/30 rounded-lg p-3 mb-3",children:[(0,s.jsx)("pre",{className:"text-xs text-danger whitespace-pre-wrap break-all max-h-[200px] overflow-y-auto",children:c}),(0,s.jsx)("button",{onClick:f,className:"text-xs text-accent hover:underline mt-1",children:"다시 시도"})]}),!o&&x.length>0&&(0,s.jsx)("div",{className:"space-y-3",children:x.map((e,t)=>(0,s.jsxs)("div",{className:"border border-border rounded-lg overflow-hidden",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2 px-3 py-2 bg-muted/50",children:[(0,s.jsx)("button",{onClick:()=>{h(e=>{let r=new Set(e);return r.has(t)?r.delete(t):r.add(t),r})},className:"text-xs text-muted-foreground hover:text-foreground w-4",children:p.has(t)?"▶":"▼"}),(0,s.jsx)("span",{className:`text-[10px] px-1.5 py-0.5 rounded font-medium ${e.is_new?"bg-success/15 text-success":"bg-accent/15 text-accent"}`,children:e.is_new?"NEW":"EXISTING"}),(0,s.jsx)("input",{value:e.sub_project_name,onChange:e=>{var r;return r=e.target.value,void m(e=>e.map((e,s)=>s===t?{...e,sub_project_name:r}:e))},className:"flex-1 bg-transparent text-sm font-medium text-foreground focus:outline-none border-b border-transparent focus:border-primary"}),(0,s.jsx)("span",{className:"text-xs text-muted-foreground tabular-nums",children:e.tasks.length}),(0,s.jsx)("button",{onClick:()=>{m(e=>e.filter((e,r)=>r!==t))},className:"text-xs text-muted-foreground hover:text-danger px-1",title:"Remove group",children:"x"})]}),!p.has(t)&&(0,s.jsxs)("div",{className:"divide-y divide-border",children:[e.tasks.map((e,r)=>{var a;return(0,s.jsxs)("div",{className:"flex items-center gap-2 px-3 py-1.5 group hover:bg-muted/30",children:[(a=e.priority,(0,s.jsx)("span",{className:`inline-block w-2 h-2 rounded-full ${{high:"bg-danger",medium:"bg-warning",low:"bg-muted-foreground/40"}[a]}`})),(0,s.jsx)("input",{value:e.title,onChange:e=>{var s;return s=e.target.value,void m(e=>e.map((e,a)=>a===t?{...e,tasks:e.tasks.map((e,t)=>t===r?{...e,title:s}:e)}:e))},className:"flex-1 bg-transparent text-xs text-foreground focus:outline-none border-b border-transparent focus:border-primary"}),(0,s.jsxs)("select",{value:e.priority,onChange:e=>{var s;return s=e.target.value,void m(e=>e.map((e,a)=>a===t?{...e,tasks:e.tasks.map((e,t)=>t===r?{...e,priority:s}:e)}:e))},className:"text-[10px] bg-transparent text-muted-foreground cursor-pointer hover:text-foreground opacity-0 group-hover:opacity-100 transition-opacity",children:[(0,s.jsx)("option",{value:"high",children:"high"}),(0,s.jsx)("option",{value:"medium",children:"medium"}),(0,s.jsx)("option",{value:"low",children:"low"})]}),x.length>1&&(0,s.jsxs)("select",{value:"",onChange:e=>{let s=parseInt(e.target.value);isNaN(s)||m(e=>{let a=e[t].tasks[r];return e.map((e,n)=>n===t?{...e,tasks:e.tasks.filter((e,t)=>t!==r)}:n===s?{...e,tasks:[...e.tasks,a]}:e)})},className:"text-[10px] bg-transparent text-muted-foreground cursor-pointer hover:text-foreground opacity-0 group-hover:opacity-100 transition-opacity",title:"Move to...",children:[(0,s.jsx)("option",{value:"",children:"Move"}),x.map((e,r)=>r!==t&&(0,s.jsx)("option",{value:r,children:e.sub_project_name},r))]}),(0,s.jsx)("button",{onClick:()=>{m(e=>e.map((e,s)=>s===t?{...e,tasks:e.tasks.filter((e,t)=>t!==r)}:e))},className:"text-xs text-muted-foreground hover:text-danger opacity-0 group-hover:opacity-100 transition-opacity px-0.5",children:"x"})]},r)}),0===e.tasks.length&&(0,s.jsx)("div",{className:"px-3 py-2 text-xs text-muted-foreground italic",children:"No tasks (this group will be skipped)"})]})]},t))}),!o&&!c&&0===x.length&&(0,s.jsx)("div",{className:"text-center py-16 text-sm text-muted-foreground",children:"No distribution available"})]}),(0,s.jsxs)("div",{className:"flex items-center justify-between px-5 py-3 border-t border-border",children:[(0,s.jsx)("span",{className:"text-xs text-muted-foreground",children:x.length>0&&`${x.length} projects, ${g} tasks`}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[!o&&x.length>0&&(0,s.jsx)("button",{onClick:f,className:"px-3 py-1.5 text-xs text-muted-foreground hover:text-foreground border border-border rounded-md transition-colors",children:"Retry"}),(0,s.jsx)("button",{onClick:r,className:"px-3 py-1.5 text-xs text-muted-foreground hover:text-foreground border border-border rounded-md transition-colors",children:"Cancel"}),(0,s.jsx)("button",{onClick:b,disabled:l||o||0===g,className:"px-4 py-1.5 text-xs bg-primary text-white rounded-md hover:bg-primary-hover transition-colors disabled:opacity-50",children:l?"Applying...":`Apply (${g})`})]})]})]})]}):null}function U({id:e,initialSubId:t,initialTaskId:r}){let{state:n,setActiveTab:o,consumeInitial:i,updateTabName:l}=x(),d=n.activeTabId===e,c=(0,a.useRef)(t),u=(0,a.useRef)(r);(0,a.useEffect)(()=>{t&&(c.current=t),r&&(u.current=r),(t||r)&&(t&&y(t),r&&C(r),i(e))},[t,r]);let[m,p]=(0,a.useState)(null),[b,g]=(0,a.useState)([]),[j,y]=(0,a.useState)(null),[v,k]=(0,a.useState)([]),[w,C]=(0,a.useState)(null),[S,T]=(0,a.useState)(!1),[I,E]=(0,a.useState)(null),[_,P]=(0,a.useState)(!1),[D,A]=(0,a.useState)(!0),[O,M]=(0,a.useState)(""),[F,U]=(0,a.useState)(!1),[B,G]=(0,a.useState)(!1),[V,H]=(0,a.useState)(null),[W,X]=(0,a.useState)(null),[Y,q]=(0,a.useState)(!1),[Q,Z]=(0,a.useState)(!1),[ee,et]=(0,a.useState)({}),er=(0,a.useRef)(!1),[es,ea]=(0,a.useState)(500),[en,eo]=(0,a.useState)(500),ei=(0,a.useRef)(null),el=(0,a.useRef)(null),ed=(0,a.useRef)(0),ec=(0,a.useRef)(0),eu=(0,a.useCallback)((e,t)=>{t.preventDefault(),el.current=e,ed.current=t.clientX,ec.current="left"===e?es:en},[es,en]);(0,a.useEffect)(()=>{let e=e=>{if(!el.current)return;let t=e.clientX-ed.current,r=Math.max(180,Math.min(900,ec.current+t));"left"===el.current?ea(r):eo(r)},t=()=>{el.current=null};return window.addEventListener("mousemove",e),window.addEventListener("mouseup",t),()=>{window.removeEventListener("mousemove",e),window.removeEventListener("mouseup",t)}},[]),(0,a.useEffect)(()=>{fetch(`/api/projects/${e}`).then(e=>e.ok?e.json():null).then(t=>{t&&(p(t),l(e,t.name))})},[e,l]);let ex=(0,a.useCallback)(async()=>{let t=await fetch(`/api/projects/${e}/sub-projects`);if(!t.ok)return;let r=await t.json();return g(r),r},[e]);(0,a.useEffect)(()=>{ex().then(e=>{if(!e||0===e.length)return;let t=c.current;t&&e.some(e=>e.id===t)?y(t):j||y(e[0].id)})},[ex]),(0,a.useEffect)(()=>{j?fetch(`/api/projects/${e}/sub-projects/${j}/tasks`).then(e=>e.json()).then(e=>{k(e);let t=u.current;t&&e.some(e=>e.id===t)&&(C(t),u.current=void 0)}):k([])},[e,j]);let em=v.find(e=>e.id===w)??null,ep=async()=>{if(!O.trim())return;let t=await fetch(`/api/projects/${e}/sub-projects`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:O.trim()})});if(t.ok){let e=await t.json();M(""),P(!1),await ex(),y(e.id)}},eh=async t=>{if(!j)return;let r=await fetch(`/api/projects/${e}/sub-projects/${j}/tasks`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({title:t})});if(r.ok){let e=await r.json();k(t=>[...t,e]),C(e.id),ex()}},ef=async(t,r)=>{let s=await fetch(`/api/projects/${e}/sub-projects/${j}/tasks/${t}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({status:r})});if(s.ok){let e=await s.json();k(r=>r.map(r=>r.id===t?e:r)),ex()}},eb=async(t,r)=>{let s=await fetch(`/api/projects/${e}/sub-projects/${j}/tasks/${t}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({is_today:r})});if(s.ok){let e=await s.json();k(r=>r.map(r=>r.id===t?e:r))}},eg=async t=>{if(!w||!j)return;let r=await fetch(`/api/projects/${e}/sub-projects/${j}/tasks/${w}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(r.ok){let e=await r.json();k(t=>t.map(t=>t.id===w?e:t)),ex()}},ej=async t=>{g(e=>{let r=new Map(e.map(e=>[e.id,e]));return t.map(e=>r.get(e)).filter(Boolean)}),await fetch(`/api/projects/${e}/sub-projects`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({orderedIds:t})})},ey=e=>{let t=e||w;t&&E({type:"delete-task",id:t})},ev=async t=>{I&&("delete-sub"===I.type?(await fetch(`/api/projects/${e}/sub-projects/${I.id}`,{method:"DELETE"}),j===I.id&&(y(null),C(null)),ex()):"delete-task"===I.type&&(await fetch(`/api/projects/${e}/sub-projects/${j}/tasks/${I.id}?mode=${t||"archive"}`,{method:"DELETE"}),k(e=>e.filter(e=>e.id!==I.id)),w===I.id&&C(null),ex()),E(null))},eN=async t=>{let r=await fetch(`/api/projects/${e}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({project_path:t})});r.ok&&(p(await r.json()),T(!1))},ek=async t=>{let r=await fetch(`/api/projects/${e}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({ai_context:t})});r.ok&&(p(await r.json()),U(!1))},ew=(0,a.useCallback)(async(t=!1)=>{if(!er.current){er.current=!0,t||G(!0);try{let r=await fetch(`/api/projects/${e}/git-sync`,{method:"POST"});if(r.ok){let e=await r.json();X(new Date),t||H(e)}}catch{}finally{er.current=!1,t||G(!1)}}},[e]);(0,a.useEffect)(()=>{if(!m?.project_path)return;let e=setInterval(()=>ew(!0),18e5);return()=>clearInterval(e)},[m?.project_path,ew]);let eC=async()=>{if(!m)return;let t=await fetch(`/api/projects/${e}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({watch_enabled:!m.watch_enabled})});t.ok&&p(await t.json())};return((0,a.useEffect)(()=>{let e=e=>{if(!d)return;let t=e.target instanceof HTMLInputElement||e.target instanceof HTMLTextAreaElement;if(!t&&"KeyB"===e.code&&!e.metaKey&&!e.ctrlKey){e.preventDefault(),A(e=>!e);return}if(!t&&"KeyN"===e.code&&!e.metaKey&&!e.ctrlKey){e.preventDefault(),P(!0);return}if(!t&&"KeyT"===e.code&&!e.metaKey&&!e.ctrlKey&&j){e.preventDefault();let t=document.querySelector("[data-add-task]");t?.click();return}if(w&&j&&!t){let t={Digit1:"idea",Digit2:"writing",Digit3:"submitted",Digit4:"testing",Digit5:"done",Digit6:"problem"};(e.metaKey||e.ctrlKey)&&t[e.code]&&(e.preventDefault(),ef(w,t[e.code]))}};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)}),m)?(0,s.jsxs)("div",{className:"flex flex-col h-full",children:[(0,s.jsxs)("header",{className:"flex items-center justify-between px-4 py-2 border-b border-border bg-card flex-shrink-0",children:[(0,s.jsxs)("div",{className:"flex items-center gap-3",children:[(0,s.jsx)("button",{onClick:()=>o("dashboard"),className:"text-muted-foreground hover:text-foreground hover:bg-muted transition-colors text-sm px-2 py-1 rounded-md",children:"← Back"}),(0,s.jsx)("span",{className:"text-border",children:"|"}),(0,s.jsx)("h1",{className:"text-sm font-semibold",children:m.name}),m.project_path&&(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)("span",{className:"text-xs text-muted-foreground font-mono truncate max-w-48",title:m.project_path,children:m.project_path}),(0,s.jsx)("button",{onClick:()=>q(!0),className:"text-xs text-muted-foreground hover:text-foreground hover:bg-muted transition-colors px-1.5 py-0.5 rounded",title:"View file tree",children:"\uD83D\uDCC2"})]})]}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsxs)("select",{value:m.agent_type||"claude",onChange:async t=>{let r=await fetch(`/api/projects/${e}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({agent_type:t.target.value})});r.ok&&p(await r.json())},className:"px-2 py-1.5 text-xs bg-muted border border-border rounded-md text-foreground cursor-pointer hover:bg-card-hover transition-colors",title:"AI Agent",children:[(0,s.jsx)("option",{value:"claude",children:"Claude"}),(0,s.jsx)("option",{value:"gemini",children:"Gemini"}),(0,s.jsx)("option",{value:"codex",children:"Codex"})]}),(0,s.jsxs)("button",{onClick:eC,className:`px-3 py-1.5 text-xs border rounded-md transition-colors flex items-center gap-1.5 ${m.watch_enabled?"bg-success/15 text-success border-success/30 hover:bg-success/25":"bg-muted hover:bg-card-hover text-muted-foreground border-border"}`,title:m.watch_enabled?"Watch ON":"Watch OFF",children:[(0,s.jsx)("span",{className:`inline-block w-2 h-2 rounded-full ${m.watch_enabled?"bg-success animate-pulse":"bg-muted-foreground/40"}`}),"Watch"]}),(0,s.jsxs)("button",{onClick:()=>U(!0),className:`px-3 py-1.5 text-xs border rounded-md transition-colors ${m.ai_context?"bg-accent/15 text-accent border-accent/30 hover:bg-accent/25":"bg-muted hover:bg-card-hover text-muted-foreground border-border"}`,children:["AI Policy",m.ai_context?" *":""]}),m.project_path?(0,s.jsxs)("div",{className:"flex items-center gap-1.5",children:[(0,s.jsxs)("button",{onClick:()=>ew(!1),disabled:B,className:"px-3 py-1.5 text-xs bg-muted hover:bg-card-hover text-foreground border border-border rounded-md transition-colors disabled:opacity-50 flex items-center gap-1.5",title:W?`Last sync: ${W.toLocaleTimeString()}`:"Git pull",children:[(0,s.jsx)("span",{className:B?"animate-spin":"",children:"↻"}),B?"Syncing...":"Git Sync"]}),W&&(0,s.jsx)("span",{className:"text-xs text-muted-foreground",children:W.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})})]}):(0,s.jsx)("button",{onClick:()=>T(!0),className:"px-3 py-1.5 text-xs bg-muted hover:bg-card-hover text-foreground border border-border rounded-md transition-colors",children:"Link folder"})]})]}),(0,s.jsxs)("div",{ref:ei,className:"flex-1 flex overflow-hidden",children:[D?(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)("div",{style:{width:es},className:"border-r border-border flex flex-col flex-shrink-0",children:(0,s.jsx)(N,{projectId:e,onCollapse:()=>A(!1)})}),(0,s.jsx)("div",{className:"panel-resize-handle",onMouseDown:e=>eu("left",e),children:(0,s.jsx)("div",{className:"panel-resize-handle-bar"})})]}):(0,s.jsx)("button",{onClick:()=>A(!0),className:"w-8 border-r border-border flex-shrink-0 flex items-center justify-center text-muted-foreground hover:text-foreground hover:bg-card-hover transition-colors text-xs",title:"Show brainstorming (B)",style:{writingMode:"vertical-rl"},children:"Brainstorm"}),(0,s.jsxs)("div",{style:{width:en},className:"border-r border-border flex flex-col flex-shrink-0",children:[_&&(0,s.jsx)("div",{className:"px-3 py-2 border-b border-border",children:(0,s.jsx)("input",{type:"text",value:O,onChange:e=>M(e.target.value),onKeyDown:e=>{"Enter"===e.key&&ep(),"Escape"===e.key&&(M(""),P(!1))},placeholder:"Sub-project name...",className:"w-full bg-input border border-border rounded px-2 py-1 text-xs focus:border-primary focus:outline-none text-foreground",autoFocus:!0})}),(0,s.jsx)($,{subProjects:b,tasks:v,selectedSubId:j,selectedTaskId:w,onSelectSub:e=>{y(e),C(null)},onSelectTask:e=>{C(e),et(t=>{if("done"!==t[e])return t;let r={...t};return delete r[e],r})},onCreateSub:()=>P(!0),onDeleteSub:e=>{E({type:"delete-sub",id:e})},onCreateTask:eh,onStatusChange:ef,onTodayToggle:eb,onDeleteTask:ey,onReorderSubs:ej,onAutoDistribute:()=>Z(!0),chatStates:ee})]}),(0,s.jsx)("div",{className:"panel-resize-handle",onMouseDown:e=>eu("center",e),children:(0,s.jsx)("div",{className:"panel-resize-handle-bar"})}),(0,s.jsx)("div",{className:"flex-1 min-w-0",children:em?(0,s.jsx)(R,{task:em,projectId:e,subProjectId:j,onUpdate:eg,onDelete:ey,onChatStateChange:(e,t)=>{et(r=>({...r,[e]:t}))}}):(0,s.jsx)("div",{className:"flex items-center justify-center h-full text-muted-foreground text-sm",children:v.length>0?"Select a task":j?"Create a task to get started":"Select a sub-project"})})]}),S&&(0,s.jsx)(h,{onSelect:eN,onCancel:()=>T(!1),initialPath:m.project_path||void 0}),(0,s.jsx)(f,{open:I?.type==="delete-sub",title:"Delete sub-project?",description:"This will delete the sub-project and all its tasks.",confirmLabel:"Delete",variant:"danger",onConfirm:()=>ev(),onCancel:()=>E(null)}),I?.type==="delete-task"&&(0,s.jsx)("div",{className:"fixed inset-0 z-50 flex items-center justify-center",style:{background:"rgba(0,0,0,0.5)",backdropFilter:"blur(2px)"},children:(0,s.jsxs)("div",{className:"bg-card border border-border rounded-xl shadow-2xl shadow-black/40 w-full max-w-sm mx-4 animate-dialog-in",children:[(0,s.jsxs)("div",{className:"p-5",children:[(0,s.jsx)("h3",{className:"text-sm font-semibold text-foreground",children:"Remove task"}),(0,s.jsx)("p",{className:"text-xs text-muted-foreground mt-1.5 leading-relaxed",children:"보관함에 넣으면 나중에 복원하거나 프롬프트를 참고할 수 있습니다."})]}),(0,s.jsxs)("div",{className:"flex justify-end gap-2 px-5 pb-4",children:[(0,s.jsx)("button",{onClick:()=>E(null),className:"px-3 py-1.5 text-xs text-muted-foreground hover:text-foreground bg-muted hover:bg-card-hover border border-border rounded-md transition-colors",children:"Cancel"}),(0,s.jsx)("button",{onClick:()=>ev("permanent"),className:"px-3 py-1.5 text-xs text-white bg-destructive hover:bg-destructive/80 rounded-md transition-colors",children:"Delete"}),(0,s.jsx)("button",{onClick:()=>ev("archive"),className:"px-3 py-1.5 text-xs text-white bg-primary hover:bg-primary-hover rounded-md transition-colors",children:"Archive"})]})]})}),(0,s.jsx)(L,{open:F,content:m.ai_context||"",onSave:ek,onClose:()=>U(!1)}),(0,s.jsx)(J,{open:!!V,results:V||[],onClose:()=>H(null)}),Y&&m.project_path&&(0,s.jsx)(K,{rootPath:m.project_path,onClose:()=>q(!1)}),(0,s.jsx)(z,{open:Q,projectId:e,onClose:()=>Z(!1),onApplied:()=>{ex()}})]}):(0,s.jsx)("div",{className:"flex-1 flex items-center justify-center text-muted-foreground",children:"Loading..."})}function B(){let{state:e}=x();return(0,s.jsxs)("div",{className:"h-screen flex flex-col",children:[(0,s.jsx)(p,{}),(0,s.jsx)("div",{className:"flex-1 min-h-0 relative",children:e.tabs.map(t=>(0,s.jsx)("div",{className:"absolute inset-0 flex flex-col",style:{display:t.id===e.activeTabId?"flex":"none"},children:"dashboard"===t.type?(0,s.jsx)(v,{}):(0,s.jsx)(U,{id:t.projectId,initialSubId:t.initialSubId,initialTaskId:t.initialTaskId})},t.id))})]})}function G(){return(0,s.jsx)(m,{children:(0,s.jsx)(B,{})})}}},e=>{e.O(0,[151,441,794,358],()=>e(e.s=3915)),_N_E=e.O()}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[801],{1048:(e,s,t)=>{"use strict";t.r(s),t.d(s,{default:()=>c});var r=t(5155),n=t(2115),u=t(4645);function c({params:e}){let{id:s}=(0,n.use)(e),t=(0,u.useRouter)();return(0,n.useEffect)(()=>{sessionStorage.setItem("im-open-project",s),t.replace("/")},[s,t]),(0,r.jsx)("div",{className:"min-h-screen flex items-center justify-center text-muted-foreground",children:"Loading..."})}},2696:(e,s,t)=>{Promise.resolve().then(t.bind(t,1048))}},e=>{e.O(0,[441,794,358],()=>e(e.s=2696)),_N_E=e.O()}]);
|