@cedros/pay-react 1.1.16 → 1.1.18
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/dist/AISettingsSection-C-thWh51.js +51 -0
- package/dist/AISettingsSection-CD9IRyR1.mjs +539 -0
- package/dist/AutosaveIndicator-DxemlKnX.js +1 -0
- package/dist/AutosaveIndicator-G2CRN8hH.mjs +35 -0
- package/dist/{CedrosContext-D7nh5-Zh.mjs → CedrosContext-BnJ2Cf7R.mjs} +1179 -642
- package/dist/CedrosContext-C26DlvLF.js +6 -0
- package/dist/CryptoButton-BdOtL7w-.mjs +542 -0
- package/dist/CryptoButton-N8kRfNDO.js +1 -0
- package/dist/FAQSection-CyYK9OAN.mjs +366 -0
- package/dist/FAQSection-_pm1ekTe.js +1 -0
- package/dist/MessagingSection-BHzf1Mhu.js +1 -0
- package/dist/MessagingSection-DO2yPTvs.mjs +347 -0
- package/dist/PaymentSettingsSection--Aqlne1F.mjs +94 -0
- package/dist/PaymentSettingsSection-DpENgoca.js +1 -0
- package/dist/SettingsSection-CGKKGXWz.mjs +57 -0
- package/dist/SettingsSection-DNoODw7i.js +1 -0
- package/dist/SingleCategorySettings-8DCtLcow.mjs +1421 -0
- package/dist/SingleCategorySettings-NLBYxM0O.js +3 -0
- package/dist/StorefrontSection-BEOMtSAg.js +1 -0
- package/dist/StorefrontSection-Mzr1H51w.mjs +765 -0
- package/dist/SubscriptionsSection-4b29i-41.js +1 -0
- package/dist/SubscriptionsSection-Dy1e15fe.mjs +616 -0
- package/dist/Toggle-CsPSF8Dr.js +1 -0
- package/dist/Toggle-DAxIdpY4.mjs +48 -0
- package/dist/WalletManager-D6BYTwXn.js +1 -0
- package/dist/{WalletManager-oEjZhaFk.mjs → WalletManager-HXXyARQ7.mjs} +36 -32
- package/dist/components/CedrosPay.d.ts.map +1 -1
- package/dist/components/CryptoSubscribeButton.d.ts.map +1 -1
- package/dist/components/PaymentModal.d.ts.map +1 -1
- package/dist/components/SubscriptionManagementPanel.d.ts.map +1 -1
- package/dist/components/admin/AISettingsSection.d.ts.map +1 -1
- package/dist/components/admin/AdminAuthManager.d.ts +2 -1
- package/dist/components/admin/AdminAuthManager.d.ts.map +1 -1
- package/dist/components/admin/AutosaveIndicator.d.ts +7 -0
- package/dist/components/admin/AutosaveIndicator.d.ts.map +1 -0
- package/dist/components/admin/CedrosPayAdminDashboard.d.ts.map +1 -1
- package/dist/components/admin/ConfigEditor.d.ts +0 -2
- package/dist/components/admin/ConfigEditor.d.ts.map +1 -1
- package/dist/components/admin/MessagingSection.d.ts.map +1 -1
- package/dist/components/admin/ProductsSection.d.ts.map +1 -1
- package/dist/components/admin/RefundsSection.d.ts.map +1 -1
- package/dist/components/admin/SecretArrayEditor.d.ts +16 -0
- package/dist/components/admin/SecretArrayEditor.d.ts.map +1 -0
- package/dist/components/admin/SingleCategorySettings.d.ts.map +1 -1
- package/dist/components/admin/StorefrontSection.d.ts.map +1 -1
- package/dist/components/admin/Toggle.d.ts +14 -0
- package/dist/components/admin/Toggle.d.ts.map +1 -0
- package/dist/components/admin/TokenMintSelector.d.ts +27 -0
- package/dist/components/admin/TokenMintSelector.d.ts.map +1 -0
- package/dist/components/admin/configApi.d.ts +5 -3
- package/dist/components/admin/configApi.d.ts.map +1 -1
- package/dist/components/admin/index.d.ts +8 -9
- package/dist/components/admin/index.d.ts.map +1 -1
- package/dist/components/admin/sections-more.d.ts +2 -9
- package/dist/components/admin/sections-more.d.ts.map +1 -1
- package/dist/context/CedrosContext.d.ts +1 -1
- package/dist/context/CedrosContext.d.ts.map +1 -1
- package/dist/crypto-only.js +1 -1
- package/dist/crypto-only.mjs +391 -380
- package/dist/ecommerce/__tests__/inventoryHooks.test.d.ts +2 -0
- package/dist/ecommerce/__tests__/inventoryHooks.test.d.ts.map +1 -0
- package/dist/ecommerce/__tests__/storage.test.d.ts +2 -0
- package/dist/ecommerce/__tests__/storage.test.d.ts.map +1 -0
- package/dist/ecommerce/adapters/CommerceAdapter.d.ts +5 -0
- package/dist/ecommerce/adapters/CommerceAdapter.d.ts.map +1 -1
- package/dist/ecommerce/adapters/mock/mockAdapter.d.ts.map +1 -1
- package/dist/ecommerce/adapters/paywall/paywallAdapter.d.ts.map +1 -1
- package/dist/ecommerce/adapters/paywall/paywallAdapter.test.d.ts +2 -0
- package/dist/ecommerce/adapters/paywall/paywallAdapter.test.d.ts.map +1 -0
- package/dist/ecommerce/components/catalog/ProductCard.d.ts.map +1 -1
- package/dist/ecommerce/components/catalog/QuickViewDialog.d.ts.map +1 -1
- package/dist/ecommerce/components/chat/ShopChatPanel.d.ts +4 -0
- package/dist/ecommerce/components/chat/ShopChatPanel.d.ts.map +1 -1
- package/dist/ecommerce/components/checkout/PaymentStep.d.ts.map +1 -1
- package/dist/ecommerce/components/faq/FAQItem.d.ts.map +1 -1
- package/dist/ecommerce/config/context.d.ts.map +1 -1
- package/dist/ecommerce/hooks/useAIRelatedProducts.d.ts.map +1 -1
- package/dist/ecommerce/hooks/useCartInventory.d.ts.map +1 -1
- package/dist/ecommerce/hooks/useHoldExpiry.d.ts.map +1 -1
- package/dist/ecommerce/hooks/useInventoryVerification.d.ts.map +1 -1
- package/dist/ecommerce/hooks/useProducts.d.ts.map +1 -1
- package/dist/ecommerce/index.d.ts +2 -0
- package/dist/ecommerce/index.d.ts.map +1 -1
- package/dist/ecommerce/integrations/cedros-pay/useCedrosPayCheckoutAdapter.d.ts.map +1 -1
- package/dist/ecommerce/state/cart/CartProvider.d.ts.map +1 -1
- package/dist/ecommerce/state/checkout/checkoutSchema.d.ts +1 -1
- package/dist/ecommerce/state/checkout/useCheckout.d.ts.map +1 -1
- package/dist/ecommerce/templates/ProductTemplate.d.ts.map +1 -1
- package/dist/ecommerce/utils/storage.d.ts +1 -1
- package/dist/ecommerce/utils/storage.d.ts.map +1 -1
- package/dist/hooks/useCreditsPayment.d.ts.map +1 -1
- package/dist/hooks/useCreditsSubscription.d.ts.map +1 -1
- package/dist/hooks/useCryptoSubscription.d.ts.map +1 -1
- package/dist/hooks/useRefundVerification.d.ts.map +1 -1
- package/dist/hooks/useStripeCheckout.d.ts +1 -1
- package/dist/hooks/useStripeCheckout.d.ts.map +1 -1
- package/dist/hooks/useSubscription.d.ts.map +1 -1
- package/dist/hooks/useSubscriptionManagement.d.ts.map +1 -1
- package/dist/hooks/useX402Payment.d.ts.map +1 -1
- package/dist/index-B-0trqeD.js +84 -0
- package/dist/index-bbSf3B7-.mjs +22915 -0
- package/dist/index.js +1 -1
- package/dist/index.mjs +67 -72
- package/dist/managers/CreditsManager.d.ts +6 -0
- package/dist/managers/CreditsManager.d.ts.map +1 -1
- package/dist/managers/ManagerCache.d.ts.map +1 -1
- package/dist/managers/RouteDiscoveryManager.d.ts +3 -0
- package/dist/managers/RouteDiscoveryManager.d.ts.map +1 -1
- package/dist/managers/StripeManager.d.ts +15 -0
- package/dist/managers/StripeManager.d.ts.map +1 -1
- package/dist/managers/SubscriptionChangeManager.d.ts.map +1 -1
- package/dist/managers/SubscriptionManager.d.ts +7 -14
- package/dist/managers/SubscriptionManager.d.ts.map +1 -1
- package/dist/managers/WalletManager.d.ts +2 -1
- package/dist/managers/WalletManager.d.ts.map +1 -1
- package/dist/managers/X402Manager.d.ts.map +1 -1
- package/dist/{sections-CL3lbNui.js → sections-CKwGmrzV.js} +1 -1
- package/dist/{sections-DnmB0qdx.mjs → sections-DpEdFL1B.mjs} +1 -1
- package/dist/stripe-only.js +1 -1
- package/dist/stripe-only.mjs +67 -72
- package/dist/telemetry.js +1 -1
- package/dist/telemetry.mjs +23 -25
- package/dist/testing/index.js +1 -1
- package/dist/testing/index.mjs +1 -1
- package/dist/types/index.d.ts +13 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/useAutosave-B2p6iwh8.js +1 -0
- package/dist/useAutosave-YwMqRzqy.mjs +44 -0
- package/dist/utils/circuitBreaker.d.ts +3 -1
- package/dist/utils/circuitBreaker.d.ts.map +1 -1
- package/dist/utils/cspHelper.d.ts +6 -0
- package/dist/utils/cspHelper.d.ts.map +1 -1
- package/dist/utils/csvHelpers.d.ts +0 -41
- package/dist/utils/csvHelpers.d.ts.map +1 -1
- package/dist/utils/errorHandling.d.ts.map +1 -1
- package/dist/utils/exponentialBackoff.d.ts.map +1 -1
- package/dist/utils/requestDeduplication.d.ts.map +1 -1
- package/dist/utils/telemetry.d.ts.map +1 -1
- package/dist/utils/validateConfig.d.ts +1 -1
- package/dist/utils/validateConfig.d.ts.map +1 -1
- package/dist/walletDetection-JZR3UCOa.mjs +27 -0
- package/dist/walletDetection-bNmV5ItZ.js +1 -0
- package/dist/{walletPool-BR6etEiq.mjs → walletPool-BV_z1lEA.mjs} +1 -1
- package/dist/{walletPool-BZyAG4YS.js → walletPool-DjA7J3a9.js} +1 -1
- package/package.json +8 -7
- package/dist/CedrosContext-C2v_s8cc.js +0 -6
- package/dist/WalletManager-B5KLZK2D.js +0 -1
- package/dist/index-BU0vgA-7.js +0 -136
- package/dist/index-DWXEBUbu.mjs +0 -27912
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),a=require("react"),b=require("./index-B-0trqeD.js"),z=require("./AutosaveIndicator-DxemlKnX.js"),w=[{id:"not_set",label:"Disabled",provider:null},{id:"gemini-2.5-flash",label:"Gemini 2.5 Flash",provider:"gemini"},{id:"gemini-2.5-pro",label:"Gemini 2.5 Pro",provider:"gemini"},{id:"openai-4o",label:"OpenAI 4o",provider:"openai"},{id:"openai-5.1",label:"OpenAI 5.1",provider:"openai"},{id:"openai-5.2",label:"OpenAI 5.2",provider:"openai"}],P=[{task:"site_chat",label:"Site Chat",description:"The conversational model that crafts responses to customer messages",defaultPrompt:`You are a friendly and helpful shopping assistant for our store. Your role is to:
|
|
2
|
+
|
|
3
|
+
- Help customers find products that match their needs
|
|
4
|
+
- Answer questions about products, shipping, returns, and store policies
|
|
5
|
+
- Provide personalized recommendations based on customer preferences
|
|
6
|
+
- Use the Product Searcher tool when customers are looking for specific items
|
|
7
|
+
|
|
8
|
+
Guidelines:
|
|
9
|
+
- Be warm, conversational, and concise
|
|
10
|
+
- Stay focused on helping with shopping-related questions
|
|
11
|
+
- If you don't know something specific about a product, say so honestly
|
|
12
|
+
- Never make up product details, prices, or availability
|
|
13
|
+
- For complex issues (order problems, refunds), direct customers to contact support`},{task:"product_searcher",label:"Product Searcher",description:"Tool used by Site Chat to find products based on customer queries",defaultPrompt:`You are a product search assistant. Given a customer's query, extract relevant search parameters to find matching products.
|
|
14
|
+
|
|
15
|
+
Extract the following when present:
|
|
16
|
+
- Keywords: Main search terms
|
|
17
|
+
- Category: Product category or type
|
|
18
|
+
- Price range: Min/max price if mentioned
|
|
19
|
+
- Attributes: Color, size, material, brand, or other specifications
|
|
20
|
+
- Sort preference: Price, popularity, newest, etc.
|
|
21
|
+
|
|
22
|
+
Return structured search parameters. Be liberal in interpretation - if a customer says "something for my mom's birthday under $50" extract: keywords=gift, price_max=50, occasion=birthday.
|
|
23
|
+
|
|
24
|
+
Do not make assumptions about specific products. Focus only on extracting search intent.`},{task:"related_product_finder",label:"Related Product Finder",description:"AI-powered recommendations for related products on product pages",defaultPrompt:`You are a product recommendation engine. Given a product, suggest related items that customers might also be interested in.
|
|
25
|
+
|
|
26
|
+
Consider these recommendation types:
|
|
27
|
+
- Complementary items: Products that go well together (e.g., phone case for a phone)
|
|
28
|
+
- Similar alternatives: Products in the same category with different features or price points
|
|
29
|
+
- Frequently bought together: Items commonly purchased as a set
|
|
30
|
+
- Upsells: Premium versions or upgrades
|
|
31
|
+
|
|
32
|
+
Guidelines:
|
|
33
|
+
- Prioritize relevance over variety
|
|
34
|
+
- Consider the product's category, price range, and use case
|
|
35
|
+
- Return product IDs or search criteria for related items
|
|
36
|
+
- Aim for 4-8 recommendations with a mix of types`},{task:"product_detail_assistant",label:"Product Detail Assistant",description:"Admin tool to generate product descriptions, suggest tags, and fill out product details",defaultPrompt:`You are a product copywriting assistant helping store administrators create compelling product listings.
|
|
37
|
+
|
|
38
|
+
You can help with:
|
|
39
|
+
- Writing engaging product descriptions that highlight key features and benefits
|
|
40
|
+
- Suggesting relevant tags and categories for better discoverability
|
|
41
|
+
- Creating SEO-friendly titles and meta descriptions
|
|
42
|
+
- Generating bullet points for key features
|
|
43
|
+
- Writing size guides or care instructions when applicable
|
|
44
|
+
|
|
45
|
+
Guidelines:
|
|
46
|
+
- Match the store's brand voice (ask if unclear)
|
|
47
|
+
- Focus on benefits, not just features
|
|
48
|
+
- Use sensory language when appropriate
|
|
49
|
+
- Keep descriptions scannable with short paragraphs
|
|
50
|
+
- Avoid superlatives and unverifiable claims
|
|
51
|
+
- Include relevant keywords naturally for SEO`}],q=[{id:"gemini",label:"Google Gemini API",placeholder:"AIza..."},{id:"openai",label:"OpenAI API",placeholder:"sk-..."}],N={apiKeys:[{provider:"gemini",isConfigured:!1},{provider:"openai",isConfigured:!1}],taskAssignments:P.map(o=>({task:o.task,label:o.label,description:o.description,assignedModel:"not_set",systemPrompt:o.defaultPrompt}))};function W({serverUrl:o,apiKey:d,authManager:c}){const[h,_]=a.useState("api-keys"),[f,y]=a.useState(N),[j,g]=a.useState(!0),[u,l]=a.useState(!1),[v,p]=a.useState(null),[C,x]=a.useState(!1),[E,$]=a.useState(null),m=a.useRef(null),[A,T]=a.useState({gemini:"",openai:""}),[S,R]=a.useState({gemini:!1,openai:!1}),I=a.useCallback(async()=>{try{let e;if(c?.isAuthenticated())e=await c.fetchWithAuth("/admin/config/ai");else{const i={"Content-Type":"application/json"};d&&(i["X-API-Key"]=d);const s=await fetch(`${o}/admin/config/ai`,{headers:i});if(!s.ok)throw new Error(`Failed to fetch: ${s.status}`);e=await s.json()}e.settings&&y(e.settings)}catch{y(N),$("Could not load saved AI settings. Showing defaults.")}finally{g(!1)}},[o,d,c]);a.useEffect(()=>{I()},[I]);const F=a.useCallback(async e=>{const i=A[e];if(i.trim()){l(!0),p(null);try{const s={provider:e,apiKey:i};if(c?.isAuthenticated())await c.fetchWithAuth("/admin/config/ai/api-key",{method:"PUT",body:JSON.stringify(s)});else{const n={"Content-Type":"application/json"};d&&(n["X-API-Key"]=d);const r=await fetch(`${o}/admin/config/ai/api-key`,{method:"PUT",headers:n,body:JSON.stringify(s)});if(!r.ok)throw new Error(`Failed to save: ${r.status}`)}y(n=>({...n,apiKeys:n.apiKeys.map(r=>r.provider===e?{...r,isConfigured:!0,maskedKey:`${i.slice(0,4)}...${i.slice(-4)}`,updatedAt:new Date().toISOString()}:r)})),T(n=>({...n,[e]:""})),x(!0),m.current&&clearTimeout(m.current),m.current=setTimeout(()=>x(!1),3e3)}catch(s){p(s instanceof Error?s.message:"Failed to save API key")}finally{l(!1)}}},[A,o,d,c]),O=a.useCallback(async e=>{if(confirm(`Are you sure you want to delete the ${e==="gemini"?"Google Gemini":"OpenAI"} API key?`)){l(!0),p(null);try{if(c?.isAuthenticated())await c.fetchWithAuth(`/admin/config/ai/api-key/${e}`,{method:"DELETE"});else{const i={"Content-Type":"application/json"};d&&(i["X-API-Key"]=d);const s=await fetch(`${o}/admin/config/ai/api-key/${e}`,{method:"DELETE",headers:i});if(!s.ok)throw new Error(`Failed to delete: ${s.status}`)}y(i=>({...i,apiKeys:i.apiKeys.map(s=>s.provider===e?{provider:e,isConfigured:!1}:s)}))}catch(i){p(i instanceof Error?i.message:"Failed to delete API key")}finally{l(!1)}}},[o,d,c]),D=a.useCallback(async(e,i)=>{l(!0),p(null);try{const s={task:e,model:i};if(c?.isAuthenticated())await c.fetchWithAuth("/admin/config/ai/assignment",{method:"PUT",body:JSON.stringify(s)});else{const n={"Content-Type":"application/json"};d&&(n["X-API-Key"]=d);const r=await fetch(`${o}/admin/config/ai/assignment`,{method:"PUT",headers:n,body:JSON.stringify(s)});if(!r.ok)throw new Error(`Failed to save: ${r.status}`)}y(n=>({...n,taskAssignments:n.taskAssignments.map(r=>r.task===e?{...r,assignedModel:i}:r)})),x(!0),m.current&&clearTimeout(m.current),m.current=setTimeout(()=>x(!1),3e3)}catch(s){p(s instanceof Error?s.message:"Failed to save assignment")}finally{l(!1)}},[o,d,c]),k=a.useCallback(e=>{if(e==="not_set")return!0;const i=w.find(n=>n.id===e);return i?.provider?f.apiKeys.find(n=>n.provider===i.provider)?.isConfigured??!1:!0},[f.apiKeys]),K=a.useMemo(()=>w.map(e=>{const i=k(e.id);return{value:e.id,label:i?e.label:`${e.label} (API key required)`,disabled:!i}}),[k]),G=a.useCallback(async(e,i)=>{l(!0),p(null);try{const s={task:e,systemPrompt:i};if(c?.isAuthenticated())await c.fetchWithAuth("/admin/config/ai/prompt",{method:"PUT",body:JSON.stringify(s)});else{const n={"Content-Type":"application/json"};d&&(n["X-API-Key"]=d);const r=await fetch(`${o}/admin/config/ai/prompt`,{method:"PUT",headers:n,body:JSON.stringify(s)});if(!r.ok)throw new Error(`Failed to save: ${r.status}`)}y(n=>({...n,taskAssignments:n.taskAssignments.map(r=>r.task===e?{...r,systemPrompt:i}:r)})),x(!0),m.current&&clearTimeout(m.current),m.current=setTimeout(()=>x(!1),3e3)}catch(s){p(s instanceof Error?s.message:"Failed to save prompt")}finally{l(!1)}},[o,d,c]);return a.useEffect(()=>()=>{m.current&&clearTimeout(m.current)},[]),j?t.jsx("div",{className:"cedros-admin__section",children:t.jsxs("div",{className:"cedros-admin__loading",children:[b.Icons.loading," Loading AI settings..."]})}):t.jsxs("div",{className:"cedros-admin__ai-settings",children:[t.jsxs("div",{className:"cedros-admin__page-header",children:[t.jsx("h2",{className:"cedros-admin__page-title",children:"Store AI"}),t.jsx("p",{className:"cedros-admin__page-description",children:"Configure AI providers, model assignments, and system prompts."})]}),t.jsxs("div",{className:"cedros-admin__tabs cedros-admin__tabs--line",children:[t.jsx("button",{type:"button",className:`cedros-admin__tab ${h==="api-keys"?"cedros-admin__tab--active":""}`,onClick:()=>_("api-keys"),children:"API Keys"}),t.jsx("button",{type:"button",className:`cedros-admin__tab ${h==="assignments"?"cedros-admin__tab--active":""}`,onClick:()=>_("assignments"),children:"Model Assignments"}),t.jsx("button",{type:"button",className:`cedros-admin__tab ${h==="prompts"?"cedros-admin__tab--active":""}`,onClick:()=>_("prompts"),children:"Prompts"})]}),v&&t.jsx("div",{className:"cedros-admin__error-banner",style:{marginTop:"1rem"},children:v}),t.jsx(b.ErrorBanner,{message:E,onRetry:I}),C&&t.jsxs("div",{className:"cedros-admin__success-banner",style:{marginTop:"1rem"},children:[b.Icons.check," Settings saved successfully"]}),h==="api-keys"&&t.jsxs("div",{className:"cedros-admin__section",style:{marginTop:"1rem"},children:[t.jsx("div",{className:"cedros-admin__section-header",children:t.jsx("h3",{className:"cedros-admin__section-title",children:"API Keys"})}),t.jsx("p",{style:{marginBottom:"1.5rem",opacity:.7,fontSize:14},children:"Configure API keys for AI providers. Keys are stored securely and never exposed."}),t.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"1.5rem"},children:q.map(e=>{const i=f.apiKeys.find(n=>n.provider===e.id),s=i?.isConfigured??!1;return t.jsxs("div",{className:"cedros-admin__api-key-card",style:{padding:"1rem",border:"1px solid var(--cedros-admin-border)",borderRadius:8},children:[t.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:"0.75rem"},children:[t.jsxs("div",{children:[t.jsx("div",{style:{fontWeight:600},children:e.label}),s&&i?.maskedKey&&t.jsxs("div",{style:{fontSize:12,opacity:.6,marginTop:2},children:["Current key: ",i.maskedKey,i.updatedAt&&t.jsxs("span",{children:[" (updated ",new Date(i.updatedAt).toLocaleDateString(),")"]})]})]}),t.jsx("span",{className:`cedros-admin__badge ${s?"cedros-admin__badge--success":"cedros-admin__badge--muted"}`,children:s?"Configured":"Not Set"})]}),t.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"0.75rem"},children:t.jsxs("div",{style:{display:"flex",gap:"0.5rem",alignItems:"center"},children:[t.jsx("input",{type:S[e.id]?"text":"password",className:"cedros-admin__input",placeholder:s?"Enter new key to replace":e.placeholder,value:A[e.id],onChange:n=>T(r=>({...r,[e.id]:n.target.value})),onBlur:()=>{A[e.id].trim()&&F(e.id)},style:{flex:1}}),t.jsx("button",{type:"button",className:"cedros-admin__button cedros-admin__button--ghost",onClick:()=>R(n=>({...n,[e.id]:!n[e.id]})),title:S[e.id]?"Hide key":"Show key",style:{padding:"0.5rem"},children:S[e.id]?b.Icons.eyeOff:b.Icons.eye}),s&&t.jsx("button",{type:"button",className:"cedros-admin__button cedros-admin__button--ghost cedros-admin__button--danger",onClick:()=>O(e.id),disabled:u,title:"Remove API key",style:{padding:"0.5rem"},children:b.Icons.trash})]})})]},e.id)})})]}),h==="assignments"&&t.jsxs("div",{className:"cedros-admin__section",style:{marginTop:"1rem"},children:[t.jsx("div",{className:"cedros-admin__section-header",children:t.jsx("h3",{className:"cedros-admin__section-title",children:"Model Assignments"})}),t.jsx("p",{style:{marginBottom:"1.5rem",opacity:.7,fontSize:14},children:"Assign AI models to specific tasks. Models require their provider's API key to be configured."}),t.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"1rem"},children:f.taskAssignments.map(e=>{const i=P.find(n=>n.task===e.task),s=w.find(n=>n.id===e.assignedModel);return t.jsxs("div",{style:{padding:"1rem",border:"1px solid var(--cedros-admin-border)",borderRadius:8},children:[t.jsxs("div",{style:{marginBottom:"0.75rem"},children:[t.jsx("div",{style:{fontWeight:600},children:i?.label??e.task}),t.jsx("div",{style:{fontSize:13,opacity:.7,marginTop:2},children:i?.description})]}),t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"0.75rem"},children:[t.jsx(b.FormDropdown,{value:e.assignedModel,onChange:n=>D(e.task,n),options:K,label:"",disabled:u,style:{flex:1,maxWidth:280}}),s&&s.provider&&t.jsx("span",{className:`cedros-admin__badge ${k(s.id)?"cedros-admin__badge--success":"cedros-admin__badge--warning"}`,children:k(s.id)?"Ready":"Missing API Key"})]})]},e.task)})})]}),h==="prompts"&&t.jsxs("div",{className:"cedros-admin__section",style:{marginTop:"1rem"},children:[t.jsx("div",{className:"cedros-admin__section-header",children:t.jsx("h3",{className:"cedros-admin__section-title",children:"System Prompts"})}),t.jsx("p",{style:{marginBottom:"1.5rem",opacity:.7,fontSize:14},children:"Configure the default system prompts for each AI task. These prompts guide the AI's behavior and responses."}),t.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"1.5rem"},children:f.taskAssignments.map(e=>{const i=P.find(s=>s.task===e.task);return t.jsx(B,{task:e.task,label:i?.label??e.task,description:i?.description??"",initialPrompt:e.systemPrompt??"",onSave:G},e.task)})})]})]})}function B({task:o,label:d,description:c,initialPrompt:h,onSave:_}){const[f,y]=a.useState(h),[j,g]=a.useState("idle"),u=a.useRef(null),l=a.useRef(null),v=a.useRef(!0);return a.useEffect(()=>{if(v.current){v.current=!1;return}return u.current&&clearTimeout(u.current),l.current&&clearTimeout(l.current),g("pending"),u.current=setTimeout(async()=>{g("saving");try{await _(o,f),g("saved"),l.current=setTimeout(()=>g("idle"),2e3)}catch{g("error")}},1500),()=>{u.current&&clearTimeout(u.current)}},[f,o,_]),a.useEffect(()=>()=>{u.current&&clearTimeout(u.current),l.current&&clearTimeout(l.current)},[]),t.jsxs("div",{style:{padding:"1rem",border:"1px solid var(--cedros-admin-border)",borderRadius:8},children:[t.jsxs("div",{style:{marginBottom:"0.75rem",display:"flex",justifyContent:"space-between",alignItems:"flex-start"},children:[t.jsxs("div",{children:[t.jsx("div",{style:{fontWeight:600},children:d}),t.jsx("div",{style:{fontSize:13,opacity:.7,marginTop:2},children:c})]}),t.jsx(z.AutosaveIndicator,{status:j})]}),t.jsx("textarea",{className:"cedros-admin__input",value:f,onChange:p=>y(p.target.value),placeholder:"Enter system prompt...",rows:4,style:{width:"100%",resize:"vertical",fontFamily:"inherit",minHeight:100}})]})}exports.AISettingsSection=W;
|
|
@@ -0,0 +1,539 @@
|
|
|
1
|
+
import { jsx as n, jsxs as r } from "react/jsx-runtime";
|
|
2
|
+
import { useState as u, useRef as S, useCallback as A, useEffect as T, useMemo as q } from "react";
|
|
3
|
+
import { $ as w, a0 as J, a2 as Y } from "./index-bbSf3B7-.mjs";
|
|
4
|
+
import { A as X } from "./AutosaveIndicator-G2CRN8hH.mjs";
|
|
5
|
+
const E = [
|
|
6
|
+
{ id: "not_set", label: "Disabled", provider: null },
|
|
7
|
+
{ id: "gemini-2.5-flash", label: "Gemini 2.5 Flash", provider: "gemini" },
|
|
8
|
+
{ id: "gemini-2.5-pro", label: "Gemini 2.5 Pro", provider: "gemini" },
|
|
9
|
+
{ id: "openai-4o", label: "OpenAI 4o", provider: "openai" },
|
|
10
|
+
{ id: "openai-5.1", label: "OpenAI 5.1", provider: "openai" },
|
|
11
|
+
{ id: "openai-5.2", label: "OpenAI 5.2", provider: "openai" }
|
|
12
|
+
], $ = [
|
|
13
|
+
{
|
|
14
|
+
task: "site_chat",
|
|
15
|
+
label: "Site Chat",
|
|
16
|
+
description: "The conversational model that crafts responses to customer messages",
|
|
17
|
+
defaultPrompt: `You are a friendly and helpful shopping assistant for our store. Your role is to:
|
|
18
|
+
|
|
19
|
+
- Help customers find products that match their needs
|
|
20
|
+
- Answer questions about products, shipping, returns, and store policies
|
|
21
|
+
- Provide personalized recommendations based on customer preferences
|
|
22
|
+
- Use the Product Searcher tool when customers are looking for specific items
|
|
23
|
+
|
|
24
|
+
Guidelines:
|
|
25
|
+
- Be warm, conversational, and concise
|
|
26
|
+
- Stay focused on helping with shopping-related questions
|
|
27
|
+
- If you don't know something specific about a product, say so honestly
|
|
28
|
+
- Never make up product details, prices, or availability
|
|
29
|
+
- For complex issues (order problems, refunds), direct customers to contact support`
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
task: "product_searcher",
|
|
33
|
+
label: "Product Searcher",
|
|
34
|
+
description: "Tool used by Site Chat to find products based on customer queries",
|
|
35
|
+
defaultPrompt: `You are a product search assistant. Given a customer's query, extract relevant search parameters to find matching products.
|
|
36
|
+
|
|
37
|
+
Extract the following when present:
|
|
38
|
+
- Keywords: Main search terms
|
|
39
|
+
- Category: Product category or type
|
|
40
|
+
- Price range: Min/max price if mentioned
|
|
41
|
+
- Attributes: Color, size, material, brand, or other specifications
|
|
42
|
+
- Sort preference: Price, popularity, newest, etc.
|
|
43
|
+
|
|
44
|
+
Return structured search parameters. Be liberal in interpretation - if a customer says "something for my mom's birthday under $50" extract: keywords=gift, price_max=50, occasion=birthday.
|
|
45
|
+
|
|
46
|
+
Do not make assumptions about specific products. Focus only on extracting search intent.`
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
task: "related_product_finder",
|
|
50
|
+
label: "Related Product Finder",
|
|
51
|
+
description: "AI-powered recommendations for related products on product pages",
|
|
52
|
+
defaultPrompt: `You are a product recommendation engine. Given a product, suggest related items that customers might also be interested in.
|
|
53
|
+
|
|
54
|
+
Consider these recommendation types:
|
|
55
|
+
- Complementary items: Products that go well together (e.g., phone case for a phone)
|
|
56
|
+
- Similar alternatives: Products in the same category with different features or price points
|
|
57
|
+
- Frequently bought together: Items commonly purchased as a set
|
|
58
|
+
- Upsells: Premium versions or upgrades
|
|
59
|
+
|
|
60
|
+
Guidelines:
|
|
61
|
+
- Prioritize relevance over variety
|
|
62
|
+
- Consider the product's category, price range, and use case
|
|
63
|
+
- Return product IDs or search criteria for related items
|
|
64
|
+
- Aim for 4-8 recommendations with a mix of types`
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
task: "product_detail_assistant",
|
|
68
|
+
label: "Product Detail Assistant",
|
|
69
|
+
description: "Admin tool to generate product descriptions, suggest tags, and fill out product details",
|
|
70
|
+
defaultPrompt: `You are a product copywriting assistant helping store administrators create compelling product listings.
|
|
71
|
+
|
|
72
|
+
You can help with:
|
|
73
|
+
- Writing engaging product descriptions that highlight key features and benefits
|
|
74
|
+
- Suggesting relevant tags and categories for better discoverability
|
|
75
|
+
- Creating SEO-friendly titles and meta descriptions
|
|
76
|
+
- Generating bullet points for key features
|
|
77
|
+
- Writing size guides or care instructions when applicable
|
|
78
|
+
|
|
79
|
+
Guidelines:
|
|
80
|
+
- Match the store's brand voice (ask if unclear)
|
|
81
|
+
- Focus on benefits, not just features
|
|
82
|
+
- Use sensory language when appropriate
|
|
83
|
+
- Keep descriptions scannable with short paragraphs
|
|
84
|
+
- Avoid superlatives and unverifiable claims
|
|
85
|
+
- Include relevant keywords naturally for SEO`
|
|
86
|
+
}
|
|
87
|
+
], H = [
|
|
88
|
+
{ id: "gemini", label: "Google Gemini API", placeholder: "AIza..." },
|
|
89
|
+
{ id: "openai", label: "OpenAI API", placeholder: "sk-..." }
|
|
90
|
+
], D = {
|
|
91
|
+
apiKeys: [
|
|
92
|
+
{ provider: "gemini", isConfigured: !1 },
|
|
93
|
+
{ provider: "openai", isConfigured: !1 }
|
|
94
|
+
],
|
|
95
|
+
taskAssignments: $.map((o) => ({
|
|
96
|
+
task: o.task,
|
|
97
|
+
label: o.label,
|
|
98
|
+
description: o.description,
|
|
99
|
+
assignedModel: "not_set",
|
|
100
|
+
systemPrompt: o.defaultPrompt
|
|
101
|
+
}))
|
|
102
|
+
};
|
|
103
|
+
function ee({ serverUrl: o, apiKey: d, authManager: c }) {
|
|
104
|
+
const [y, _] = u("api-keys"), [h, g] = u(D), [N, b] = u(!0), [p, l] = u(!1), [k, f] = u(null), [O, v] = u(!1), [K, R] = u(null), m = S(null), [I, F] = u({
|
|
105
|
+
gemini: "",
|
|
106
|
+
openai: ""
|
|
107
|
+
}), [x, G] = u({
|
|
108
|
+
gemini: !1,
|
|
109
|
+
openai: !1
|
|
110
|
+
}), C = A(async () => {
|
|
111
|
+
try {
|
|
112
|
+
let e;
|
|
113
|
+
if (c?.isAuthenticated())
|
|
114
|
+
e = await c.fetchWithAuth("/admin/config/ai");
|
|
115
|
+
else {
|
|
116
|
+
const s = { "Content-Type": "application/json" };
|
|
117
|
+
d && (s["X-API-Key"] = d);
|
|
118
|
+
const t = await fetch(`${o}/admin/config/ai`, { headers: s });
|
|
119
|
+
if (!t.ok) throw new Error(`Failed to fetch: ${t.status}`);
|
|
120
|
+
e = await t.json();
|
|
121
|
+
}
|
|
122
|
+
e.settings && g(e.settings);
|
|
123
|
+
} catch {
|
|
124
|
+
g(D), R("Could not load saved AI settings. Showing defaults.");
|
|
125
|
+
} finally {
|
|
126
|
+
b(!1);
|
|
127
|
+
}
|
|
128
|
+
}, [o, d, c]);
|
|
129
|
+
T(() => {
|
|
130
|
+
C();
|
|
131
|
+
}, [C]);
|
|
132
|
+
const z = A(
|
|
133
|
+
async (e) => {
|
|
134
|
+
const s = I[e];
|
|
135
|
+
if (s.trim()) {
|
|
136
|
+
l(!0), f(null);
|
|
137
|
+
try {
|
|
138
|
+
const t = { provider: e, apiKey: s };
|
|
139
|
+
if (c?.isAuthenticated())
|
|
140
|
+
await c.fetchWithAuth("/admin/config/ai/api-key", {
|
|
141
|
+
method: "PUT",
|
|
142
|
+
body: JSON.stringify(t)
|
|
143
|
+
});
|
|
144
|
+
else {
|
|
145
|
+
const i = { "Content-Type": "application/json" };
|
|
146
|
+
d && (i["X-API-Key"] = d);
|
|
147
|
+
const a = await fetch(`${o}/admin/config/ai/api-key`, {
|
|
148
|
+
method: "PUT",
|
|
149
|
+
headers: i,
|
|
150
|
+
body: JSON.stringify(t)
|
|
151
|
+
});
|
|
152
|
+
if (!a.ok) throw new Error(`Failed to save: ${a.status}`);
|
|
153
|
+
}
|
|
154
|
+
g((i) => ({
|
|
155
|
+
...i,
|
|
156
|
+
apiKeys: i.apiKeys.map(
|
|
157
|
+
(a) => a.provider === e ? {
|
|
158
|
+
...a,
|
|
159
|
+
isConfigured: !0,
|
|
160
|
+
maskedKey: `${s.slice(0, 4)}...${s.slice(-4)}`,
|
|
161
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
162
|
+
} : a
|
|
163
|
+
)
|
|
164
|
+
})), F((i) => ({ ...i, [e]: "" })), v(!0), m.current && clearTimeout(m.current), m.current = setTimeout(() => v(!1), 3e3);
|
|
165
|
+
} catch (t) {
|
|
166
|
+
f(t instanceof Error ? t.message : "Failed to save API key");
|
|
167
|
+
} finally {
|
|
168
|
+
l(!1);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
[I, o, d, c]
|
|
173
|
+
), j = A(
|
|
174
|
+
async (e) => {
|
|
175
|
+
if (confirm(`Are you sure you want to delete the ${e === "gemini" ? "Google Gemini" : "OpenAI"} API key?`)) {
|
|
176
|
+
l(!0), f(null);
|
|
177
|
+
try {
|
|
178
|
+
if (c?.isAuthenticated())
|
|
179
|
+
await c.fetchWithAuth(`/admin/config/ai/api-key/${e}`, {
|
|
180
|
+
method: "DELETE"
|
|
181
|
+
});
|
|
182
|
+
else {
|
|
183
|
+
const s = { "Content-Type": "application/json" };
|
|
184
|
+
d && (s["X-API-Key"] = d);
|
|
185
|
+
const t = await fetch(`${o}/admin/config/ai/api-key/${e}`, {
|
|
186
|
+
method: "DELETE",
|
|
187
|
+
headers: s
|
|
188
|
+
});
|
|
189
|
+
if (!t.ok) throw new Error(`Failed to delete: ${t.status}`);
|
|
190
|
+
}
|
|
191
|
+
g((s) => ({
|
|
192
|
+
...s,
|
|
193
|
+
apiKeys: s.apiKeys.map(
|
|
194
|
+
(t) => t.provider === e ? { provider: e, isConfigured: !1 } : t
|
|
195
|
+
)
|
|
196
|
+
}));
|
|
197
|
+
} catch (s) {
|
|
198
|
+
f(s instanceof Error ? s.message : "Failed to delete API key");
|
|
199
|
+
} finally {
|
|
200
|
+
l(!1);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
[o, d, c]
|
|
205
|
+
), W = A(
|
|
206
|
+
async (e, s) => {
|
|
207
|
+
l(!0), f(null);
|
|
208
|
+
try {
|
|
209
|
+
const t = { task: e, model: s };
|
|
210
|
+
if (c?.isAuthenticated())
|
|
211
|
+
await c.fetchWithAuth("/admin/config/ai/assignment", {
|
|
212
|
+
method: "PUT",
|
|
213
|
+
body: JSON.stringify(t)
|
|
214
|
+
});
|
|
215
|
+
else {
|
|
216
|
+
const i = { "Content-Type": "application/json" };
|
|
217
|
+
d && (i["X-API-Key"] = d);
|
|
218
|
+
const a = await fetch(`${o}/admin/config/ai/assignment`, {
|
|
219
|
+
method: "PUT",
|
|
220
|
+
headers: i,
|
|
221
|
+
body: JSON.stringify(t)
|
|
222
|
+
});
|
|
223
|
+
if (!a.ok) throw new Error(`Failed to save: ${a.status}`);
|
|
224
|
+
}
|
|
225
|
+
g((i) => ({
|
|
226
|
+
...i,
|
|
227
|
+
taskAssignments: i.taskAssignments.map(
|
|
228
|
+
(a) => a.task === e ? { ...a, assignedModel: s } : a
|
|
229
|
+
)
|
|
230
|
+
})), v(!0), m.current && clearTimeout(m.current), m.current = setTimeout(() => v(!1), 3e3);
|
|
231
|
+
} catch (t) {
|
|
232
|
+
f(t instanceof Error ? t.message : "Failed to save assignment");
|
|
233
|
+
} finally {
|
|
234
|
+
l(!1);
|
|
235
|
+
}
|
|
236
|
+
},
|
|
237
|
+
[o, d, c]
|
|
238
|
+
), P = A(
|
|
239
|
+
(e) => {
|
|
240
|
+
if (e === "not_set") return !0;
|
|
241
|
+
const s = E.find((i) => i.id === e);
|
|
242
|
+
return s?.provider ? h.apiKeys.find((i) => i.provider === s.provider)?.isConfigured ?? !1 : !0;
|
|
243
|
+
},
|
|
244
|
+
[h.apiKeys]
|
|
245
|
+
), B = q(() => E.map((e) => {
|
|
246
|
+
const s = P(e.id);
|
|
247
|
+
return {
|
|
248
|
+
value: e.id,
|
|
249
|
+
label: s ? e.label : `${e.label} (API key required)`,
|
|
250
|
+
disabled: !s
|
|
251
|
+
};
|
|
252
|
+
}), [P]), L = A(
|
|
253
|
+
async (e, s) => {
|
|
254
|
+
l(!0), f(null);
|
|
255
|
+
try {
|
|
256
|
+
const t = { task: e, systemPrompt: s };
|
|
257
|
+
if (c?.isAuthenticated())
|
|
258
|
+
await c.fetchWithAuth("/admin/config/ai/prompt", {
|
|
259
|
+
method: "PUT",
|
|
260
|
+
body: JSON.stringify(t)
|
|
261
|
+
});
|
|
262
|
+
else {
|
|
263
|
+
const i = { "Content-Type": "application/json" };
|
|
264
|
+
d && (i["X-API-Key"] = d);
|
|
265
|
+
const a = await fetch(`${o}/admin/config/ai/prompt`, {
|
|
266
|
+
method: "PUT",
|
|
267
|
+
headers: i,
|
|
268
|
+
body: JSON.stringify(t)
|
|
269
|
+
});
|
|
270
|
+
if (!a.ok) throw new Error(`Failed to save: ${a.status}`);
|
|
271
|
+
}
|
|
272
|
+
g((i) => ({
|
|
273
|
+
...i,
|
|
274
|
+
taskAssignments: i.taskAssignments.map(
|
|
275
|
+
(a) => a.task === e ? { ...a, systemPrompt: s } : a
|
|
276
|
+
)
|
|
277
|
+
})), v(!0), m.current && clearTimeout(m.current), m.current = setTimeout(() => v(!1), 3e3);
|
|
278
|
+
} catch (t) {
|
|
279
|
+
f(t instanceof Error ? t.message : "Failed to save prompt");
|
|
280
|
+
} finally {
|
|
281
|
+
l(!1);
|
|
282
|
+
}
|
|
283
|
+
},
|
|
284
|
+
[o, d, c]
|
|
285
|
+
);
|
|
286
|
+
return T(() => () => {
|
|
287
|
+
m.current && clearTimeout(m.current);
|
|
288
|
+
}, []), N ? /* @__PURE__ */ n("div", { className: "cedros-admin__section", children: /* @__PURE__ */ r("div", { className: "cedros-admin__loading", children: [
|
|
289
|
+
w.loading,
|
|
290
|
+
" Loading AI settings..."
|
|
291
|
+
] }) }) : /* @__PURE__ */ r("div", { className: "cedros-admin__ai-settings", children: [
|
|
292
|
+
/* @__PURE__ */ r("div", { className: "cedros-admin__page-header", children: [
|
|
293
|
+
/* @__PURE__ */ n("h2", { className: "cedros-admin__page-title", children: "Store AI" }),
|
|
294
|
+
/* @__PURE__ */ n("p", { className: "cedros-admin__page-description", children: "Configure AI providers, model assignments, and system prompts." })
|
|
295
|
+
] }),
|
|
296
|
+
/* @__PURE__ */ r("div", { className: "cedros-admin__tabs cedros-admin__tabs--line", children: [
|
|
297
|
+
/* @__PURE__ */ n(
|
|
298
|
+
"button",
|
|
299
|
+
{
|
|
300
|
+
type: "button",
|
|
301
|
+
className: `cedros-admin__tab ${y === "api-keys" ? "cedros-admin__tab--active" : ""}`,
|
|
302
|
+
onClick: () => _("api-keys"),
|
|
303
|
+
children: "API Keys"
|
|
304
|
+
}
|
|
305
|
+
),
|
|
306
|
+
/* @__PURE__ */ n(
|
|
307
|
+
"button",
|
|
308
|
+
{
|
|
309
|
+
type: "button",
|
|
310
|
+
className: `cedros-admin__tab ${y === "assignments" ? "cedros-admin__tab--active" : ""}`,
|
|
311
|
+
onClick: () => _("assignments"),
|
|
312
|
+
children: "Model Assignments"
|
|
313
|
+
}
|
|
314
|
+
),
|
|
315
|
+
/* @__PURE__ */ n(
|
|
316
|
+
"button",
|
|
317
|
+
{
|
|
318
|
+
type: "button",
|
|
319
|
+
className: `cedros-admin__tab ${y === "prompts" ? "cedros-admin__tab--active" : ""}`,
|
|
320
|
+
onClick: () => _("prompts"),
|
|
321
|
+
children: "Prompts"
|
|
322
|
+
}
|
|
323
|
+
)
|
|
324
|
+
] }),
|
|
325
|
+
k && /* @__PURE__ */ n("div", { className: "cedros-admin__error-banner", style: { marginTop: "1rem" }, children: k }),
|
|
326
|
+
/* @__PURE__ */ n(J, { message: K, onRetry: C }),
|
|
327
|
+
O && /* @__PURE__ */ r("div", { className: "cedros-admin__success-banner", style: { marginTop: "1rem" }, children: [
|
|
328
|
+
w.check,
|
|
329
|
+
" Settings saved successfully"
|
|
330
|
+
] }),
|
|
331
|
+
y === "api-keys" && /* @__PURE__ */ r("div", { className: "cedros-admin__section", style: { marginTop: "1rem" }, children: [
|
|
332
|
+
/* @__PURE__ */ n("div", { className: "cedros-admin__section-header", children: /* @__PURE__ */ n("h3", { className: "cedros-admin__section-title", children: "API Keys" }) }),
|
|
333
|
+
/* @__PURE__ */ n("p", { style: { marginBottom: "1.5rem", opacity: 0.7, fontSize: 14 }, children: "Configure API keys for AI providers. Keys are stored securely and never exposed." }),
|
|
334
|
+
/* @__PURE__ */ n("div", { style: { display: "flex", flexDirection: "column", gap: "1.5rem" }, children: H.map((e) => {
|
|
335
|
+
const s = h.apiKeys.find((i) => i.provider === e.id), t = s?.isConfigured ?? !1;
|
|
336
|
+
return /* @__PURE__ */ r(
|
|
337
|
+
"div",
|
|
338
|
+
{
|
|
339
|
+
className: "cedros-admin__api-key-card",
|
|
340
|
+
style: {
|
|
341
|
+
padding: "1rem",
|
|
342
|
+
border: "1px solid var(--cedros-admin-border)",
|
|
343
|
+
borderRadius: 8
|
|
344
|
+
},
|
|
345
|
+
children: [
|
|
346
|
+
/* @__PURE__ */ r("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: "0.75rem" }, children: [
|
|
347
|
+
/* @__PURE__ */ r("div", { children: [
|
|
348
|
+
/* @__PURE__ */ n("div", { style: { fontWeight: 600 }, children: e.label }),
|
|
349
|
+
t && s?.maskedKey && /* @__PURE__ */ r("div", { style: { fontSize: 12, opacity: 0.6, marginTop: 2 }, children: [
|
|
350
|
+
"Current key: ",
|
|
351
|
+
s.maskedKey,
|
|
352
|
+
s.updatedAt && /* @__PURE__ */ r("span", { children: [
|
|
353
|
+
" (updated ",
|
|
354
|
+
new Date(s.updatedAt).toLocaleDateString(),
|
|
355
|
+
")"
|
|
356
|
+
] })
|
|
357
|
+
] })
|
|
358
|
+
] }),
|
|
359
|
+
/* @__PURE__ */ n(
|
|
360
|
+
"span",
|
|
361
|
+
{
|
|
362
|
+
className: `cedros-admin__badge ${t ? "cedros-admin__badge--success" : "cedros-admin__badge--muted"}`,
|
|
363
|
+
children: t ? "Configured" : "Not Set"
|
|
364
|
+
}
|
|
365
|
+
)
|
|
366
|
+
] }),
|
|
367
|
+
/* @__PURE__ */ n("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: /* @__PURE__ */ r("div", { style: { display: "flex", gap: "0.5rem", alignItems: "center" }, children: [
|
|
368
|
+
/* @__PURE__ */ n(
|
|
369
|
+
"input",
|
|
370
|
+
{
|
|
371
|
+
type: x[e.id] ? "text" : "password",
|
|
372
|
+
className: "cedros-admin__input",
|
|
373
|
+
placeholder: t ? "Enter new key to replace" : e.placeholder,
|
|
374
|
+
value: I[e.id],
|
|
375
|
+
onChange: (i) => F((a) => ({ ...a, [e.id]: i.target.value })),
|
|
376
|
+
onBlur: () => {
|
|
377
|
+
I[e.id].trim() && z(e.id);
|
|
378
|
+
},
|
|
379
|
+
style: { flex: 1 }
|
|
380
|
+
}
|
|
381
|
+
),
|
|
382
|
+
/* @__PURE__ */ n(
|
|
383
|
+
"button",
|
|
384
|
+
{
|
|
385
|
+
type: "button",
|
|
386
|
+
className: "cedros-admin__button cedros-admin__button--ghost",
|
|
387
|
+
onClick: () => G((i) => ({ ...i, [e.id]: !i[e.id] })),
|
|
388
|
+
title: x[e.id] ? "Hide key" : "Show key",
|
|
389
|
+
style: { padding: "0.5rem" },
|
|
390
|
+
children: x[e.id] ? w.eyeOff : w.eye
|
|
391
|
+
}
|
|
392
|
+
),
|
|
393
|
+
t && /* @__PURE__ */ n(
|
|
394
|
+
"button",
|
|
395
|
+
{
|
|
396
|
+
type: "button",
|
|
397
|
+
className: "cedros-admin__button cedros-admin__button--ghost cedros-admin__button--danger",
|
|
398
|
+
onClick: () => j(e.id),
|
|
399
|
+
disabled: p,
|
|
400
|
+
title: "Remove API key",
|
|
401
|
+
style: { padding: "0.5rem" },
|
|
402
|
+
children: w.trash
|
|
403
|
+
}
|
|
404
|
+
)
|
|
405
|
+
] }) })
|
|
406
|
+
]
|
|
407
|
+
},
|
|
408
|
+
e.id
|
|
409
|
+
);
|
|
410
|
+
}) })
|
|
411
|
+
] }),
|
|
412
|
+
y === "assignments" && /* @__PURE__ */ r("div", { className: "cedros-admin__section", style: { marginTop: "1rem" }, children: [
|
|
413
|
+
/* @__PURE__ */ n("div", { className: "cedros-admin__section-header", children: /* @__PURE__ */ n("h3", { className: "cedros-admin__section-title", children: "Model Assignments" }) }),
|
|
414
|
+
/* @__PURE__ */ n("p", { style: { marginBottom: "1.5rem", opacity: 0.7, fontSize: 14 }, children: "Assign AI models to specific tasks. Models require their provider's API key to be configured." }),
|
|
415
|
+
/* @__PURE__ */ n("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: h.taskAssignments.map((e) => {
|
|
416
|
+
const s = $.find((i) => i.task === e.task), t = E.find((i) => i.id === e.assignedModel);
|
|
417
|
+
return /* @__PURE__ */ r(
|
|
418
|
+
"div",
|
|
419
|
+
{
|
|
420
|
+
style: {
|
|
421
|
+
padding: "1rem",
|
|
422
|
+
border: "1px solid var(--cedros-admin-border)",
|
|
423
|
+
borderRadius: 8
|
|
424
|
+
},
|
|
425
|
+
children: [
|
|
426
|
+
/* @__PURE__ */ r("div", { style: { marginBottom: "0.75rem" }, children: [
|
|
427
|
+
/* @__PURE__ */ n("div", { style: { fontWeight: 600 }, children: s?.label ?? e.task }),
|
|
428
|
+
/* @__PURE__ */ n("div", { style: { fontSize: 13, opacity: 0.7, marginTop: 2 }, children: s?.description })
|
|
429
|
+
] }),
|
|
430
|
+
/* @__PURE__ */ r("div", { style: { display: "flex", alignItems: "center", gap: "0.75rem" }, children: [
|
|
431
|
+
/* @__PURE__ */ n(
|
|
432
|
+
Y,
|
|
433
|
+
{
|
|
434
|
+
value: e.assignedModel,
|
|
435
|
+
onChange: (i) => W(e.task, i),
|
|
436
|
+
options: B,
|
|
437
|
+
label: "",
|
|
438
|
+
disabled: p,
|
|
439
|
+
style: { flex: 1, maxWidth: 280 }
|
|
440
|
+
}
|
|
441
|
+
),
|
|
442
|
+
t && t.provider && /* @__PURE__ */ n(
|
|
443
|
+
"span",
|
|
444
|
+
{
|
|
445
|
+
className: `cedros-admin__badge ${P(t.id) ? "cedros-admin__badge--success" : "cedros-admin__badge--warning"}`,
|
|
446
|
+
children: P(t.id) ? "Ready" : "Missing API Key"
|
|
447
|
+
}
|
|
448
|
+
)
|
|
449
|
+
] })
|
|
450
|
+
]
|
|
451
|
+
},
|
|
452
|
+
e.task
|
|
453
|
+
);
|
|
454
|
+
}) })
|
|
455
|
+
] }),
|
|
456
|
+
y === "prompts" && /* @__PURE__ */ r("div", { className: "cedros-admin__section", style: { marginTop: "1rem" }, children: [
|
|
457
|
+
/* @__PURE__ */ n("div", { className: "cedros-admin__section-header", children: /* @__PURE__ */ n("h3", { className: "cedros-admin__section-title", children: "System Prompts" }) }),
|
|
458
|
+
/* @__PURE__ */ n("p", { style: { marginBottom: "1.5rem", opacity: 0.7, fontSize: 14 }, children: "Configure the default system prompts for each AI task. These prompts guide the AI's behavior and responses." }),
|
|
459
|
+
/* @__PURE__ */ n("div", { style: { display: "flex", flexDirection: "column", gap: "1.5rem" }, children: h.taskAssignments.map((e) => {
|
|
460
|
+
const s = $.find((t) => t.task === e.task);
|
|
461
|
+
return /* @__PURE__ */ n(
|
|
462
|
+
M,
|
|
463
|
+
{
|
|
464
|
+
task: e.task,
|
|
465
|
+
label: s?.label ?? e.task,
|
|
466
|
+
description: s?.description ?? "",
|
|
467
|
+
initialPrompt: e.systemPrompt ?? "",
|
|
468
|
+
onSave: L
|
|
469
|
+
},
|
|
470
|
+
e.task
|
|
471
|
+
);
|
|
472
|
+
}) })
|
|
473
|
+
] })
|
|
474
|
+
] });
|
|
475
|
+
}
|
|
476
|
+
function M({
|
|
477
|
+
task: o,
|
|
478
|
+
label: d,
|
|
479
|
+
description: c,
|
|
480
|
+
initialPrompt: y,
|
|
481
|
+
onSave: _
|
|
482
|
+
}) {
|
|
483
|
+
const [h, g] = u(y), [N, b] = u("idle"), p = S(null), l = S(null), k = S(!0);
|
|
484
|
+
return T(() => {
|
|
485
|
+
if (k.current) {
|
|
486
|
+
k.current = !1;
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
return p.current && clearTimeout(p.current), l.current && clearTimeout(l.current), b("pending"), p.current = setTimeout(async () => {
|
|
490
|
+
b("saving");
|
|
491
|
+
try {
|
|
492
|
+
await _(o, h), b("saved"), l.current = setTimeout(() => b("idle"), 2e3);
|
|
493
|
+
} catch {
|
|
494
|
+
b("error");
|
|
495
|
+
}
|
|
496
|
+
}, 1500), () => {
|
|
497
|
+
p.current && clearTimeout(p.current);
|
|
498
|
+
};
|
|
499
|
+
}, [h, o, _]), T(() => () => {
|
|
500
|
+
p.current && clearTimeout(p.current), l.current && clearTimeout(l.current);
|
|
501
|
+
}, []), /* @__PURE__ */ r(
|
|
502
|
+
"div",
|
|
503
|
+
{
|
|
504
|
+
style: {
|
|
505
|
+
padding: "1rem",
|
|
506
|
+
border: "1px solid var(--cedros-admin-border)",
|
|
507
|
+
borderRadius: 8
|
|
508
|
+
},
|
|
509
|
+
children: [
|
|
510
|
+
/* @__PURE__ */ r("div", { style: { marginBottom: "0.75rem", display: "flex", justifyContent: "space-between", alignItems: "flex-start" }, children: [
|
|
511
|
+
/* @__PURE__ */ r("div", { children: [
|
|
512
|
+
/* @__PURE__ */ n("div", { style: { fontWeight: 600 }, children: d }),
|
|
513
|
+
/* @__PURE__ */ n("div", { style: { fontSize: 13, opacity: 0.7, marginTop: 2 }, children: c })
|
|
514
|
+
] }),
|
|
515
|
+
/* @__PURE__ */ n(X, { status: N })
|
|
516
|
+
] }),
|
|
517
|
+
/* @__PURE__ */ n(
|
|
518
|
+
"textarea",
|
|
519
|
+
{
|
|
520
|
+
className: "cedros-admin__input",
|
|
521
|
+
value: h,
|
|
522
|
+
onChange: (f) => g(f.target.value),
|
|
523
|
+
placeholder: "Enter system prompt...",
|
|
524
|
+
rows: 4,
|
|
525
|
+
style: {
|
|
526
|
+
width: "100%",
|
|
527
|
+
resize: "vertical",
|
|
528
|
+
fontFamily: "inherit",
|
|
529
|
+
minHeight: 100
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
)
|
|
533
|
+
]
|
|
534
|
+
}
|
|
535
|
+
);
|
|
536
|
+
}
|
|
537
|
+
export {
|
|
538
|
+
ee as AISettingsSection
|
|
539
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const e=require("react/jsx-runtime"),i=require("./index-B-0trqeD.js");function a({status:n,error:r}){return n==="idle"?null:e.jsxs("span",{className:`cedros-admin__autosave-indicator cedros-admin__autosave-indicator--${n}`,style:{display:"inline-flex",alignItems:"center",gap:"0.375rem",fontSize:"0.8125rem",color:n==="error"?"var(--cedros-admin-error, #ef4444)":"var(--cedros-admin-text-muted, #64748b)"},children:[n==="pending"&&e.jsx("span",{style:{opacity:.7},children:"Unsaved changes"}),n==="saving"&&e.jsxs(e.Fragment,{children:[i.Icons.loading,e.jsx("span",{children:"Saving..."})]}),n==="saved"&&e.jsxs(e.Fragment,{children:[i.Icons.check,e.jsx("span",{style:{color:"var(--cedros-admin-success, #22c55e)"},children:"Saved"})]}),n==="error"&&e.jsxs("span",{children:["Save failed",r?`: ${r}`:""]})]})}exports.AutosaveIndicator=a;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { jsxs as n, jsx as r, Fragment as i } from "react/jsx-runtime";
|
|
2
|
+
import { $ as d } from "./index-bbSf3B7-.mjs";
|
|
3
|
+
function l({ status: e, error: a }) {
|
|
4
|
+
return e === "idle" ? null : /* @__PURE__ */ n(
|
|
5
|
+
"span",
|
|
6
|
+
{
|
|
7
|
+
className: `cedros-admin__autosave-indicator cedros-admin__autosave-indicator--${e}`,
|
|
8
|
+
style: {
|
|
9
|
+
display: "inline-flex",
|
|
10
|
+
alignItems: "center",
|
|
11
|
+
gap: "0.375rem",
|
|
12
|
+
fontSize: "0.8125rem",
|
|
13
|
+
color: e === "error" ? "var(--cedros-admin-error, #ef4444)" : "var(--cedros-admin-text-muted, #64748b)"
|
|
14
|
+
},
|
|
15
|
+
children: [
|
|
16
|
+
e === "pending" && /* @__PURE__ */ r("span", { style: { opacity: 0.7 }, children: "Unsaved changes" }),
|
|
17
|
+
e === "saving" && /* @__PURE__ */ n(i, { children: [
|
|
18
|
+
d.loading,
|
|
19
|
+
/* @__PURE__ */ r("span", { children: "Saving..." })
|
|
20
|
+
] }),
|
|
21
|
+
e === "saved" && /* @__PURE__ */ n(i, { children: [
|
|
22
|
+
d.check,
|
|
23
|
+
/* @__PURE__ */ r("span", { style: { color: "var(--cedros-admin-success, #22c55e)" }, children: "Saved" })
|
|
24
|
+
] }),
|
|
25
|
+
e === "error" && /* @__PURE__ */ n("span", { children: [
|
|
26
|
+
"Save failed",
|
|
27
|
+
a ? `: ${a}` : ""
|
|
28
|
+
] })
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
export {
|
|
34
|
+
l as A
|
|
35
|
+
};
|