@appgram/react 0.1.0 → 0.1.3
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/{useVote-CLhkwtLT.d.mts → StatusBoard-DhKRu-An.d.mts} +125 -1
- package/dist/{useVote-CLhkwtLT.d.ts → StatusBoard-DhKRu-An.d.ts} +125 -1
- package/dist/{chunk-N6PJDQCU.mjs → chunk-NABMGLTY.mjs} +210 -6
- package/dist/chunk-NABMGLTY.mjs.map +1 -0
- package/dist/chunk-NSV6Q6QQ.js +202 -0
- package/dist/chunk-NSV6Q6QQ.js.map +1 -0
- package/dist/chunk-ONZ7RQBM.mjs +199 -0
- package/dist/chunk-ONZ7RQBM.mjs.map +1 -0
- package/dist/{chunk-75P634IK.js → chunk-UPTP7QX5.js} +213 -5
- package/dist/chunk-UPTP7QX5.js.map +1 -0
- package/dist/{chunk-AIDLOCVJ.mjs → chunk-UWIJR4ZY.mjs} +760 -15
- package/dist/chunk-UWIJR4ZY.mjs.map +1 -0
- package/dist/{chunk-3UBJGXCO.js → chunk-WZIN7KEM.js} +820 -74
- package/dist/chunk-WZIN7KEM.js.map +1 -0
- package/dist/components/index.d.mts +68 -106
- package/dist/components/index.d.ts +68 -106
- package/dist/components/index.js +29 -21
- package/dist/components/index.mjs +2 -2
- package/dist/hooks/index.d.mts +3 -572
- package/dist/hooks/index.d.ts +3 -572
- package/dist/hooks/index.js +33 -13
- package/dist/hooks/index.mjs +2 -2
- package/dist/index-DpZz_TZE.d.ts +917 -0
- package/dist/index-X95JANOa.d.mts +917 -0
- package/dist/index.d.mts +32 -5
- package/dist/index.d.ts +32 -5
- package/dist/index.js +123 -76
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +60 -41
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-3UBJGXCO.js.map +0 -1
- package/dist/chunk-75P634IK.js.map +0 -1
- package/dist/chunk-AIDLOCVJ.mjs.map +0 -1
- package/dist/chunk-KPIKYXAN.mjs +0 -47
- package/dist/chunk-KPIKYXAN.mjs.map +0 -1
- package/dist/chunk-N6PJDQCU.mjs.map +0 -1
- package/dist/chunk-ZJZ3A2S3.js +0 -49
- package/dist/chunk-ZJZ3A2S3.js.map +0 -1
package/dist/chunk-KPIKYXAN.mjs
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { useAppgramContext, getErrorMessage } from './chunk-N6PJDQCU.mjs';
|
|
2
|
-
import { useState, useCallback, useEffect } from 'react';
|
|
3
|
-
|
|
4
|
-
function useWish(options) {
|
|
5
|
-
const { client, fingerprint } = useAppgramContext();
|
|
6
|
-
const [wish, setWish] = useState(null);
|
|
7
|
-
const [isLoading, setIsLoading] = useState(!options.skip);
|
|
8
|
-
const [error, setError] = useState(null);
|
|
9
|
-
const fetchWish = useCallback(async () => {
|
|
10
|
-
if (options.skip || !options.wishId) return;
|
|
11
|
-
setIsLoading(true);
|
|
12
|
-
setError(null);
|
|
13
|
-
try {
|
|
14
|
-
const response = await client.getWish(options.wishId);
|
|
15
|
-
if (response.success && response.data) {
|
|
16
|
-
let wishData = response.data;
|
|
17
|
-
if (fingerprint) {
|
|
18
|
-
const voteResponse = await client.checkVote(options.wishId, fingerprint);
|
|
19
|
-
wishData = {
|
|
20
|
-
...wishData,
|
|
21
|
-
has_voted: voteResponse.success && voteResponse.data?.has_voted
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
setWish(wishData);
|
|
25
|
-
} else {
|
|
26
|
-
setError(getErrorMessage(response.error, "Failed to fetch wish"));
|
|
27
|
-
}
|
|
28
|
-
} catch (err) {
|
|
29
|
-
setError(getErrorMessage(err, "An error occurred"));
|
|
30
|
-
} finally {
|
|
31
|
-
setIsLoading(false);
|
|
32
|
-
}
|
|
33
|
-
}, [client, fingerprint, options.wishId, options.skip]);
|
|
34
|
-
useEffect(() => {
|
|
35
|
-
fetchWish();
|
|
36
|
-
}, [fetchWish]);
|
|
37
|
-
return {
|
|
38
|
-
wish,
|
|
39
|
-
isLoading,
|
|
40
|
-
error,
|
|
41
|
-
refetch: fetchWish
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export { useWish };
|
|
46
|
-
//# sourceMappingURL=chunk-KPIKYXAN.mjs.map
|
|
47
|
-
//# sourceMappingURL=chunk-KPIKYXAN.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hooks/useWish.ts"],"names":[],"mappings":";;;AA8CO,SAAS,QAAQ,OAAA,EAAwC;AAC9D,EAAA,MAAM,EAAE,MAAA,EAAQ,WAAA,EAAY,GAAI,iBAAA,EAAkB;AAClD,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,SAAsB,IAAI,CAAA;AAClD,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,IAAI,QAAA,CAAS,CAAC,QAAQ,IAAI,CAAA;AACxD,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAwB,IAAI,CAAA;AAEtD,EAAA,MAAM,SAAA,GAAY,YAAY,YAAY;AACxC,IAAA,IAAI,OAAA,CAAQ,IAAA,IAAQ,CAAC,OAAA,CAAQ,MAAA,EAAQ;AAErC,IAAA,YAAA,CAAa,IAAI,CAAA;AACjB,IAAA,QAAA,CAAS,IAAI,CAAA;AAEb,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,MAAA,CAAO,OAAA,CAAQ,QAAQ,MAAM,CAAA;AAEpD,MAAA,IAAI,QAAA,CAAS,OAAA,IAAW,QAAA,CAAS,IAAA,EAAM;AACrC,QAAA,IAAI,WAAW,QAAA,CAAS,IAAA;AAGxB,QAAA,IAAI,WAAA,EAAa;AACf,UAAA,MAAM,eAAe,MAAM,MAAA,CAAO,SAAA,CAAU,OAAA,CAAQ,QAAQ,WAAW,CAAA;AACvE,UAAA,QAAA,GAAW;AAAA,YACT,GAAG,QAAA;AAAA,YACH,SAAA,EAAW,YAAA,CAAa,OAAA,IAAW,YAAA,CAAa,IAAA,EAAM;AAAA,WACxD;AAAA,QACF;AAEA,QAAA,OAAA,CAAQ,QAAQ,CAAA;AAAA,MAClB,CAAA,MAAO;AACL,QAAA,QAAA,CAAS,eAAA,CAAgB,QAAA,CAAS,KAAA,EAAO,sBAAsB,CAAC,CAAA;AAAA,MAClE;AAAA,IACF,SAAS,GAAA,EAAK;AACZ,MAAA,QAAA,CAAS,eAAA,CAAgB,GAAA,EAAK,mBAAmB,CAAC,CAAA;AAAA,IACpD,CAAA,SAAE;AACA,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA,IACpB;AAAA,EACF,CAAA,EAAG,CAAC,MAAA,EAAQ,WAAA,EAAa,QAAQ,MAAA,EAAQ,OAAA,CAAQ,IAAI,CAAC,CAAA;AAEtD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,SAAA,EAAU;AAAA,EACZ,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;AAEd,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,SAAA;AAAA,IACA,KAAA;AAAA,IACA,OAAA,EAAS;AAAA,GACX;AACF","file":"chunk-KPIKYXAN.mjs","sourcesContent":["/**\n * useWish Hook\n *\n * Fetches and manages a single wish.\n */\n\nimport { useState, useEffect, useCallback } from 'react'\nimport { useAppgramContext } from '../provider/context'\nimport { getErrorMessage } from '../utils'\nimport type { Wish } from '../types'\n\nexport interface UseWishOptions {\n /**\n * The wish ID to fetch\n */\n wishId: string\n\n /**\n * Skip initial fetch\n * @default false\n */\n skip?: boolean\n}\n\nexport interface UseWishResult {\n /**\n * The wish data\n */\n wish: Wish | null\n\n /**\n * Loading state\n */\n isLoading: boolean\n\n /**\n * Error message if any\n */\n error: string | null\n\n /**\n * Manually refetch data\n */\n refetch: () => Promise<void>\n}\n\nexport function useWish(options: UseWishOptions): UseWishResult {\n const { client, fingerprint } = useAppgramContext()\n const [wish, setWish] = useState<Wish | null>(null)\n const [isLoading, setIsLoading] = useState(!options.skip)\n const [error, setError] = useState<string | null>(null)\n\n const fetchWish = useCallback(async () => {\n if (options.skip || !options.wishId) return\n\n setIsLoading(true)\n setError(null)\n\n try {\n const response = await client.getWish(options.wishId)\n\n if (response.success && response.data) {\n let wishData = response.data\n\n // Check vote status if fingerprint available\n if (fingerprint) {\n const voteResponse = await client.checkVote(options.wishId, fingerprint)\n wishData = {\n ...wishData,\n has_voted: voteResponse.success && voteResponse.data?.has_voted,\n }\n }\n\n setWish(wishData)\n } else {\n setError(getErrorMessage(response.error, 'Failed to fetch wish'))\n }\n } catch (err) {\n setError(getErrorMessage(err, 'An error occurred'))\n } finally {\n setIsLoading(false)\n }\n }, [client, fingerprint, options.wishId, options.skip])\n\n useEffect(() => {\n fetchWish()\n }, [fetchWish])\n\n return {\n wish,\n isLoading,\n error,\n refetch: fetchWish,\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/provider/context.ts","../src/utils/fingerprint.ts","../src/utils/cn.ts","../src/utils/index.ts","../src/hooks/useWishes.ts","../src/hooks/useVote.ts","../src/hooks/useComments.ts","../src/hooks/useRoadmap.ts","../src/hooks/useReleases.ts","../src/hooks/useHelpCenter.ts","../src/hooks/useSupport.ts"],"names":["useState","useCallback","useEffect"],"mappings":"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","file":"chunk-N6PJDQCU.mjs","sourcesContent":["/**\n * Appgram Context\n */\n\nimport { createContext, useContext } from 'react'\nimport type { AppgramClient } from '../client/AppgramClient'\nimport type { AppgramTheme } from '../types'\n\nexport interface AppgramConfig {\n /**\n * Your Appgram project ID\n */\n projectId: string\n\n /**\n * Organization slug (used for public URLs)\n */\n orgSlug?: string\n\n /**\n * Project slug (used for public URLs)\n */\n projectSlug?: string\n\n /**\n * Optional API URL override (defaults to https://api.appgram.dev)\n */\n apiUrl?: string\n\n /**\n * Enable browser fingerprinting for anonymous voting\n * @default true\n */\n enableFingerprinting?: boolean\n\n /**\n * Theme customization\n */\n theme?: AppgramTheme\n}\n\nexport interface AppgramContextValue {\n /**\n * The Appgram configuration\n */\n config: Required<Pick<AppgramConfig, 'projectId'>> & AppgramConfig\n\n /**\n * The API client instance\n */\n client: AppgramClient\n\n /**\n * Browser fingerprint for anonymous voting\n */\n fingerprint: string | null\n\n /**\n * Theme values\n */\n theme: AppgramTheme\n}\n\nexport const AppgramContext = createContext<AppgramContextValue | null>(null)\n\n/**\n * Hook to access the Appgram context\n * @throws Error if used outside of AppgramProvider\n */\nexport function useAppgramContext(): AppgramContextValue {\n const context = useContext(AppgramContext)\n\n if (!context) {\n throw new Error(\n 'useAppgramContext must be used within an AppgramProvider. ' +\n 'Make sure you have wrapped your app with <AppgramProvider>.'\n )\n }\n\n return context\n}\n","/**\n * Browser Fingerprint Utility\n *\n * Generates a unique fingerprint for anonymous voting.\n * Uses a combination of browser/device characteristics.\n */\n\nconst STORAGE_KEY = 'appgram_fingerprint'\n\n/**\n * Hash a string using a simple algorithm\n */\nfunction simpleHash(str: string): string {\n let hash = 0\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i)\n hash = ((hash << 5) - hash) + char\n hash = hash & hash // Convert to 32bit integer\n }\n return Math.abs(hash).toString(36)\n}\n\n/**\n * Get browser characteristics for fingerprinting\n */\nfunction getBrowserCharacteristics(): string {\n if (typeof window === 'undefined') {\n return 'server-side'\n }\n\n const characteristics = [\n navigator.userAgent,\n navigator.language,\n screen.colorDepth,\n screen.width,\n screen.height,\n new Date().getTimezoneOffset(),\n navigator.hardwareConcurrency || 0,\n 'deviceMemory' in navigator ? (navigator as any).deviceMemory : 0,\n ]\n\n return characteristics.join('|')\n}\n\n/**\n * Generate a fingerprint ID\n */\nfunction generateFingerprint(): string {\n const characteristics = getBrowserCharacteristics()\n const timestamp = Date.now().toString(36)\n const randomBytes = new Uint8Array(6)\n crypto.getRandomValues(randomBytes)\n const random = Array.from(randomBytes, b => b.toString(36)).join('').substring(0, 10)\n return `${simpleHash(characteristics)}-${timestamp}-${random}`\n}\n\n/**\n * Get or create a fingerprint for the current browser/device\n * @returns The fingerprint string\n */\nexport function getFingerprint(): string {\n if (typeof window === 'undefined') {\n return 'server-side-fingerprint'\n }\n\n // Try to get from localStorage\n let fingerprint = localStorage.getItem(STORAGE_KEY)\n\n if (!fingerprint) {\n // Generate new fingerprint\n fingerprint = generateFingerprint()\n try {\n localStorage.setItem(STORAGE_KEY, fingerprint)\n } catch {\n // localStorage might be disabled\n }\n }\n\n return fingerprint\n}\n\n/**\n * Reset the stored fingerprint (for testing purposes)\n */\nexport function resetFingerprint(): void {\n if (typeof window === 'undefined') return\n try {\n localStorage.removeItem(STORAGE_KEY)\n } catch {\n // localStorage might be disabled\n }\n}\n","/**\n * Utility for merging Tailwind CSS classes\n */\n\nimport { clsx, type ClassValue } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\n/**\n * Merges Tailwind CSS classes with proper precedence handling\n * @param inputs - Class values to merge\n * @returns Merged class string\n */\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs))\n}\n","/**\n * Utility Exports\n */\n\nexport { cn } from './cn'\nexport { getFingerprint, resetFingerprint } from './fingerprint'\n\n/**\n * Safely extract error message from API response error\n */\nexport function getErrorMessage(error: unknown, fallback = 'An error occurred'): string {\n if (!error) return fallback\n if (typeof error === 'string') return error\n if (typeof error === 'object' && error !== null) {\n if ('message' in error && typeof (error as any).message === 'string') {\n return (error as any).message\n }\n }\n return fallback\n}\n","/**\n * useWishes Hook\n *\n * Fetches and manages a list of wishes with filtering and pagination.\n * Provides headless access to the wishes API for custom UI implementations.\n *\n * @example\n * ```tsx\n * import { useWishes } from '@appgram/react'\n *\n * function WishList() {\n * const { wishes, isLoading, error, setFilters, refetch } = useWishes({\n * filters: { sort_by: 'votes', status: 'pending' },\n * refreshInterval: 30000,\n * })\n *\n * if (isLoading) return <Spinner />\n * if (error) return <Error message={error} onRetry={refetch} />\n *\n * return (\n * <ul>\n * {wishes.map(wish => (\n * <li key={wish.id}>{wish.title}</li>\n * ))}\n * </ul>\n * )\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With search and pagination\n * function SearchableWishes() {\n * const { wishes, isLoading, setFilters, page, totalPages, setPage } = useWishes()\n *\n * const handleSearch = (query: string) => {\n * setFilters({ search: query, page: 1 })\n * }\n *\n * return (\n * <>\n * <Search onSearch={handleSearch} />\n * <WishGrid wishes={wishes} loading={isLoading} />\n * <Pagination\n * current={page}\n * total={totalPages}\n * onChange={setPage}\n * />\n * </>\n * )\n * }\n * ```\n */\n\nimport { useState, useEffect, useCallback, useRef } from 'react'\nimport { useAppgramContext } from '../provider/context'\nimport { getErrorMessage } from '../utils'\nimport type { Wish, WishFilters } from '../types'\n\nexport interface UseWishesOptions {\n /**\n * Initial filters\n */\n filters?: WishFilters\n\n /**\n * Auto-refresh interval in milliseconds (0 to disable)\n * @default 0\n */\n refreshInterval?: number\n\n /**\n * Skip initial fetch\n * @default false\n */\n skip?: boolean\n}\n\nexport interface UseWishesResult {\n /**\n * List of wishes\n */\n wishes: Wish[]\n\n /**\n * Loading state\n */\n isLoading: boolean\n\n /**\n * Error message if any\n */\n error: string | null\n\n /**\n * Total number of wishes\n */\n total: number\n\n /**\n * Current page\n */\n page: number\n\n /**\n * Total pages\n */\n totalPages: number\n\n /**\n * Update filters\n */\n setFilters: (filters: WishFilters) => void\n\n /**\n * Go to a specific page\n */\n setPage: (page: number) => void\n\n /**\n * Manually refetch data\n */\n refetch: () => Promise<void>\n}\n\nexport function useWishes(options: UseWishesOptions = {}): UseWishesResult {\n const { client, fingerprint } = useAppgramContext()\n const [wishes, setWishes] = useState<Wish[]>([])\n const [isLoading, setIsLoading] = useState(!options.skip)\n const [error, setError] = useState<string | null>(null)\n const [total, setTotal] = useState(0)\n const [page, setPage] = useState(options.filters?.page || 1)\n const [totalPages, setTotalPages] = useState(0)\n const [filters, setFilters] = useState<WishFilters>(options.filters || {})\n\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null)\n\n const fetchWishes = useCallback(async () => {\n if (options.skip) return\n\n setIsLoading(true)\n setError(null)\n\n try {\n const response = await client.getPublicWishes({\n ...filters,\n page,\n fingerprint: fingerprint ?? undefined,\n })\n\n if (response.success && response.data) {\n // Server returns has_voted for each wish when fingerprint is provided\n const wishData = response.data.data || []\n setWishes(wishData)\n setTotal(response.data.total)\n setTotalPages(response.data.total_pages)\n } else {\n setError(getErrorMessage(response.error, 'Failed to fetch wishes'))\n }\n } catch (err) {\n setError(getErrorMessage(err, 'An error occurred'))\n } finally {\n setIsLoading(false)\n }\n }, [client, fingerprint, filters, page, options.skip])\n\n // Initial fetch and filter/page changes\n useEffect(() => {\n fetchWishes()\n }, [fetchWishes])\n\n // Auto-refresh interval\n useEffect(() => {\n if (options.refreshInterval && options.refreshInterval > 0) {\n intervalRef.current = setInterval(fetchWishes, options.refreshInterval)\n }\n\n return () => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current)\n }\n }\n }, [options.refreshInterval, fetchWishes])\n\n const handleSetFilters = useCallback((newFilters: WishFilters) => {\n setFilters(newFilters)\n setPage(1) // Reset to first page when filters change\n }, [])\n\n return {\n wishes,\n isLoading,\n error,\n total,\n page,\n totalPages,\n setFilters: handleSetFilters,\n setPage,\n refetch: fetchWishes,\n }\n}\n","/**\n * useVote Hook\n *\n * Manages voting state and actions for a wish.\n * Provides optimistic updates for instant UI feedback.\n *\n * @example\n * ```tsx\n * import { useVote } from '@appgram/react'\n *\n * function VoteButton({ wishId, initialCount, initialHasVoted }) {\n * const { hasVoted, voteCount, toggle, isLoading } = useVote({\n * wishId,\n * initialVoteCount: initialCount,\n * initialHasVoted,\n * onVoteChange: (voted, count) => {\n * analytics.track('vote', { wishId, voted })\n * }\n * })\n *\n * return (\n * <button\n * onClick={toggle}\n * disabled={isLoading}\n * className={hasVoted ? 'voted' : ''}\n * >\n * {hasVoted ? '✓' : '▲'} {voteCount}\n * </button>\n * )\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Lazy vote check to avoid rate limiting\n * const { hasVoted, voteCount, toggle } = useVote({\n * wishId: wish.id,\n * initialVoteCount: wish.vote_count,\n * skipAutoCheck: true, // Check on first click instead\n * })\n * ```\n */\n\nimport { useState, useEffect, useCallback } from 'react'\nimport { useAppgramContext } from '../provider/context'\nimport { getErrorMessage } from '../utils'\n\nexport interface UseVoteOptions {\n /**\n * The wish ID to vote on\n */\n wishId: string\n\n /**\n * Initial vote count (optional, useful when you already have the wish data)\n */\n initialVoteCount?: number\n\n /**\n * Initial hasVoted state (optional)\n */\n initialHasVoted?: boolean\n\n /**\n * Voter email (optional, for identified voting)\n */\n voterEmail?: string\n\n /**\n * Callback when vote state changes\n */\n onVoteChange?: (hasVoted: boolean, voteCount: number) => void\n\n /**\n * Skip automatic vote check on mount to avoid rate limiting\n * When true, vote status will be checked lazily on first interaction\n * @default true\n */\n skipAutoCheck?: boolean\n}\n\nexport interface UseVoteResult {\n /**\n * Whether the current user has voted\n */\n hasVoted: boolean\n\n /**\n * Current vote count\n */\n voteCount: number\n\n /**\n * Loading state for vote operations\n */\n isLoading: boolean\n\n /**\n * Loading state for initial vote check\n */\n isChecking: boolean\n\n /**\n * Error message if any\n */\n error: string | null\n\n /**\n * Toggle vote (vote if not voted, unvote if voted)\n */\n toggle: () => Promise<void>\n\n /**\n * Cast a vote\n */\n vote: () => Promise<void>\n\n /**\n * Remove a vote\n */\n unvote: () => Promise<void>\n}\n\nexport function useVote(options: UseVoteOptions): UseVoteResult {\n const { client, fingerprint } = useAppgramContext()\n const [hasVoted, setHasVoted] = useState(options.initialHasVoted || false)\n const [voteCount, setVoteCount] = useState(options.initialVoteCount || 0)\n const [voteId, setVoteId] = useState<string | null>(null)\n const [isLoading, setIsLoading] = useState(false)\n const [isChecking, setIsChecking] = useState(false)\n const [hasChecked, setHasChecked] = useState(false)\n const [error, setError] = useState<string | null>(null)\n\n // Skip auto check by default to avoid rate limiting when many VoteButtons render\n const skipAutoCheck = options.skipAutoCheck !== false\n\n // Check vote status - called on mount (if not skipped) or lazily before voting\n const checkVoteStatus = useCallback(async () => {\n if (!fingerprint || !options.wishId || hasChecked) {\n return\n }\n\n setIsChecking(true)\n try {\n const response = await client.checkVote(options.wishId, fingerprint)\n if (response.success && response.data) {\n setHasVoted(response.data.has_voted)\n if (response.data.vote_id) {\n setVoteId(response.data.vote_id)\n }\n }\n setHasChecked(true)\n } catch {\n // Silent fail for vote check\n setHasChecked(true)\n } finally {\n setIsChecking(false)\n }\n }, [client, fingerprint, options.wishId, hasChecked])\n\n // Only auto-check on mount if skipAutoCheck is false\n useEffect(() => {\n if (!skipAutoCheck) {\n checkVoteStatus()\n }\n }, [skipAutoCheck, checkVoteStatus])\n\n // Update state if initial values change\n useEffect(() => {\n if (options.initialVoteCount !== undefined) {\n setVoteCount(options.initialVoteCount)\n }\n }, [options.initialVoteCount])\n\n useEffect(() => {\n if (options.initialHasVoted !== undefined) {\n setHasVoted(options.initialHasVoted)\n }\n }, [options.initialHasVoted])\n\n const vote = useCallback(async () => {\n if (!fingerprint || isLoading) return\n\n // If we haven't checked vote status yet, check first\n if (!hasChecked) {\n setIsLoading(true)\n try {\n const checkResponse = await client.checkVote(options.wishId, fingerprint)\n if (checkResponse.success && checkResponse.data) {\n setHasVoted(checkResponse.data.has_voted)\n if (checkResponse.data.vote_id) {\n setVoteId(checkResponse.data.vote_id)\n }\n setHasChecked(true)\n // If already voted, don't vote again\n if (checkResponse.data.has_voted) {\n setIsLoading(false)\n return\n }\n }\n } catch {\n // Continue with vote attempt if check fails\n setHasChecked(true)\n }\n } else if (hasVoted) {\n // Already voted and we know it\n return\n }\n\n setIsLoading(true)\n setError(null)\n\n try {\n const response = await client.createVote(\n options.wishId,\n fingerprint,\n options.voterEmail\n )\n\n if (response.success && response.data) {\n setHasVoted(true)\n setVoteId(response.data.id)\n setVoteCount((prev) => prev + 1)\n options.onVoteChange?.(true, voteCount + 1)\n } else {\n setError(getErrorMessage(response.error, 'Failed to vote'))\n }\n } catch (err) {\n setError(getErrorMessage(err, 'Failed to vote'))\n } finally {\n setIsLoading(false)\n }\n }, [client, fingerprint, hasVoted, hasChecked, isLoading, options, voteCount])\n\n const unvote = useCallback(async () => {\n if (!voteId || !hasVoted || isLoading) return\n\n setIsLoading(true)\n setError(null)\n\n try {\n const response = await client.deleteVote(voteId)\n\n if (response.success) {\n setHasVoted(false)\n setVoteId(null)\n setVoteCount((prev) => Math.max(0, prev - 1))\n options.onVoteChange?.(false, Math.max(0, voteCount - 1))\n } else {\n setError(getErrorMessage(response.error, 'Failed to remove vote'))\n }\n } catch (err) {\n setError(getErrorMessage(err, 'Failed to remove vote'))\n } finally {\n setIsLoading(false)\n }\n }, [client, hasVoted, isLoading, options, voteCount, voteId])\n\n const toggle = useCallback(async () => {\n if (!fingerprint || isLoading) return\n\n // If we haven't checked vote status yet, check first to know which action to take\n if (!hasChecked) {\n setIsLoading(true)\n try {\n const checkResponse = await client.checkVote(options.wishId, fingerprint)\n if (checkResponse.success && checkResponse.data) {\n const alreadyVoted = checkResponse.data.has_voted\n setHasVoted(alreadyVoted)\n if (checkResponse.data.vote_id) {\n setVoteId(checkResponse.data.vote_id)\n }\n setHasChecked(true)\n setIsLoading(false)\n\n // Now perform the appropriate action\n if (alreadyVoted) {\n // User wants to unvote\n if (checkResponse.data.vote_id) {\n await unvote()\n }\n } else {\n // User wants to vote\n await vote()\n }\n return\n }\n } catch {\n // If check fails, default to voting\n setHasChecked(true)\n setIsLoading(false)\n }\n }\n\n // Normal toggle when we know the status\n if (hasVoted) {\n await unvote()\n } else {\n await vote()\n }\n }, [client, fingerprint, hasVoted, hasChecked, isLoading, options.wishId, unvote, vote])\n\n return {\n hasVoted,\n voteCount,\n isLoading,\n isChecking,\n error,\n toggle,\n vote,\n unvote,\n }\n}\n","/**\n * useComments Hook\n *\n * Fetches and manages comments for a wish.\n */\n\nimport { useState, useEffect, useCallback } from 'react'\nimport { useAppgramContext } from '../provider/context'\nimport { getErrorMessage } from '../utils'\nimport type { Comment, CommentCreateInput } from '../types'\n\nexport interface UseCommentsOptions {\n /**\n * The wish ID to fetch comments for\n */\n wishId: string\n\n /**\n * Number of comments per page\n * @default 20\n */\n perPage?: number\n\n /**\n * Skip initial fetch\n * @default false\n */\n skip?: boolean\n}\n\nexport interface UseCommentsResult {\n /**\n * List of comments\n */\n comments: Comment[]\n\n /**\n * Loading state\n */\n isLoading: boolean\n\n /**\n * Loading state for creating a comment\n */\n isCreating: boolean\n\n /**\n * Error message if any\n */\n error: string | null\n\n /**\n * Total number of comments\n */\n total: number\n\n /**\n * Current page\n */\n page: number\n\n /**\n * Total pages\n */\n totalPages: number\n\n /**\n * Go to next page\n */\n nextPage: () => void\n\n /**\n * Go to previous page\n */\n prevPage: () => void\n\n /**\n * Go to specific page\n */\n setPage: (page: number) => void\n\n /**\n * Create a new comment\n */\n createComment: (data: Omit<CommentCreateInput, 'wish_id'>) => Promise<Comment | null>\n\n /**\n * Manually refetch data\n */\n refetch: () => Promise<void>\n}\n\nexport function useComments(options: UseCommentsOptions): UseCommentsResult {\n const { client } = useAppgramContext()\n const [comments, setComments] = useState<Comment[]>([])\n const [isLoading, setIsLoading] = useState(!options.skip)\n const [isCreating, setIsCreating] = useState(false)\n const [error, setError] = useState<string | null>(null)\n const [total, setTotal] = useState(0)\n const [page, setPage] = useState(1)\n const [totalPages, setTotalPages] = useState(0)\n\n const perPage = options.perPage || 20\n\n const fetchComments = useCallback(async () => {\n if (options.skip || !options.wishId) return\n\n setIsLoading(true)\n setError(null)\n\n try {\n const response = await client.getComments(options.wishId, {\n page,\n per_page: perPage,\n })\n\n if (response.success && response.data) {\n setComments(response.data.data || [])\n setTotal(response.data.total)\n setTotalPages(response.data.total_pages)\n } else {\n setError(getErrorMessage(response.error, 'Failed to fetch comments'))\n }\n } catch (err) {\n setError(getErrorMessage(err, 'An error occurred'))\n } finally {\n setIsLoading(false)\n }\n }, [client, options.wishId, options.skip, page, perPage])\n\n useEffect(() => {\n fetchComments()\n }, [fetchComments])\n\n const createComment = useCallback(\n async (data: Omit<CommentCreateInput, 'wish_id'>): Promise<Comment | null> => {\n setIsCreating(true)\n setError(null)\n\n try {\n const response = await client.createComment({\n ...data,\n wish_id: options.wishId,\n })\n\n if (response.success && response.data) {\n // Add new comment to the list\n setComments((prev) => [response.data!, ...prev])\n setTotal((prev) => prev + 1)\n return response.data\n } else {\n setError(getErrorMessage(response.error, 'Failed to create comment'))\n return null\n }\n } catch (err) {\n setError(getErrorMessage(err, 'An error occurred'))\n return null\n } finally {\n setIsCreating(false)\n }\n },\n [client, options.wishId]\n )\n\n const nextPage = useCallback(() => {\n if (page < totalPages) {\n setPage((prev) => prev + 1)\n }\n }, [page, totalPages])\n\n const prevPage = useCallback(() => {\n if (page > 1) {\n setPage((prev) => prev - 1)\n }\n }, [page])\n\n return {\n comments,\n isLoading,\n isCreating,\n error,\n total,\n page,\n totalPages,\n nextPage,\n prevPage,\n setPage,\n createComment,\n refetch: fetchComments,\n }\n}\n","/**\n * useRoadmap Hook\n *\n * Fetches and manages roadmap data for custom UI implementations.\n *\n * @example\n * ```tsx\n * import { useRoadmap } from '@appgram/react'\n *\n * function CustomRoadmap() {\n * const { roadmap, isLoading, error, refetch } = useRoadmap({\n * refreshInterval: 60000,\n * })\n *\n * if (isLoading) return <Skeleton />\n * if (error) return <Error message={error} />\n *\n * return (\n * <div className=\"roadmap-columns\">\n * {roadmap?.columns.map(col => (\n * <Column key={col.id} title={col.title} items={col.items} />\n * ))}\n * </div>\n * )\n * }\n * ```\n */\n\nimport { useState, useEffect, useCallback } from 'react'\nimport { useAppgramContext } from '../provider/context'\nimport { getErrorMessage } from '../utils'\nimport type { Roadmap, RoadmapColumn } from '../types'\n\nexport interface UseRoadmapOptions {\n /**\n * Auto-refresh interval in milliseconds (0 to disable)\n * @default 0\n */\n refreshInterval?: number\n\n /**\n * Skip initial fetch\n * @default false\n */\n skip?: boolean\n}\n\nexport interface UseRoadmapResult {\n /**\n * Roadmap data\n */\n roadmap: Roadmap | null\n\n /**\n * Roadmap columns with items\n */\n columns: RoadmapColumn[]\n\n /**\n * Total number of items\n */\n totalItems: number\n\n /**\n * Loading state\n */\n isLoading: boolean\n\n /**\n * Error message if any\n */\n error: string | null\n\n /**\n * Manually refetch data\n */\n refetch: () => Promise<void>\n}\n\nexport function useRoadmap(options: UseRoadmapOptions = {}): UseRoadmapResult {\n const { client } = useAppgramContext()\n const [roadmap, setRoadmap] = useState<Roadmap | null>(null)\n const [columns, setColumns] = useState<RoadmapColumn[]>([])\n const [totalItems, setTotalItems] = useState(0)\n const [isLoading, setIsLoading] = useState(!options.skip)\n const [error, setError] = useState<string | null>(null)\n\n const fetchRoadmap = useCallback(async () => {\n if (options.skip) return\n\n setIsLoading(true)\n setError(null)\n\n try {\n const response = await client.getRoadmapData()\n\n if (response.success && response.data) {\n setRoadmap(response.data.roadmap)\n // Columns can be at top level or nested inside roadmap\n const cols = response.data.columns || response.data.roadmap?.columns || []\n setColumns(cols)\n // Calculate total items from columns\n const itemCount = response.data.total_items || cols.reduce((sum, col) => sum + (col.items?.length || 0), 0)\n setTotalItems(itemCount)\n } else {\n setError(getErrorMessage(response.error, 'Failed to fetch roadmap'))\n }\n } catch (err) {\n setError(getErrorMessage(err, 'An error occurred'))\n } finally {\n setIsLoading(false)\n }\n }, [client, options.skip])\n\n useEffect(() => {\n fetchRoadmap()\n }, [fetchRoadmap])\n\n // Auto-refresh\n useEffect(() => {\n if (!options.refreshInterval || options.refreshInterval <= 0) return\n\n const interval = setInterval(fetchRoadmap, options.refreshInterval)\n return () => clearInterval(interval)\n }, [options.refreshInterval, fetchRoadmap])\n\n return {\n roadmap,\n columns,\n totalItems,\n isLoading,\n error,\n refetch: fetchRoadmap,\n }\n}\n","/**\n * useReleases Hook\n *\n * Fetches and manages releases/changelog data for custom UI implementations.\n *\n * @example\n * ```tsx\n * import { useReleases } from '@appgram/react'\n *\n * function ChangelogList() {\n * const { releases, isLoading, error, refetch } = useReleases({ limit: 10 })\n *\n * if (isLoading) return <Spinner />\n * if (error) return <Alert>{error}</Alert>\n *\n * return (\n * <ul className=\"changelog\">\n * {releases.map(release => (\n * <li key={release.id}>\n * <h3>{release.title}</h3>\n * <time>{formatDate(release.published_at)}</time>\n * <div dangerouslySetInnerHTML={{ __html: release.content }} />\n * </li>\n * ))}\n * </ul>\n * )\n * }\n * ```\n */\n\nimport { useState, useEffect, useCallback } from 'react'\nimport { useAppgramContext } from '../provider/context'\nimport { getErrorMessage } from '../utils'\nimport type { Release } from '../types'\n\nexport interface UseReleasesOptions {\n /**\n * Maximum number of releases to fetch\n * @default 50\n */\n limit?: number\n\n /**\n * Skip initial fetch\n * @default false\n */\n skip?: boolean\n}\n\nexport interface UseReleasesResult {\n /**\n * List of releases\n */\n releases: Release[]\n\n /**\n * Loading state\n */\n isLoading: boolean\n\n /**\n * Error message if any\n */\n error: string | null\n\n /**\n * Manually refetch data\n */\n refetch: () => Promise<void>\n}\n\nexport function useReleases(options: UseReleasesOptions = {}): UseReleasesResult {\n const { client } = useAppgramContext()\n const [releases, setReleases] = useState<Release[]>([])\n const [isLoading, setIsLoading] = useState(!options.skip)\n const [error, setError] = useState<string | null>(null)\n\n const fetchReleases = useCallback(async () => {\n if (options.skip) return\n\n setIsLoading(true)\n setError(null)\n\n try {\n const response = await client.getReleases({\n limit: options.limit || 50,\n })\n\n if (response.success && response.data) {\n setReleases(response.data)\n } else {\n setError(getErrorMessage(response.error, 'Failed to fetch releases'))\n }\n } catch (err) {\n setError(getErrorMessage(err, 'An error occurred'))\n } finally {\n setIsLoading(false)\n }\n }, [client, options.skip, options.limit])\n\n useEffect(() => {\n fetchReleases()\n }, [fetchReleases])\n\n return {\n releases,\n isLoading,\n error,\n refetch: fetchReleases,\n }\n}\n\n/**\n * useRelease Hook\n *\n * Fetches a single release by slug.\n */\nexport interface UseReleaseOptions {\n /**\n * The release slug to fetch\n */\n releaseSlug: string\n\n /**\n * Skip initial fetch\n * @default false\n */\n skip?: boolean\n}\n\nexport interface UseReleaseResult {\n /**\n * The release data\n */\n release: Release | null\n\n /**\n * Loading state\n */\n isLoading: boolean\n\n /**\n * Error message if any\n */\n error: string | null\n\n /**\n * Manually refetch data\n */\n refetch: () => Promise<void>\n}\n\nexport function useRelease(options: UseReleaseOptions): UseReleaseResult {\n const { client } = useAppgramContext()\n const [release, setRelease] = useState<Release | null>(null)\n const [isLoading, setIsLoading] = useState(!options.skip)\n const [error, setError] = useState<string | null>(null)\n\n const fetchRelease = useCallback(async () => {\n if (options.skip || !options.releaseSlug) return\n\n setIsLoading(true)\n setError(null)\n\n try {\n const response = await client.getRelease(options.releaseSlug)\n\n if (response.success && response.data) {\n setRelease(response.data)\n } else {\n setError(getErrorMessage(response.error, 'Failed to fetch release'))\n }\n } catch (err) {\n setError(getErrorMessage(err, 'An error occurred'))\n } finally {\n setIsLoading(false)\n }\n }, [client, options.skip, options.releaseSlug])\n\n useEffect(() => {\n fetchRelease()\n }, [fetchRelease])\n\n return {\n release,\n isLoading,\n error,\n refetch: fetchRelease,\n }\n}\n","/**\n * useHelpCenter Hook\n *\n * Fetches and manages help center data.\n */\n\nimport { useState, useEffect, useCallback } from 'react'\nimport { useAppgramContext } from '../provider/context'\nimport { getErrorMessage } from '../utils'\nimport type { HelpCollection, HelpFlow, HelpArticle } from '../types'\n\nexport interface UseHelpCenterOptions {\n /**\n * Skip initial fetch\n * @default false\n */\n skip?: boolean\n}\n\nexport interface UseHelpCenterResult {\n /**\n * Help collection\n */\n collection: HelpCollection | null\n\n /**\n * Help flows\n */\n flows: HelpFlow[]\n\n /**\n * Loading state\n */\n isLoading: boolean\n\n /**\n * Error message if any\n */\n error: string | null\n\n /**\n * Manually refetch data\n */\n refetch: () => Promise<void>\n}\n\nexport function useHelpCenter(options: UseHelpCenterOptions = {}): UseHelpCenterResult {\n const { client } = useAppgramContext()\n const [collection, setCollection] = useState<HelpCollection | null>(null)\n const [flows, setFlows] = useState<HelpFlow[]>([])\n const [isLoading, setIsLoading] = useState(!options.skip)\n const [error, setError] = useState<string | null>(null)\n\n const fetchHelpCenter = useCallback(async () => {\n if (options.skip) return\n\n setIsLoading(true)\n setError(null)\n\n try {\n const response = await client.getHelpCollection()\n\n if (response.success && response.data) {\n setCollection(response.data.collection)\n setFlows(response.data.flows || [])\n } else {\n setError(getErrorMessage(response.error, 'Failed to fetch help center'))\n }\n } catch (err) {\n setError(getErrorMessage(err, 'An error occurred'))\n } finally {\n setIsLoading(false)\n }\n }, [client, options.skip])\n\n useEffect(() => {\n fetchHelpCenter()\n }, [fetchHelpCenter])\n\n return {\n collection,\n flows,\n isLoading,\n error,\n refetch: fetchHelpCenter,\n }\n}\n\n/**\n * useHelpFlow Hook\n *\n * Fetches a single help flow by slug.\n */\nexport interface UseHelpFlowOptions {\n /**\n * The flow slug to fetch\n */\n flowSlug: string\n\n /**\n * Skip initial fetch\n * @default false\n */\n skip?: boolean\n}\n\nexport interface UseHelpFlowResult {\n /**\n * The flow data\n */\n flow: HelpFlow | null\n\n /**\n * Loading state\n */\n isLoading: boolean\n\n /**\n * Error message if any\n */\n error: string | null\n\n /**\n * Manually refetch data\n */\n refetch: () => Promise<void>\n}\n\nexport function useHelpFlow(options: UseHelpFlowOptions): UseHelpFlowResult {\n const { client } = useAppgramContext()\n const [flow, setFlow] = useState<HelpFlow | null>(null)\n const [isLoading, setIsLoading] = useState(!options.skip)\n const [error, setError] = useState<string | null>(null)\n\n const fetchFlow = useCallback(async () => {\n if (options.skip || !options.flowSlug) return\n\n setIsLoading(true)\n setError(null)\n\n try {\n const response = await client.getHelpFlow(options.flowSlug)\n\n if (response.success && response.data) {\n setFlow(response.data)\n } else {\n setError(getErrorMessage(response.error, 'Failed to fetch flow'))\n }\n } catch (err) {\n setError(getErrorMessage(err, 'An error occurred'))\n } finally {\n setIsLoading(false)\n }\n }, [client, options.skip, options.flowSlug])\n\n useEffect(() => {\n fetchFlow()\n }, [fetchFlow])\n\n return {\n flow,\n isLoading,\n error,\n refetch: fetchFlow,\n }\n}\n\n/**\n * useHelpArticle Hook\n *\n * Fetches a single help article by slug.\n */\nexport interface UseHelpArticleOptions {\n /**\n * The article slug to fetch\n */\n articleSlug: string\n\n /**\n * The flow ID the article belongs to\n */\n flowId: string\n\n /**\n * Skip initial fetch\n * @default false\n */\n skip?: boolean\n}\n\nexport interface UseHelpArticleResult {\n /**\n * The article data\n */\n article: HelpArticle | null\n\n /**\n * Loading state\n */\n isLoading: boolean\n\n /**\n * Error message if any\n */\n error: string | null\n\n /**\n * Manually refetch data\n */\n refetch: () => Promise<void>\n}\n\nexport function useHelpArticle(options: UseHelpArticleOptions): UseHelpArticleResult {\n const { client } = useAppgramContext()\n const [article, setArticle] = useState<HelpArticle | null>(null)\n const [isLoading, setIsLoading] = useState(!options.skip)\n const [error, setError] = useState<string | null>(null)\n\n const fetchArticle = useCallback(async () => {\n if (options.skip || !options.articleSlug || !options.flowId) return\n\n setIsLoading(true)\n setError(null)\n\n try {\n const response = await client.getHelpArticle(options.articleSlug, options.flowId)\n\n if (response.success && response.data) {\n setArticle(response.data)\n } else {\n setError(getErrorMessage(response.error, 'Failed to fetch article'))\n }\n } catch (err) {\n setError(getErrorMessage(err, 'An error occurred'))\n } finally {\n setIsLoading(false)\n }\n }, [client, options.skip, options.articleSlug, options.flowId])\n\n useEffect(() => {\n fetchArticle()\n }, [fetchArticle])\n\n return {\n article,\n isLoading,\n error,\n refetch: fetchArticle,\n }\n}\n","/**\n * useSupport Hook\n *\n * Manages support ticket submissions and access.\n */\n\nimport { useState, useCallback } from 'react'\nimport { useAppgramContext } from '../provider/context'\nimport { getErrorMessage } from '../utils'\nimport type { SupportRequest, SupportRequestInput } from '../types'\n\nexport interface UseSupportOptions {\n /**\n * Callback when a ticket is successfully submitted\n */\n onSubmitSuccess?: (ticket: SupportRequest) => void\n\n /**\n * Callback when a submission fails\n */\n onSubmitError?: (error: string) => void\n}\n\nexport interface UseSupportResult {\n /**\n * Loading state for ticket submission\n */\n isSubmitting: boolean\n\n /**\n * Loading state for magic link request\n */\n isSendingMagicLink: boolean\n\n /**\n * Loading state for token verification\n */\n isVerifying: boolean\n\n /**\n * Error message if any\n */\n error: string | null\n\n /**\n * Success message after submitting\n */\n successMessage: string | null\n\n /**\n * Submit a new support ticket\n */\n submitTicket: (data: SupportRequestInput) => Promise<SupportRequest | null>\n\n /**\n * Request a magic link to access tickets\n */\n requestMagicLink: (email: string) => Promise<boolean>\n\n /**\n * Verify a magic link token\n */\n verifyToken: (token: string) => Promise<{\n tickets: SupportRequest[]\n userEmail: string\n } | null>\n\n /**\n * Get a specific ticket by ID with token\n */\n getTicket: (ticketId: string, token: string) => Promise<SupportRequest | null>\n\n /**\n * Add a message to a ticket\n */\n addMessage: (\n ticketId: string,\n token: string,\n content: string\n ) => Promise<{ id: string; content: string; created_at: string } | null>\n\n /**\n * Clear any error or success messages\n */\n clearMessages: () => void\n}\n\nexport function useSupport(options: UseSupportOptions = {}): UseSupportResult {\n const { client } = useAppgramContext()\n const [isSubmitting, setIsSubmitting] = useState(false)\n const [isSendingMagicLink, setIsSendingMagicLink] = useState(false)\n const [isVerifying, setIsVerifying] = useState(false)\n const [error, setError] = useState<string | null>(null)\n const [successMessage, setSuccessMessage] = useState<string | null>(null)\n\n const clearMessages = useCallback(() => {\n setError(null)\n setSuccessMessage(null)\n }, [])\n\n const submitTicket = useCallback(\n async (data: SupportRequestInput): Promise<SupportRequest | null> => {\n setIsSubmitting(true)\n setError(null)\n setSuccessMessage(null)\n\n try {\n const response = await client.submitSupportRequest(data)\n\n if (response.success && response.data) {\n setSuccessMessage('Your support request has been submitted successfully.')\n options.onSubmitSuccess?.(response.data)\n return response.data\n } else {\n const errorMsg = getErrorMessage(response.error, 'Failed to submit support request')\n setError(errorMsg)\n options.onSubmitError?.(errorMsg)\n return null\n }\n } catch (err) {\n const errorMsg = getErrorMessage(err, 'An error occurred')\n setError(errorMsg)\n options.onSubmitError?.(errorMsg)\n return null\n } finally {\n setIsSubmitting(false)\n }\n },\n [client, options]\n )\n\n const requestMagicLink = useCallback(\n async (email: string): Promise<boolean> => {\n setIsSendingMagicLink(true)\n setError(null)\n setSuccessMessage(null)\n\n try {\n const response = await client.sendSupportMagicLink(email)\n\n if (response.success) {\n setSuccessMessage('A magic link has been sent to your email.')\n return true\n } else {\n setError(getErrorMessage(response.error, 'Failed to send magic link'))\n return false\n }\n } catch (err) {\n setError(getErrorMessage(err, 'An error occurred'))\n return false\n } finally {\n setIsSendingMagicLink(false)\n }\n },\n [client]\n )\n\n const verifyToken = useCallback(\n async (\n token: string\n ): Promise<{ tickets: SupportRequest[]; userEmail: string } | null> => {\n setIsVerifying(true)\n setError(null)\n\n try {\n const response = await client.verifySupportToken(token)\n\n if (response.success && response.data) {\n return {\n tickets: response.data.tickets,\n userEmail: response.data.user_email,\n }\n } else {\n setError(getErrorMessage(response.error, 'Invalid or expired token'))\n return null\n }\n } catch (err) {\n setError(getErrorMessage(err, 'An error occurred'))\n return null\n } finally {\n setIsVerifying(false)\n }\n },\n [client]\n )\n\n const getTicket = useCallback(\n async (ticketId: string, token: string): Promise<SupportRequest | null> => {\n setError(null)\n\n try {\n const response = await client.getSupportTicket(ticketId, token)\n\n if (response.success && response.data) {\n return response.data\n } else {\n setError(getErrorMessage(response.error, 'Failed to fetch ticket'))\n return null\n }\n } catch (err) {\n setError(getErrorMessage(err, 'An error occurred'))\n return null\n }\n },\n [client]\n )\n\n const addMessage = useCallback(\n async (\n ticketId: string,\n token: string,\n content: string\n ): Promise<{ id: string; content: string; created_at: string } | null> => {\n setError(null)\n\n try {\n const response = await client.addSupportMessage(ticketId, token, content)\n\n if (response.success && response.data) {\n return response.data\n } else {\n setError(getErrorMessage(response.error, 'Failed to add message'))\n return null\n }\n } catch (err) {\n setError(getErrorMessage(err, 'An error occurred'))\n return null\n }\n },\n [client]\n )\n\n return {\n isSubmitting,\n isSendingMagicLink,\n isVerifying,\n error,\n successMessage,\n submitTicket,\n requestMagicLink,\n verifyToken,\n getTicket,\n addMessage,\n clearMessages,\n }\n}\n"]}
|
package/dist/chunk-ZJZ3A2S3.js
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var chunk75P634IK_js = require('./chunk-75P634IK.js');
|
|
4
|
-
var react = require('react');
|
|
5
|
-
|
|
6
|
-
function useWish(options) {
|
|
7
|
-
const { client, fingerprint } = chunk75P634IK_js.useAppgramContext();
|
|
8
|
-
const [wish, setWish] = react.useState(null);
|
|
9
|
-
const [isLoading, setIsLoading] = react.useState(!options.skip);
|
|
10
|
-
const [error, setError] = react.useState(null);
|
|
11
|
-
const fetchWish = react.useCallback(async () => {
|
|
12
|
-
if (options.skip || !options.wishId) return;
|
|
13
|
-
setIsLoading(true);
|
|
14
|
-
setError(null);
|
|
15
|
-
try {
|
|
16
|
-
const response = await client.getWish(options.wishId);
|
|
17
|
-
if (response.success && response.data) {
|
|
18
|
-
let wishData = response.data;
|
|
19
|
-
if (fingerprint) {
|
|
20
|
-
const voteResponse = await client.checkVote(options.wishId, fingerprint);
|
|
21
|
-
wishData = {
|
|
22
|
-
...wishData,
|
|
23
|
-
has_voted: voteResponse.success && voteResponse.data?.has_voted
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
setWish(wishData);
|
|
27
|
-
} else {
|
|
28
|
-
setError(chunk75P634IK_js.getErrorMessage(response.error, "Failed to fetch wish"));
|
|
29
|
-
}
|
|
30
|
-
} catch (err) {
|
|
31
|
-
setError(chunk75P634IK_js.getErrorMessage(err, "An error occurred"));
|
|
32
|
-
} finally {
|
|
33
|
-
setIsLoading(false);
|
|
34
|
-
}
|
|
35
|
-
}, [client, fingerprint, options.wishId, options.skip]);
|
|
36
|
-
react.useEffect(() => {
|
|
37
|
-
fetchWish();
|
|
38
|
-
}, [fetchWish]);
|
|
39
|
-
return {
|
|
40
|
-
wish,
|
|
41
|
-
isLoading,
|
|
42
|
-
error,
|
|
43
|
-
refetch: fetchWish
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
exports.useWish = useWish;
|
|
48
|
-
//# sourceMappingURL=chunk-ZJZ3A2S3.js.map
|
|
49
|
-
//# sourceMappingURL=chunk-ZJZ3A2S3.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hooks/useWish.ts"],"names":["useAppgramContext","useState","useCallback","getErrorMessage","useEffect"],"mappings":";;;;;AA8CO,SAAS,QAAQ,OAAA,EAAwC;AAC9D,EAAA,MAAM,EAAE,MAAA,EAAQ,WAAA,EAAY,GAAIA,kCAAA,EAAkB;AAClD,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIC,eAAsB,IAAI,CAAA;AAClD,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,IAAIA,cAAA,CAAS,CAAC,QAAQ,IAAI,CAAA;AACxD,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIA,eAAwB,IAAI,CAAA;AAEtD,EAAA,MAAM,SAAA,GAAYC,kBAAY,YAAY;AACxC,IAAA,IAAI,OAAA,CAAQ,IAAA,IAAQ,CAAC,OAAA,CAAQ,MAAA,EAAQ;AAErC,IAAA,YAAA,CAAa,IAAI,CAAA;AACjB,IAAA,QAAA,CAAS,IAAI,CAAA;AAEb,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,MAAA,CAAO,OAAA,CAAQ,QAAQ,MAAM,CAAA;AAEpD,MAAA,IAAI,QAAA,CAAS,OAAA,IAAW,QAAA,CAAS,IAAA,EAAM;AACrC,QAAA,IAAI,WAAW,QAAA,CAAS,IAAA;AAGxB,QAAA,IAAI,WAAA,EAAa;AACf,UAAA,MAAM,eAAe,MAAM,MAAA,CAAO,SAAA,CAAU,OAAA,CAAQ,QAAQ,WAAW,CAAA;AACvE,UAAA,QAAA,GAAW;AAAA,YACT,GAAG,QAAA;AAAA,YACH,SAAA,EAAW,YAAA,CAAa,OAAA,IAAW,YAAA,CAAa,IAAA,EAAM;AAAA,WACxD;AAAA,QACF;AAEA,QAAA,OAAA,CAAQ,QAAQ,CAAA;AAAA,MAClB,CAAA,MAAO;AACL,QAAA,QAAA,CAASC,gCAAA,CAAgB,QAAA,CAAS,KAAA,EAAO,sBAAsB,CAAC,CAAA;AAAA,MAClE;AAAA,IACF,SAAS,GAAA,EAAK;AACZ,MAAA,QAAA,CAASA,gCAAA,CAAgB,GAAA,EAAK,mBAAmB,CAAC,CAAA;AAAA,IACpD,CAAA,SAAE;AACA,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA,IACpB;AAAA,EACF,CAAA,EAAG,CAAC,MAAA,EAAQ,WAAA,EAAa,QAAQ,MAAA,EAAQ,OAAA,CAAQ,IAAI,CAAC,CAAA;AAEtD,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,SAAA,EAAU;AAAA,EACZ,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;AAEd,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,SAAA;AAAA,IACA,KAAA;AAAA,IACA,OAAA,EAAS;AAAA,GACX;AACF","file":"chunk-ZJZ3A2S3.js","sourcesContent":["/**\n * useWish Hook\n *\n * Fetches and manages a single wish.\n */\n\nimport { useState, useEffect, useCallback } from 'react'\nimport { useAppgramContext } from '../provider/context'\nimport { getErrorMessage } from '../utils'\nimport type { Wish } from '../types'\n\nexport interface UseWishOptions {\n /**\n * The wish ID to fetch\n */\n wishId: string\n\n /**\n * Skip initial fetch\n * @default false\n */\n skip?: boolean\n}\n\nexport interface UseWishResult {\n /**\n * The wish data\n */\n wish: Wish | null\n\n /**\n * Loading state\n */\n isLoading: boolean\n\n /**\n * Error message if any\n */\n error: string | null\n\n /**\n * Manually refetch data\n */\n refetch: () => Promise<void>\n}\n\nexport function useWish(options: UseWishOptions): UseWishResult {\n const { client, fingerprint } = useAppgramContext()\n const [wish, setWish] = useState<Wish | null>(null)\n const [isLoading, setIsLoading] = useState(!options.skip)\n const [error, setError] = useState<string | null>(null)\n\n const fetchWish = useCallback(async () => {\n if (options.skip || !options.wishId) return\n\n setIsLoading(true)\n setError(null)\n\n try {\n const response = await client.getWish(options.wishId)\n\n if (response.success && response.data) {\n let wishData = response.data\n\n // Check vote status if fingerprint available\n if (fingerprint) {\n const voteResponse = await client.checkVote(options.wishId, fingerprint)\n wishData = {\n ...wishData,\n has_voted: voteResponse.success && voteResponse.data?.has_voted,\n }\n }\n\n setWish(wishData)\n } else {\n setError(getErrorMessage(response.error, 'Failed to fetch wish'))\n }\n } catch (err) {\n setError(getErrorMessage(err, 'An error occurred'))\n } finally {\n setIsLoading(false)\n }\n }, [client, fingerprint, options.wishId, options.skip])\n\n useEffect(() => {\n fetchWish()\n }, [fetchWish])\n\n return {\n wish,\n isLoading,\n error,\n refetch: fetchWish,\n }\n}\n"]}
|