@shellapps/experience-react 1.1.0 → 1.3.0

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ExperienceProvider.tsx","../src/context.ts","../src/ErrorBoundary.tsx","../src/hooks.ts"],"sourcesContent":["import React, { useEffect, useRef } from 'react';\nimport { Experience } from '@shellapps/experience';\nimport type { ExperienceConfig } from '@shellapps/experience';\nimport { ExperienceContext } from './context';\n\nexport interface ExperienceProviderProps {\n appId: string;\n apiKey: string;\n profileId?: string;\n options?: Partial<Omit<ExperienceConfig, 'appId' | 'apiKey'>>;\n children: React.ReactNode;\n}\n\nexport function ExperienceProvider({ appId, apiKey, profileId, options, children }: ExperienceProviderProps) {\n const instanceRef = useRef<Experience | null>(null);\n\n if (!instanceRef.current) {\n const instance = Experience.init({ appId, apiKey, ...options });\n if (profileId) instance.identify(profileId);\n instanceRef.current = instance;\n }\n\n useEffect(() => {\n if (profileId && instanceRef.current) {\n instanceRef.current.identify(profileId);\n }\n }, [profileId]);\n\n // data-t auto-tracking\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n let el = e.target as HTMLElement | null;\n while (el) {\n const tid = el.getAttribute?.('data-t');\n if (tid) {\n instanceRef.current?.track('element_click', { elementTid: tid });\n break;\n }\n el = el.parentElement;\n }\n };\n document.addEventListener('click', handler, true);\n return () => document.removeEventListener('click', handler, true);\n }, []);\n\n useEffect(() => {\n return () => {\n instanceRef.current?.shutdown();\n };\n }, []);\n\n return (\n <ExperienceContext.Provider value={instanceRef.current}>\n {children}\n </ExperienceContext.Provider>\n );\n}\n","import { createContext } from 'react';\nimport type { Experience } from '@shellapps/experience';\n\nexport const ExperienceContext = createContext<Experience | null>(null);\n","import React from 'react';\nimport type { Experience } from '@shellapps/experience';\nimport { ExperienceContext } from './context';\n\ninterface ErrorBoundaryProps {\n fallback?: React.ReactNode;\n showCommentForm?: boolean;\n onError?: (error: Error, errorInfo: React.ErrorInfo) => void;\n children: React.ReactNode;\n}\n\ninterface ErrorBoundaryState {\n hasError: boolean;\n error: Error | null;\n comment: string;\n submitted: boolean;\n}\n\nexport class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {\n static contextType = ExperienceContext;\n declare context: Experience | null;\n\n state: ErrorBoundaryState = {\n hasError: false,\n error: null,\n comment: '',\n submitted: false,\n };\n\n static getDerivedStateFromError(error: Error): Partial<ErrorBoundaryState> {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void {\n this.context?.captureError(error, {\n extra: { componentStack: errorInfo.componentStack || '' },\n severity: 'fatal' as any,\n });\n this.props.onError?.(error, errorInfo);\n }\n\n private handleSubmitComment = () => {\n if (this.state.comment.trim() && this.state.error) {\n this.context?.captureMessage(\n `User feedback: ${this.state.comment}`,\n 'info',\n );\n this.setState({ submitted: true });\n }\n };\n\n render() {\n if (this.state.hasError) {\n if (this.props.fallback) {\n return this.props.fallback;\n }\n\n return (\n <div style={{ padding: 20, textAlign: 'center' }}>\n <h2>Something went wrong</h2>\n <p>{this.state.error?.message}</p>\n {this.props.showCommentForm && !this.state.submitted && (\n <div>\n <textarea\n placeholder=\"Tell us what happened...\"\n value={this.state.comment}\n onChange={(e) => this.setState({ comment: e.target.value })}\n style={{ width: '100%', minHeight: 80, marginTop: 10 }}\n />\n <button onClick={this.handleSubmitComment} style={{ marginTop: 8 }}>\n Submit\n </button>\n </div>\n )}\n {this.state.submitted && <p>Thank you for your feedback!</p>}\n </div>\n );\n }\n\n return this.props.children;\n }\n}\n","import { useContext, useState, useCallback, useMemo } from 'react';\nimport { ExperienceContext } from './context';\n\nexport function useExperience() {\n const ctx = useContext(ExperienceContext);\n if (!ctx) throw new Error('useExperience must be used within ExperienceProvider');\n return ctx;\n}\n\nexport function useTrack() {\n const experience = useExperience();\n return useMemo(() => ({\n track: (eventName: string, metadata?: Record<string, string>) => experience.track(eventName, metadata),\n trackPageView: () => experience.trackPageView(),\n }), [experience]);\n}\n\nexport function useFlag<T>(flagName: string, defaultValue: T): T {\n const experience = useExperience();\n return experience.getFlag(flagName, defaultValue);\n}\n\ninterface TranslationResult {\n t: (key: string, params?: Record<string, string | number>) => string;\n locale: string;\n setLocale: (locale: string) => void;\n locales: Array<{ code: string; name: string }>;\n}\n\n/**\n * Translation hook — stub implementation for EXP-5.\n * Currently returns the key with interpolation support.\n * Will fetch from the Experience API when translations are implemented.\n */\nexport function useTranslation(): TranslationResult {\n const [locale, setLocaleState] = useState(\n typeof navigator !== 'undefined' ? navigator.language?.split('-')[0] || 'en' : 'en'\n );\n\n const t = useCallback((key: string, params?: Record<string, string | number>): string => {\n let result = key;\n if (params) {\n for (const [k, v] of Object.entries(params)) {\n result = result.replace(new RegExp(`\\\\{\\\\{${k}\\\\}\\\\}`, 'g'), String(v));\n }\n }\n return result;\n }, []);\n\n const setLocale = useCallback((newLocale: string) => {\n setLocaleState(newLocale);\n }, []);\n\n return { t, locale, setLocale, locales: [] };\n}\n"],"mappings":"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","names":["React","jsx","React"]}
1
+ {"version":3,"sources":["../src/ExperienceProvider.tsx","../src/context.ts","../src/ErrorBoundary.tsx","../src/FeedbackButton.tsx","../src/hooks.ts"],"sourcesContent":["import React, { useEffect, useRef } from 'react';\nimport { Experience } from '@shellapps/experience';\nimport type { ExperienceConfig } from '@shellapps/experience';\nimport { ExperienceContext } from './context';\n\nexport interface ExperienceProviderProps {\n appId: string;\n apiKey: string;\n profileId?: string;\n options?: Partial<Omit<ExperienceConfig, 'appId' | 'apiKey'>>;\n children: React.ReactNode;\n}\n\nexport function ExperienceProvider({ appId, apiKey, profileId, options, children }: ExperienceProviderProps) {\n const instanceRef = useRef<Experience | null>(null);\n\n if (!instanceRef.current) {\n const instance = Experience.init({ appId, apiKey, ...options });\n if (profileId) instance.identify(profileId);\n instanceRef.current = instance;\n }\n\n useEffect(() => {\n if (profileId && instanceRef.current) {\n instanceRef.current.identify(profileId);\n }\n }, [profileId]);\n\n // data-t auto-tracking\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n let el = e.target as HTMLElement | null;\n while (el) {\n const tid = el.getAttribute?.('data-t');\n if (tid) {\n instanceRef.current?.track('element_click', { elementTid: tid });\n break;\n }\n el = el.parentElement;\n }\n };\n document.addEventListener('click', handler, true);\n return () => document.removeEventListener('click', handler, true);\n }, []);\n\n useEffect(() => {\n return () => {\n instanceRef.current?.shutdown();\n };\n }, []);\n\n return (\n <ExperienceContext.Provider value={instanceRef.current}>\n {children}\n </ExperienceContext.Provider>\n );\n}\n","import { createContext } from 'react';\nimport type { Experience } from '@shellapps/experience';\n\nexport const ExperienceContext = createContext<Experience | null>(null);\n","import React from 'react';\nimport type { Experience } from '@shellapps/experience';\nimport { ExperienceContext } from './context';\n\ninterface ErrorBoundaryProps {\n fallback?: React.ReactNode;\n showCommentForm?: boolean;\n onError?: (error: Error, errorInfo: React.ErrorInfo) => void;\n children: React.ReactNode;\n}\n\ninterface ErrorBoundaryState {\n hasError: boolean;\n error: Error | null;\n comment: string;\n submitted: boolean;\n}\n\nexport class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {\n static contextType = ExperienceContext;\n declare context: Experience | null;\n\n state: ErrorBoundaryState = {\n hasError: false,\n error: null,\n comment: '',\n submitted: false,\n };\n\n static getDerivedStateFromError(error: Error): Partial<ErrorBoundaryState> {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void {\n this.context?.captureError(error, {\n extra: { componentStack: errorInfo.componentStack || '' },\n severity: 'fatal' as any,\n });\n this.props.onError?.(error, errorInfo);\n }\n\n private handleSubmitComment = () => {\n if (this.state.comment.trim() && this.state.error) {\n this.context?.captureMessage(\n `User feedback: ${this.state.comment}`,\n 'info',\n );\n this.setState({ submitted: true });\n }\n };\n\n render() {\n if (this.state.hasError) {\n if (this.props.fallback) {\n return this.props.fallback;\n }\n\n return (\n <div style={{ padding: 20, textAlign: 'center' }}>\n <h2>Something went wrong</h2>\n <p>{this.state.error?.message}</p>\n {this.props.showCommentForm && !this.state.submitted && (\n <div>\n <textarea\n placeholder=\"Tell us what happened...\"\n value={this.state.comment}\n onChange={(e) => this.setState({ comment: e.target.value })}\n style={{ width: '100%', minHeight: 80, marginTop: 10 }}\n />\n <button onClick={this.handleSubmitComment} style={{ marginTop: 8 }}>\n Submit\n </button>\n </div>\n )}\n {this.state.submitted && <p>Thank you for your feedback!</p>}\n </div>\n );\n }\n\n return this.props.children;\n }\n}\n","import React, { useState, useEffect, useCallback, useRef, useContext } from 'react';\nimport { ExperienceContext } from './context';\n\n// ── Types ──────────────────────────────────────────────────────────────────\n\ntype FeedbackType = 'bug' | 'feature-request' | 'comment' | 'praise';\ntype FeedbackStatus = 'new' | 'acknowledged' | 'in-progress' | 'resolved' | 'wont-fix';\n\ninterface FeedbackItem {\n _id: string;\n type: FeedbackType;\n title: string;\n content: string;\n status: FeedbackStatus;\n tags: string[];\n vote_count: number;\n reply_count: number;\n created_at: string;\n}\n\ninterface FeedbackReply {\n _id: string;\n author_type: 'user' | 'developer';\n author_name?: string;\n content: string;\n created_at: string;\n}\n\ninterface FeedbackButtonProps {\n /** Position of the floating button */\n position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';\n /** Custom button label */\n label?: string;\n /** Button colour */\n color?: string;\n /** Hide the floating button (use exp.openFeedback() instead) */\n hidden?: boolean;\n /** API endpoint base URL */\n apiUrl?: string;\n /** Auth token for user endpoints */\n authToken?: string;\n}\n\n// ── Styles ─────────────────────────────────────────────────────────────────\n\nconst TYPE_META: Record<FeedbackType, { icon: string; label: string; color: string }> = {\n 'bug': { icon: '🐛', label: 'Bug Report', color: '#ef4444' },\n 'feature-request': { icon: '💡', label: 'Feature Request', color: '#8b5cf6' },\n 'comment': { icon: '💬', label: 'Comment', color: '#3b82f6' },\n 'praise': { icon: '🎉', label: 'Praise', color: '#10b981' },\n};\n\nconst STATUS_LABELS: Record<FeedbackStatus, string> = {\n 'new': '🆕 New',\n 'acknowledged': '👀 Acknowledged',\n 'in-progress': '🔧 In Progress',\n 'resolved': '✅ Resolved',\n 'wont-fix': '🚫 Won\\'t Fix',\n};\n\n// ── Component ──────────────────────────────────────────────────────────────\n\nexport function FeedbackButton({\n position = 'bottom-right',\n label = 'Feedback',\n color = '#6366f1',\n hidden = false,\n apiUrl,\n authToken,\n}: FeedbackButtonProps) {\n const experience = useContext(ExperienceContext);\n const [isOpen, setIsOpen] = useState(false);\n const [view, setView] = useState<'list' | 'new' | 'detail'>('list');\n const [selectedType, setSelectedType] = useState<FeedbackType>('comment');\n const [title, setTitle] = useState('');\n const [content, setContent] = useState('');\n const [submitting, setSubmitting] = useState(false);\n const [items, setItems] = useState<FeedbackItem[]>([]);\n const [selectedItem, setSelectedItem] = useState<FeedbackItem | null>(null);\n const [replies, setReplies] = useState<FeedbackReply[]>([]);\n const [replyText, setReplyText] = useState('');\n const [loading, setLoading] = useState(false);\n const [screenshot, setScreenshot] = useState<string | null>(null);\n const panelRef = useRef<HTMLDivElement>(null);\n\n const baseUrl = apiUrl || (experience as any)?.config?.apiUrl || 'https://experience.shellapps.com';\n const appId = (experience as any)?.config?.appId || '';\n\n const headers = useCallback((): Record<string, string> => {\n const h: Record<string, string> = { 'Content-Type': 'application/json' };\n if (authToken) h['Authorization'] = `Bearer ${authToken}`;\n return h;\n }, [authToken]);\n\n // Expose openFeedback on the experience instance\n useEffect(() => {\n if (experience) {\n (experience as any).openFeedback = () => setIsOpen(true);\n }\n return () => {\n if (experience) delete (experience as any).openFeedback;\n };\n }, [experience]);\n\n // Load feedback list when opening\n useEffect(() => {\n if (isOpen && view === 'list') {\n loadFeedback();\n }\n }, [isOpen, view]);\n\n const loadFeedback = async () => {\n setLoading(true);\n try {\n const res = await fetch(\n `${baseUrl}/api/v1/feedback?appId=${appId}&limit=20`,\n { headers: headers() },\n );\n if (res.ok) {\n const data = await res.json();\n setItems(data.items || []);\n }\n } catch {\n // silently fail\n }\n setLoading(false);\n };\n\n const loadDetail = async (item: FeedbackItem) => {\n setSelectedItem(item);\n setView('detail');\n try {\n const res = await fetch(\n `${baseUrl}/api/v1/feedback/${item._id}`,\n { headers: headers() },\n );\n if (res.ok) {\n const data = await res.json();\n setReplies(data.replies || []);\n }\n } catch {\n // silently fail\n }\n };\n\n const captureScreenshot = async () => {\n try {\n const html2canvas = (window as any).html2canvas;\n if (!html2canvas) return;\n const canvas = await html2canvas(document.body, { scale: 0.5, logging: false });\n setScreenshot(canvas.toDataURL('image/jpeg', 0.6));\n } catch {\n // screenshot not available\n }\n };\n\n const submit = async () => {\n if (!title.trim() || !content.trim()) return;\n setSubmitting(true);\n try {\n const ctx = {\n userAgent: navigator.userAgent,\n url: window.location.href,\n viewport: { width: window.innerWidth, height: window.innerHeight },\n locale: navigator.language,\n referrer: document.referrer || undefined,\n };\n\n const res = await fetch(`${baseUrl}/api/v1/feedback`, {\n method: 'POST',\n headers: headers(),\n body: JSON.stringify({\n appId,\n type: selectedType,\n title: title.trim(),\n content: content.trim(),\n context: ctx,\n screenshot: screenshot || undefined,\n }),\n });\n\n if (res.ok) {\n setTitle('');\n setContent('');\n setScreenshot(null);\n setView('list');\n loadFeedback();\n }\n } catch {\n // silently fail\n }\n setSubmitting(false);\n };\n\n const submitReply = async () => {\n if (!replyText.trim() || !selectedItem) return;\n try {\n const res = await fetch(`${baseUrl}/api/v1/feedback/${selectedItem._id}/reply`, {\n method: 'POST',\n headers: headers(),\n body: JSON.stringify({ content: replyText.trim() }),\n });\n if (res.ok) {\n const reply = await res.json();\n setReplies((prev) => [...prev, reply]);\n setReplyText('');\n }\n } catch {\n // silently fail\n }\n };\n\n const vote = async (id: string) => {\n try {\n await fetch(`${baseUrl}/api/v1/feedback/${id}/vote`, {\n method: 'POST',\n headers: headers(),\n body: JSON.stringify({ type: 'upvote' }),\n });\n loadFeedback();\n } catch {\n // silently fail\n }\n };\n\n // ── Position styles ──────────────────────────────────────────────────────\n\n const posStyles: Record<string, React.CSSProperties> = {\n 'bottom-right': { bottom: 20, right: 20 },\n 'bottom-left': { bottom: 20, left: 20 },\n 'top-right': { top: 20, right: 20 },\n 'top-left': { top: 20, left: 20 },\n };\n\n const panelPos: Record<string, React.CSSProperties> = {\n 'bottom-right': { bottom: 70, right: 20 },\n 'bottom-left': { bottom: 70, left: 20 },\n 'top-right': { top: 70, right: 20 },\n 'top-left': { top: 70, left: 20 },\n };\n\n // ── Render ───────────────────────────────────────────────────────────────\n\n return (\n <>\n {/* Floating button */}\n {!hidden && (\n <button\n onClick={() => setIsOpen(!isOpen)}\n style={{\n position: 'fixed',\n ...posStyles[position],\n zIndex: 99999,\n background: color,\n color: '#fff',\n border: 'none',\n borderRadius: 28,\n padding: '10px 20px',\n fontSize: 14,\n fontWeight: 600,\n cursor: 'pointer',\n boxShadow: '0 4px 12px rgba(0,0,0,0.15)',\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n }}\n >\n 💬 {label}\n </button>\n )}\n\n {/* Panel */}\n {isOpen && (\n <div\n ref={panelRef}\n style={{\n position: 'fixed',\n ...panelPos[position],\n zIndex: 100000,\n width: 380,\n maxHeight: 520,\n background: '#fff',\n borderRadius: 12,\n boxShadow: '0 8px 32px rgba(0,0,0,0.18)',\n display: 'flex',\n flexDirection: 'column',\n overflow: 'hidden',\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n fontSize: 14,\n color: '#1f2937',\n }}\n >\n {/* Header */}\n <div\n style={{\n padding: '14px 16px',\n background: color,\n color: '#fff',\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n }}\n >\n <span style={{ fontWeight: 600 }}>\n {view === 'new' ? 'New Feedback' : view === 'detail' ? 'Feedback' : 'Feedback'}\n </span>\n <div style={{ display: 'flex', gap: 8 }}>\n {view !== 'list' && (\n <button\n onClick={() => { setView('list'); setSelectedItem(null); }}\n style={{ background: 'none', border: 'none', color: '#fff', cursor: 'pointer', fontSize: 14 }}\n >\n ← Back\n </button>\n )}\n <button\n onClick={() => setIsOpen(false)}\n style={{ background: 'none', border: 'none', color: '#fff', cursor: 'pointer', fontSize: 18 }}\n >\n ✕\n </button>\n </div>\n </div>\n\n {/* Body */}\n <div style={{ flex: 1, overflow: 'auto', padding: 16 }}>\n {/* LIST VIEW */}\n {view === 'list' && (\n <>\n <button\n onClick={() => setView('new')}\n style={{\n width: '100%',\n padding: '10px',\n background: color,\n color: '#fff',\n border: 'none',\n borderRadius: 8,\n cursor: 'pointer',\n fontWeight: 600,\n marginBottom: 12,\n }}\n >\n + New Feedback\n </button>\n {loading ? (\n <p style={{ textAlign: 'center', color: '#9ca3af' }}>Loading…</p>\n ) : items.length === 0 ? (\n <p style={{ textAlign: 'center', color: '#9ca3af' }}>No feedback yet</p>\n ) : (\n items.map((item) => (\n <div\n key={item._id}\n onClick={() => loadDetail(item)}\n style={{\n padding: 10,\n borderRadius: 8,\n border: '1px solid #e5e7eb',\n marginBottom: 8,\n cursor: 'pointer',\n }}\n >\n <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 4 }}>\n <span>\n {TYPE_META[item.type]?.icon} <strong>{item.title}</strong>\n </span>\n {item.type === 'feature-request' && (\n <button\n onClick={(e) => { e.stopPropagation(); vote(item._id); }}\n style={{\n background: 'none',\n border: '1px solid #d1d5db',\n borderRadius: 4,\n padding: '2px 6px',\n cursor: 'pointer',\n fontSize: 12,\n }}\n >\n ▲ {item.vote_count}\n </button>\n )}\n </div>\n <div style={{ fontSize: 12, color: '#6b7280' }}>\n {STATUS_LABELS[item.status]} · {item.reply_count} replies · {new Date(item.created_at).toLocaleDateString()}\n </div>\n </div>\n ))\n )}\n </>\n )}\n\n {/* NEW FEEDBACK VIEW */}\n {view === 'new' && (\n <>\n {/* Type selector */}\n <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8, marginBottom: 12 }}>\n {(Object.entries(TYPE_META) as [FeedbackType, typeof TYPE_META['bug']][]).map(\n ([type, meta]) => (\n <button\n key={type}\n onClick={() => setSelectedType(type)}\n style={{\n padding: 8,\n borderRadius: 8,\n border: `2px solid ${selectedType === type ? meta.color : '#e5e7eb'}`,\n background: selectedType === type ? `${meta.color}10` : '#fff',\n cursor: 'pointer',\n fontSize: 13,\n textAlign: 'center',\n }}\n >\n {meta.icon} {meta.label}\n </button>\n ),\n )}\n </div>\n\n <input\n placeholder=\"Title\"\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n style={{\n width: '100%',\n padding: 8,\n borderRadius: 6,\n border: '1px solid #d1d5db',\n marginBottom: 8,\n fontSize: 14,\n boxSizing: 'border-box',\n }}\n />\n\n <textarea\n placeholder=\"Describe your feedback…\"\n value={content}\n onChange={(e) => setContent(e.target.value)}\n rows={4}\n style={{\n width: '100%',\n padding: 8,\n borderRadius: 6,\n border: '1px solid #d1d5db',\n marginBottom: 8,\n fontSize: 14,\n resize: 'vertical',\n boxSizing: 'border-box',\n }}\n />\n\n {/* Screenshot button */}\n {(window as any).html2canvas && (\n <button\n onClick={captureScreenshot}\n style={{\n background: 'none',\n border: '1px solid #d1d5db',\n borderRadius: 6,\n padding: '6px 10px',\n cursor: 'pointer',\n fontSize: 12,\n marginBottom: 8,\n color: screenshot ? '#10b981' : '#6b7280',\n }}\n >\n 📷 {screenshot ? 'Screenshot captured ✓' : 'Capture screenshot'}\n </button>\n )}\n\n <button\n onClick={submit}\n disabled={submitting || !title.trim() || !content.trim()}\n style={{\n width: '100%',\n padding: 10,\n background: submitting ? '#9ca3af' : color,\n color: '#fff',\n border: 'none',\n borderRadius: 8,\n cursor: submitting ? 'default' : 'pointer',\n fontWeight: 600,\n }}\n >\n {submitting ? 'Submitting…' : 'Submit'}\n </button>\n </>\n )}\n\n {/* DETAIL VIEW */}\n {view === 'detail' && selectedItem && (\n <>\n <div style={{ marginBottom: 12 }}>\n <div style={{ fontSize: 12, color: TYPE_META[selectedItem.type]?.color, fontWeight: 600, marginBottom: 4 }}>\n {TYPE_META[selectedItem.type]?.icon} {TYPE_META[selectedItem.type]?.label}\n </div>\n <h3 style={{ margin: '0 0 4px', fontSize: 16 }}>{selectedItem.title}</h3>\n <div style={{ fontSize: 12, color: '#6b7280', marginBottom: 8 }}>\n {STATUS_LABELS[selectedItem.status]} · {new Date(selectedItem.created_at).toLocaleDateString()}\n </div>\n <p style={{ margin: 0, lineHeight: 1.5 }}>{selectedItem.content}</p>\n </div>\n\n <hr style={{ border: 'none', borderTop: '1px solid #e5e7eb', margin: '12px 0' }} />\n\n {/* Replies */}\n <div style={{ marginBottom: 12 }}>\n <strong style={{ fontSize: 13 }}>Replies ({replies.length})</strong>\n {replies.map((r) => (\n <div\n key={r._id}\n style={{\n padding: 8,\n marginTop: 8,\n borderRadius: 6,\n background: r.author_type === 'developer' ? '#eff6ff' : '#f9fafb',\n borderLeft: `3px solid ${r.author_type === 'developer' ? '#3b82f6' : '#d1d5db'}`,\n }}\n >\n <div style={{ fontSize: 11, color: '#6b7280', marginBottom: 2 }}>\n {r.author_type === 'developer' ? '🛠️ Developer' : '👤 You'}{r.author_name ? ` · ${r.author_name}` : ''} · {new Date(r.created_at).toLocaleDateString()}\n </div>\n <div style={{ fontSize: 13 }}>{r.content}</div>\n </div>\n ))}\n </div>\n\n {/* Reply input */}\n <div style={{ display: 'flex', gap: 6 }}>\n <input\n placeholder=\"Write a reply…\"\n value={replyText}\n onChange={(e) => setReplyText(e.target.value)}\n onKeyDown={(e) => { if (e.key === 'Enter') submitReply(); }}\n style={{\n flex: 1,\n padding: 8,\n borderRadius: 6,\n border: '1px solid #d1d5db',\n fontSize: 13,\n }}\n />\n <button\n onClick={submitReply}\n disabled={!replyText.trim()}\n style={{\n padding: '8px 12px',\n background: color,\n color: '#fff',\n border: 'none',\n borderRadius: 6,\n cursor: 'pointer',\n fontSize: 13,\n }}\n >\n Send\n </button>\n </div>\n </>\n )}\n </div>\n </div>\n )}\n </>\n );\n}\n","import { useContext, useState, useCallback, useMemo, useEffect, useRef } from 'react';\nimport { ExperienceContext } from './context';\n\nexport function useExperience() {\n const ctx = useContext(ExperienceContext);\n if (!ctx) throw new Error('useExperience must be used within ExperienceProvider');\n return ctx;\n}\n\nexport function useTrack() {\n const experience = useExperience();\n return useMemo(() => ({\n track: (eventName: string, metadata?: Record<string, string>) => experience.track(eventName, metadata),\n trackPageView: () => experience.trackPageView(),\n }), [experience]);\n}\n\nexport function useFlag<T>(flagName: string, defaultValue: T): T {\n const experience = useExperience();\n return experience.getFlag(flagName, defaultValue);\n}\n\n// ─── Translation Types ──────────────────────────────────────────\n\ninterface TranslationResult {\n t: (key: string, params?: Record<string, string | number>) => string;\n locale: string;\n setLocale: (locale: string) => void;\n locales: Array<{ code: string; name: string; progress?: number }>;\n isLoading: boolean;\n}\n\ninterface TranslationCache {\n [locale: string]: Record<string, string>;\n}\n\n// Module-level cache shared across hook instances\nconst translationCache: TranslationCache = {};\nconst fetchPromises = new Map<string, Promise<Record<string, string>>>();\n\n/**\n * Translation hook for the Experience Platform.\n *\n * Fetches translations from the Experience API, caches in memory + localStorage,\n * and provides `t()` for interpolation and `setLocale()` for switching.\n *\n * Usage:\n * ```tsx\n * const { t, locale, setLocale, locales } = useTranslation();\n * return <h1>{t('greeting', { name: 'Alex' })}</h1>;\n * ```\n */\nexport function useTranslation(): TranslationResult {\n const experience = useExperience();\n const config = (experience as any).config || {};\n const appId: string = config.appId || '';\n const apiBaseUrl: string = config.apiUrl || config.baseUrl || 'https://experience-api.shellapps.com';\n\n const [locale, setLocaleState] = useState(() => {\n if (typeof window === 'undefined') return 'en';\n // Check localStorage for persisted locale preference\n const saved = localStorage.getItem(`exp_locale_${appId}`);\n if (saved) return saved;\n return navigator.language?.split('-')[0] || 'en';\n });\n\n const [translations, setTranslations] = useState<Record<string, string>>(() => {\n // Try memory cache first\n if (translationCache[locale]) return translationCache[locale]!;\n // Try localStorage\n if (typeof window !== 'undefined') {\n try {\n const cached = localStorage.getItem(`exp_translations_${appId}_${locale}`);\n if (cached) {\n const parsed = JSON.parse(cached);\n translationCache[locale] = parsed;\n return parsed;\n }\n } catch { /* ignore */ }\n }\n return {};\n });\n\n const [locales, setLocales] = useState<Array<{ code: string; name: string; progress?: number }>>([]);\n const [isLoading, setIsLoading] = useState(false);\n\n // Fetch translations for a locale\n const fetchTranslations = useCallback(async (loc: string): Promise<Record<string, string>> => {\n if (!appId) return {};\n\n // Deduplicate in-flight requests\n const cacheKey = `${appId}_${loc}`;\n const existing = fetchPromises.get(cacheKey);\n if (existing) return existing;\n\n const promise = (async () => {\n try {\n const res = await fetch(`${apiBaseUrl}/api/v1/translations/${appId}/${loc}`);\n if (!res.ok) return {};\n const data = await res.json();\n // Cache in memory and localStorage\n translationCache[loc] = data;\n if (typeof window !== 'undefined') {\n try {\n localStorage.setItem(`exp_translations_${appId}_${loc}`, JSON.stringify(data));\n } catch { /* quota exceeded, ignore */ }\n }\n return data as Record<string, string>;\n } catch {\n return {};\n } finally {\n fetchPromises.delete(cacheKey);\n }\n })();\n\n fetchPromises.set(cacheKey, promise);\n return promise;\n }, [appId, apiBaseUrl]);\n\n // Fetch available locales\n useEffect(() => {\n if (!appId) return;\n fetch(`${apiBaseUrl}/api/v1/translations/${appId}/locales`)\n .then(res => res.ok ? res.json() : { locales: [] })\n .then(data => setLocales(data.locales || []))\n .catch(() => {});\n }, [appId, apiBaseUrl]);\n\n // Fetch translations when locale changes\n useEffect(() => {\n if (!appId) return;\n\n // Use cached if available\n if (translationCache[locale]) {\n setTranslations(translationCache[locale]!);\n return;\n }\n\n setIsLoading(true);\n fetchTranslations(locale).then(data => {\n setTranslations(data);\n setIsLoading(false);\n });\n }, [locale, appId, fetchTranslations]);\n\n // t() function with interpolation and plural support\n const t = useCallback((key: string, params?: Record<string, string | number>): string => {\n let result = translations[key] ?? key;\n\n // Handle plurals: \"singular||plural\" with count param\n if (result.includes('||') && params && 'count' in params) {\n const parts = result.split('||');\n const count = Number(params.count);\n result = count === 1 ? (parts[0] ?? result) : (parts[1] ?? result);\n }\n\n // Handle interpolation: {{variable}}\n if (params) {\n for (const [k, v] of Object.entries(params)) {\n result = result.replace(new RegExp(`\\\\{\\\\{${k}\\\\}\\\\}`, 'g'), String(v));\n }\n }\n\n return result;\n }, [translations]);\n\n // setLocale with persistence\n const setLocale = useCallback((newLocale: string) => {\n setLocaleState(newLocale);\n if (typeof window !== 'undefined') {\n localStorage.setItem(`exp_locale_${appId}`, newLocale);\n }\n }, [appId]);\n\n return { t, locale, setLocale, locales, isLoading };\n}\n"],"mappings":"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","names":["React","jsx","React","useEffect","useRef","jsx","jsxs","useRef","useEffect","useContext","useState","useCallback","useEffect","useContext","useState","useCallback","useEffect"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shellapps/experience-react",
3
- "version": "1.1.0",
3
+ "version": "1.3.0",
4
4
  "description": "React SDK for @shellapps/experience",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -43,5 +43,5 @@
43
43
  "url": "git+https://github.com/ShellTechnology/shellapps-js.git",
44
44
  "directory": "packages/experience-react"
45
45
  },
46
- "gitHead": "984bce1c38a4fe679cfe034601efe88c85ec6e8b"
46
+ "gitHead": "fcee37dbeeeeab01345cf0e359eeac2ce40edcd4"
47
47
  }