1import { r as reactExports, j as jsxRuntimeExports } from "./vendor-react-Bay9Y7Lb.js"; 2import { a as api } from "./index-D0Bmh-UX.js"; 3import { D as DevDebugInfo } from "./AdminShared-P_hor2hS.js"; 4import { bn as Globe, cL as RefreshCw, cc as Save, fY as Facebook, fZ as Apple, bz as EyeOff, bA as Eye, b1 as CircleAlert } from "./vendor-dVNaLJx_.js"; 5import "./vendor-i18n-R-bMoYp_.js"; 6const GoogleIcon = () => /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { viewBox: "0 0 24 24", width: "24", height: "24", xmlns: "http://www.w3.org/2000/svg", className: "fill-current", children: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M12.48 10.92v3.28h7.84c-.24 1.84-.85 3.18-1.73 4.1-1.02 1.02-2.3 1.84-4.32 1.84-5.18 0-9.4-4.22-9.4-9.4s4.22-9.4 9.4-9.4c2.86 0 5.21 1.09 6.84 2.63l2.5-2.5C20.06 2.5 16.73 1 12.48 1 5.83 1 1 5.83 1 12.48s4.83 11.48 11.48 11.48c6.48 0 11.23-4.49 11.23-11.58 0-.79-.07-1.55-.19-2.28z" }) }); 7const DEFAULT_SOCIAL = { 8 google: { enabled: false, clientId: "", clientSecret: "" }, 9 facebook: { enabled: false, clientId: "", clientSecret: "" }, 10 apple: { enabled: false, clientId: "", clientSecret: "" } 11}; 12const SocialSettings = ({ activeRole }) => { 13 const [config, setConfig] = reactExports.useState(DEFAULT_SOCIAL); 14 const [loading, setLoading] = reactExports.useState(true); 15 const [saving, setSaving] = reactExports.useState(false); 16 const [showSecrets, setShowSecrets] = reactExports.useState({}); 17 reactExports.useEffect(() => { 18 loadConfig(); 19 }, []); 20 const loadConfig = async () => { 21 setLoading(true); 22 const saved = await api.getSystemSetting("social_login"); 23 if (saved && saved.value) { 24 setConfig({ ...DEFAULT_SOCIAL, ...saved.value }); 25 } 26 setLoading(false); 27 }; 28 const handleSave = async () => { 29 setSaving(true); 30 try { 31 await api.saveSystemSetting("social_login", config); 32 await api.reloadOAuthStrategies(); 33 alert("Social login settings saved and strategies reloaded."); 34 } catch (e) { 35 alert("Failed to save configuration or reload strategies."); 36 } finally { 37 setSaving(false); 38 } 39 }; 40 const updateProvider = (provider, field, value) => { 41 setConfig((prev) => ({ 42 ...prev, 43 [provider]: { 44 ...prev[provider], 45 [field]: value 46 } 47 })); 48 }; 49 const toggleSecret = (provider) => { 50 setShowSecrets((prev) => ({ ...prev, [provider]: !prev[provider] })); 51 }; 52 if (loading) return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-10 text-center text-zinc-500", children: "Loading Configuration..." }); 53 const providers = [ 54 { key: "google", name: "Google", icon: GoogleIcon, color: "text-red-500 bg-red-50 dark:bg-red-900/20" }, 55 { key: "facebook", name: "Facebook", icon: Facebook, color: "text-blue-600 bg-blue-50 dark:bg-blue-900/20" }, 56 { key: "apple", name: "Apple", icon: Apple, color: "text-zinc-900 bg-zinc-100 dark:text-white dark:bg-zinc-800" } 57 ]; 58 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6 max-w-4xl mx-auto animate-in fade-in", children: [ 59 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white dark:bg-zinc-900 border border-zinc-200 dark:border-zinc-800 rounded-xl p-6 shadow-sm", children: [
60 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-6 pb-6 border-b border-zinc-100 dark:border-zinc-800", children: [ 61 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [ 62 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-12 h-12 bg-indigo-50 dark:bg-indigo-900/20 rounded-xl flex items-center justify-center text-indigo-600 dark:text-indigo-400", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Globe, { size: 24 }) }), 63 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 64 /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-xl font-bold text-zinc-900 dark:text-white", children: "Social Login" }), 65 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-zinc-500", children: "Configure OAuth providers for single sign-on." }) 66 ] }) 67 ] }), 68 /* @__PURE__ */ jsxRuntimeExports.jsxs( 69 "button", 70 { 71 onClick: handleSave, 72 disabled: saving, 73 className: "px-6 py-2 bg-indigo-600 hover:bg-indigo-700 text-white rounded-lg font-bold text-sm flex items-center gap-2 shadow-lg shadow-indigo-500/20 disabled:opacity-50", 74 children: [
75 saving ? /* @__PURE__ */ jsxRuntimeExports.jsx(RefreshCw, { className: "animate-spin", size: 16 }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Save, { size: 16 }), 76 "Save Changes" 77 ] 78 } 79 ) 80 ] }), 81 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-6", children: providers.map((p) => { 82 const providerConfig = config[p.key]; 83 const Icon = p.icon; 84 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-6 rounded-xl border border-zinc-200 dark:border-zinc-700 bg-zinc-50/50 dark:bg-zinc-900/50", children: [ 85 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-4", children: [ 86 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [ 87 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `p-2 rounded-lg ${p.color}`, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Icon, {}) }), 88 /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "font-bold text-zinc-900 dark:text-white text-lg", children: p.name }) 89 ] }),
90 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "flex items-center gap-2 cursor-pointer select-none", children: [ 91 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `text-sm font-bold ${providerConfig.enabled ? "text-emerald-600 dark:text-emerald-400" : "text-zinc-500"}`, children: providerConfig.enabled ? "Enabled" : "Disabled" }), 92 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${providerConfig.enabled ? "bg-emerald-500" : "bg-zinc-300 dark:bg-zinc-600"}`, children: [ 93 /* @__PURE__ */ jsxRuntimeExports.jsx( 94 "input", 95 { 96 type: "checkbox", 97 className: "sr-only", 98 checked: providerConfig.enabled, 99 onChange: (e) => updateProvider(p.key, "enabled", e.target.checked) 100 } 101 ), 102 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `inline-block h-4 w-4 transform rounded-full bg-white transition duration-200 ease-in-out ${providerConfig.enabled ? "translate-x-6" : "translate-x-1"}` }) 103 ] }) 104 ] }) 105 ] }),
106 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `grid grid-cols-1 md:grid-cols-2 gap-4 transition-opacity ${providerConfig.enabled ? "opacity-100" : "opacity-50 pointer-events-none"}`, children: [ 107 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 108 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-bold text-zinc-700 dark:text-zinc-300 mb-1", children: "Client ID" }), 109 /* @__PURE__ */ jsxRuntimeExports.jsx( 110 "input", 111 { 112 value: providerConfig.clientId, 113 onChange: (e) => updateProvider(p.key, "clientId", e.target.value), 114 className: "w-full px-3 py-2 bg-white dark:bg-black border border-zinc-300 dark:border-zinc-700 rounded-lg text-sm text-zinc-900 dark:text-white focus:ring-2 focus:ring-indigo-500 outline-none font-mono", 115 placeholder: `Enter ${p.name} Client ID` 116 } 117 ) 118 ] }), 119 /* @__P
119URE__ */ jsxRuntimeExports.jsxs("div", { children: [ 120 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-bold text-zinc-700 dark:text-zinc-300 mb-1", children: "Client Secret" }), 121 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [ 122 /* @__PURE__ */ jsxRuntimeExports.jsx( 123 "input", 124 { 125 type: showSecrets[p.key] ? "text" : "password", 126 value: providerConfig.clientSecret, 127 onChange: (e) => updateProvider(p.key, "clientSecret", e.target.value), 128 className: "w-full px-3 py-2 bg-white dark:bg-black border border-zinc-300 dark:border-zinc-700 rounded-lg text-sm text-zinc-900 dark:text-white focus:ring-2 focus:ring-indigo-500 outline-none pr-10 font-mono", 129 placeholder: `Enter ${p.name} Client Secret` 130 } 131 ), 132 /* @__PURE__ */ jsxRuntimeExports.jsx( 133 "button", 134 { 135 onClick: () => toggleSecret(p.key), 136 className: "absolute right-3 top-1/2 -translate-y-1/2 text-zinc-400 hover:text-zinc-600 dark:hover:text-zinc-200", 137 children: showSecrets[p.key] ? /* @__PURE__ */ jsxRuntimeExports.jsx(EyeOff, { size: 16 }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Eye, { size: 16 }) 138 } 139 ) 140 ] }) 141 ] }) 142 ] }) 143 ] }, p.key); 144 }) }),
145 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-6 p-4 bg-indigo-50 dark:bg-indigo-900/10 rounded-lg border border-indigo-100 dark:border-indigo-800 flex gap-3", children: [ 146 /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "text-indigo-600 dark:text-indigo-400 shrink-0 mt-0.5", size: 20 }), 147 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 148 /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-sm font-bold text-indigo-900 dark:text-indigo-200", children: "Production Setup Required" }), 149 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-indigo-800 dark:text-indigo-300 mt-1", children: [ 150 "Ensure you have configured the Authorized Redirect URIs in your provider developer consoles to match your production domain:", 151 /* @__PURE__ */ jsxRuntimeExports.jsx("br", {}), 152 /* @__PURE__ */ jsxRuntimeExports.jsx("code", { className: "bg-white/50 dark:bg-black/30 px-1 rounded", children: "https://your-domain.com/api/auth/social/callback" }) 153 ] }) 154 ] }) 155 ] }) 156 ] }), 157 /* @__PURE__ */ jsxRuntimeExports.jsx(DevDebugInfo, { table: "SystemSetting", keyName: "social_login", value: config, isSuperAdmin: activeRole == null ? void 0 : activeRole.isSuperAdmin }) 158 ] }); 159}; 160export { 161 SocialSettings as default 162};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.