UNPKG

@agentdao/core

Version:

Core functionality, skills, and ready-made UI components for AgentDAO - Web3 subscriptions, content generation, social media, help support, live chat, RSS fetching, web search, and agent pricing integration

336 lines (335 loc) 24.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Web3SubscriptionWidget = Web3SubscriptionWidget; const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = require("react"); const theme_1 = require("./theme"); const Web3SubscriptionSkill_1 = require("../Web3SubscriptionSkill"); function Web3SubscriptionWidget({ config, className, style }) { const [isOpen, setIsOpen] = (0, react_1.useState)(false); const [currentStep, setCurrentStep] = (0, react_1.useState)('plans'); const [selectedPlan, setSelectedPlan] = (0, react_1.useState)(null); const [userAddress, setUserAddress] = (0, react_1.useState)(''); const [paymentMethods, setPaymentMethods] = (0, react_1.useState)([]); const [selectedPaymentMethod, setSelectedPaymentMethod] = (0, react_1.useState)(null); const [loading, setLoading] = (0, react_1.useState)(false); const [error, setError] = (0, react_1.useState)(null); const [subscription, setSubscription] = (0, react_1.useState)(null); const theme = (0, theme_1.getTheme)(config.theme || 'auto'); (0, react_1.useEffect)(() => { // Inject CSS variables const styleElement = document.createElement('style'); styleElement.textContent = ` .agentdao-widget { ${(0, theme_1.generateCSSVariables)(theme)} } `; document.head.appendChild(styleElement); return () => { document.head.removeChild(styleElement); }; }, [theme]); const handlePlanSelect = (plan) => { setSelectedPlan(plan); setCurrentStep('payment'); }; const handlePaymentMethodSelect = (method) => { setSelectedPaymentMethod(method); }; const handleSubscribe = async () => { if (!selectedPlan || !selectedPaymentMethod || !userAddress) { setError('Please fill in all required fields'); return; } setLoading(true); setError(null); try { // Convert SubscriptionPlan to the format expected by Web3SubscriptionSkill const plansConfig = config.plans.reduce((acc, plan) => { acc[plan.id] = { name: plan.name, description: plan.description, features: plan.features, pricing: { monthly: { price: plan.price, discount: 0 }, quarterly: { price: plan.price * 3 * 0.9, discount: 10 }, annually: { price: plan.price * 12 * 0.8, discount: 20 } }, billing: { allowTrial: plan.trialDays ? true : false, trialDays: plan.trialDays || 0, gracePeriodDays: 3 } }; return acc; }, {}); const subscriptionSkill = new Web3SubscriptionSkill_1.Web3SubscriptionSkill({ agentId: config.agentId, agentName: config.agentName, domain: config.domain, plans: plansConfig, adaoToken: { address: selectedPaymentMethod.address, decimals: selectedPaymentMethod.decimals, network: 'base' }, provider: { rpcUrl: config.provider?.rpcUrl || 'https://mainnet.base.org', chainId: config.provider?.chainId || 8453, explorer: config.provider?.explorer || 'https://basescan.org' }, payment: { autoApprove: true, requireConfirmation: false, refundPolicy: { enabled: true, gracePeriod: 7 }, billing: { allowTrial: true, trialDays: 7, gracePeriodDays: 3 } }, integration: { webhookUrl: config.onSubscriptionCreated ? undefined : undefined, redirectUrl: undefined, successMessage: 'Subscription created successfully!', errorMessage: 'Failed to create subscription' }, analytics: { trackRevenue: true, trackUsage: true, exportData: false } }); const newSubscription = await subscriptionSkill.createSubscription(userAddress, selectedPlan.id, selectedPlan.billingPeriod); setSubscription(newSubscription); setCurrentStep('success'); if (config.onSubscriptionCreated) { config.onSubscriptionCreated(newSubscription); } } catch (err) { setError(err instanceof Error ? err.message : 'Failed to create subscription'); if (config.onError) { config.onError(err instanceof Error ? err : new Error('Unknown error')); } } finally { setLoading(false); } }; const getPositionStyles = () => { const baseStyles = { position: 'fixed', zIndex: 9999, ...style }; switch (config.position) { case 'bottom-right': return { ...baseStyles, bottom: '20px', right: '20px' }; case 'bottom-left': return { ...baseStyles, bottom: '20px', left: '20px' }; case 'top-right': return { ...baseStyles, top: '20px', right: '20px' }; case 'top-left': return { ...baseStyles, top: '20px', left: '20px' }; case 'center': return { ...baseStyles, top: '50%', left: '50%', transform: 'translate(-50%, -50%)' }; default: return { ...baseStyles, bottom: '20px', right: '20px' }; } }; return ((0, jsx_runtime_1.jsxs)("div", { className: `agentdao-widget ${className || ''}`, style: getPositionStyles(), children: [!isOpen && ((0, jsx_runtime_1.jsx)("button", { onClick: () => setIsOpen(true), style: { width: '60px', height: '60px', borderRadius: '50%', backgroundColor: theme.colors.primary, color: 'white', border: 'none', cursor: 'pointer', boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)', fontSize: '24px', display: 'flex', alignItems: 'center', justifyContent: 'center', }, children: "\uD83D\uDCB0" })), isOpen && ((0, jsx_runtime_1.jsx)("div", { style: { position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, backgroundColor: 'rgba(0, 0, 0, 0.5)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 10000, }, onClick: () => setIsOpen(false), children: (0, jsx_runtime_1.jsxs)("div", { style: { backgroundColor: theme.colors.surface, borderRadius: theme.borderRadius.lg, padding: theme.spacing.lg, maxWidth: '500px', width: '90%', maxHeight: '80vh', overflow: 'auto', boxShadow: '0 20px 25px -5px rgba(0, 0, 0, 0.1)', }, onClick: (e) => e.stopPropagation(), children: [(0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: theme.spacing.lg }, children: [(0, jsx_runtime_1.jsxs)("h2", { style: { color: theme.colors.text, fontSize: theme.typography.fontSize.lg, margin: 0, fontFamily: theme.typography.fontFamily }, children: ["Subscribe to ", config.agentName] }), (0, jsx_runtime_1.jsx)("button", { onClick: () => setIsOpen(false), style: { background: 'none', border: 'none', fontSize: '24px', cursor: 'pointer', color: theme.colors.textSecondary, }, children: "\u00D7" })] }), currentStep === 'plans' && ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h3", { style: { color: theme.colors.text, fontSize: theme.typography.fontSize.md, marginBottom: theme.spacing.md, fontFamily: theme.typography.fontFamily }, children: "Choose a Plan" }), (0, jsx_runtime_1.jsx)("div", { style: { display: 'flex', flexDirection: 'column', gap: theme.spacing.md }, children: config.plans.map((plan) => ((0, jsx_runtime_1.jsxs)("div", { style: { border: `1px solid ${theme.colors.border}`, borderRadius: theme.borderRadius.md, padding: theme.spacing.md, cursor: 'pointer', backgroundColor: plan.popular ? theme.colors.primary + '10' : 'transparent', position: 'relative', }, onClick: () => handlePlanSelect(plan), children: [plan.popular && ((0, jsx_runtime_1.jsx)("div", { style: { position: 'absolute', top: '-8px', right: '16px', backgroundColor: theme.colors.primary, color: 'white', padding: '4px 8px', borderRadius: theme.borderRadius.sm, fontSize: theme.typography.fontSize.xs, }, children: "Popular" })), (0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center' }, children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h4", { style: { color: theme.colors.text, margin: '0 0 4px 0', fontSize: theme.typography.fontSize.md, fontFamily: theme.typography.fontFamily }, children: plan.name }), (0, jsx_runtime_1.jsx)("p", { style: { color: theme.colors.textSecondary, margin: '0 0 8px 0', fontSize: theme.typography.fontSize.sm, fontFamily: theme.typography.fontFamily }, children: plan.description }), (0, jsx_runtime_1.jsx)("ul", { style: { margin: '0 0 8px 0', paddingLeft: '20px', fontSize: theme.typography.fontSize.sm, color: theme.colors.textSecondary, fontFamily: theme.typography.fontFamily }, children: plan.features.map((feature, index) => ((0, jsx_runtime_1.jsx)("li", { children: feature }, index))) })] }), (0, jsx_runtime_1.jsxs)("div", { style: { textAlign: 'right' }, children: [(0, jsx_runtime_1.jsxs)("div", { style: { fontSize: theme.typography.fontSize.lg, fontWeight: 'bold', color: theme.colors.text, fontFamily: theme.typography.fontFamily }, children: ["$", plan.price] }), (0, jsx_runtime_1.jsxs)("div", { style: { fontSize: theme.typography.fontSize.sm, color: theme.colors.textSecondary, fontFamily: theme.typography.fontFamily }, children: ["per ", plan.billingPeriod] }), plan.trialDays && ((0, jsx_runtime_1.jsxs)("div", { style: { fontSize: theme.typography.fontSize.xs, color: theme.colors.success, fontFamily: theme.typography.fontFamily }, children: [plan.trialDays, " days free trial"] }))] })] })] }, plan.id))) })] })), currentStep === 'payment' && ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h3", { style: { color: theme.colors.text, fontSize: theme.typography.fontSize.md, marginBottom: theme.spacing.md, fontFamily: theme.typography.fontFamily }, children: "Payment Details" }), (0, jsx_runtime_1.jsxs)("div", { style: { marginBottom: theme.spacing.md }, children: [(0, jsx_runtime_1.jsx)("label", { style: { display: 'block', marginBottom: '4px', color: theme.colors.text, fontSize: theme.typography.fontSize.sm, fontFamily: theme.typography.fontFamily }, children: "Wallet Address" }), (0, jsx_runtime_1.jsx)("input", { type: "text", value: userAddress, onChange: (e) => setUserAddress(e.target.value), placeholder: "0x...", style: { width: '100%', padding: theme.spacing.sm, border: `1px solid ${theme.colors.border}`, borderRadius: theme.borderRadius.sm, backgroundColor: theme.colors.background, color: theme.colors.text, fontSize: theme.typography.fontSize.sm, fontFamily: theme.typography.fontFamily, boxSizing: 'border-box', } })] }), paymentMethods.length > 0 && ((0, jsx_runtime_1.jsxs)("div", { style: { marginBottom: theme.spacing.md }, children: [(0, jsx_runtime_1.jsx)("label", { style: { display: 'block', marginBottom: '4px', color: theme.colors.text, fontSize: theme.typography.fontSize.sm, fontFamily: theme.typography.fontFamily }, children: "Payment Method" }), (0, jsx_runtime_1.jsx)("div", { style: { display: 'flex', flexDirection: 'column', gap: theme.spacing.sm }, children: paymentMethods.map((method) => ((0, jsx_runtime_1.jsx)("div", { style: { border: `1px solid ${selectedPaymentMethod?.address === method.address ? theme.colors.primary : theme.colors.border}`, borderRadius: theme.borderRadius.sm, padding: theme.spacing.sm, cursor: 'pointer', backgroundColor: selectedPaymentMethod?.address === method.address ? theme.colors.primary + '10' : 'transparent', }, onClick: () => handlePaymentMethodSelect(method), children: (0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center' }, children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { style: { fontWeight: 'bold', color: theme.colors.text, fontSize: theme.typography.fontSize.sm, fontFamily: theme.typography.fontFamily }, children: method.symbol }), (0, jsx_runtime_1.jsxs)("div", { style: { color: theme.colors.textSecondary, fontSize: theme.typography.fontSize.xs, fontFamily: theme.typography.fontFamily }, children: ["Balance: ", method.balance, " ", method.symbol] })] }), (0, jsx_runtime_1.jsxs)("div", { style: { color: theme.colors.textSecondary, fontSize: theme.typography.fontSize.sm, fontFamily: theme.typography.fontFamily }, children: ["$", method.priceUSD?.toFixed(2)] })] }) }, method.address))) })] })), error && ((0, jsx_runtime_1.jsx)("div", { style: { backgroundColor: theme.colors.error + '10', color: theme.colors.error, padding: theme.spacing.sm, borderRadius: theme.borderRadius.sm, marginBottom: theme.spacing.md, fontSize: theme.typography.fontSize.sm, fontFamily: theme.typography.fontFamily }, children: error })), (0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', gap: theme.spacing.sm }, children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => setCurrentStep('plans'), style: { padding: `${theme.spacing.sm} ${theme.spacing.md}`, border: `1px solid ${theme.colors.border}`, borderRadius: theme.borderRadius.sm, backgroundColor: 'transparent', color: theme.colors.text, cursor: 'pointer', fontSize: theme.typography.fontSize.sm, fontFamily: theme.typography.fontFamily, flex: 1, }, children: "Back" }), (0, jsx_runtime_1.jsx)("button", { onClick: handleSubscribe, disabled: loading || !userAddress || !selectedPaymentMethod, style: { padding: `${theme.spacing.sm} ${theme.spacing.md}`, border: 'none', borderRadius: theme.borderRadius.sm, backgroundColor: loading ? theme.colors.secondary : theme.colors.primary, color: 'white', cursor: loading ? 'not-allowed' : 'pointer', fontSize: theme.typography.fontSize.sm, fontFamily: theme.typography.fontFamily, flex: 2, }, children: loading ? 'Processing...' : `Subscribe for $${selectedPlan?.price}` })] })] })), currentStep === 'success' && ((0, jsx_runtime_1.jsxs)("div", { style: { textAlign: 'center' }, children: [(0, jsx_runtime_1.jsx)("div", { style: { fontSize: '48px', marginBottom: theme.spacing.md }, children: "\u2705" }), (0, jsx_runtime_1.jsx)("h3", { style: { color: theme.colors.text, fontSize: theme.typography.fontSize.lg, marginBottom: theme.spacing.sm, fontFamily: theme.typography.fontFamily }, children: "Subscription Created!" }), (0, jsx_runtime_1.jsxs)("p", { style: { color: theme.colors.textSecondary, fontSize: theme.typography.fontSize.sm, marginBottom: theme.spacing.lg, fontFamily: theme.typography.fontFamily }, children: ["You now have access to ", selectedPlan?.name, " features."] }), (0, jsx_runtime_1.jsx)("button", { onClick: () => setIsOpen(false), style: { padding: `${theme.spacing.sm} ${theme.spacing.lg}`, border: 'none', borderRadius: theme.borderRadius.sm, backgroundColor: theme.colors.primary, color: 'white', cursor: 'pointer', fontSize: theme.typography.fontSize.sm, fontFamily: theme.typography.fontFamily, }, children: "Close" })] }))] }) }))] })); }