@semiont/frontend 0.4.12 → 0.4.13
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/assets/{AuthContext-CUx-cP7W.js → AuthContext-CqopYuY9.js} +2 -2
- package/dist/assets/{AuthContext-CUx-cP7W.js.map → AuthContext-CqopYuY9.js.map} +1 -1
- package/dist/assets/{CookiePreferences-BuRvkBwM.js → CookiePreferences-DIUP_g1S.js} +2 -2
- package/dist/assets/{CookiePreferences-BuRvkBwM.js.map → CookiePreferences-DIUP_g1S.js.map} +1 -1
- package/dist/assets/{PdfAnnotationCanvas.client-CW6SKH2U-CjRY6TID.js → PdfAnnotationCanvas.client-CW6SKH2U-Ct60nVWs.js} +2 -2
- package/dist/assets/{PdfAnnotationCanvas.client-CW6SKH2U-CjRY6TID.js.map → PdfAnnotationCanvas.client-CW6SKH2U-Ct60nVWs.js.map} +1 -1
- package/dist/assets/{ToolbarPanels-Drd8QG61.js → ToolbarPanels-CtBfzYcP.js} +2 -2
- package/dist/assets/{ToolbarPanels-Drd8QG61.js.map → ToolbarPanels-CtBfzYcP.js.map} +1 -1
- package/dist/assets/{client-BbPyO59A.js → client-B-4-Nmfd.js} +2 -2
- package/dist/assets/{client-BbPyO59A.js.map → client-B-4-Nmfd.js.map} +1 -1
- package/dist/assets/{client-BsHptwGn.js → client-CTdkaDl6.js} +2 -2
- package/dist/assets/{client-BsHptwGn.js.map → client-CTdkaDl6.js.map} +1 -1
- package/dist/assets/{client-DZ-DNAU-.js → client-DvSa4CTk.js} +2 -2
- package/dist/assets/{client-DZ-DNAU-.js.map → client-DvSa4CTk.js.map} +1 -1
- package/dist/assets/{client-COY1ucYF.js → client-rUyzJlA6.js} +2 -2
- package/dist/assets/{client-COY1ucYF.js.map → client-rUyzJlA6.js.map} +1 -1
- package/dist/assets/{en-IUV4ZXKH-eHunUM2g.js → en-IUV4ZXKH-b_r0oyRV.js} +45 -45
- package/dist/assets/en-IUV4ZXKH-b_r0oyRV.js.map +1 -0
- package/dist/assets/{index-DKq_l4UW.js → index-dFCLrpeL.js} +3 -3
- package/dist/assets/index-dFCLrpeL.js.map +1 -0
- package/dist/assets/{layout-CvaTeY53.js → layout-BwurEG3I.js} +2 -2
- package/dist/assets/{layout-CvaTeY53.js.map → layout-BwurEG3I.js.map} +1 -1
- package/dist/assets/{layout-D5Pjl6Q-.js → layout-CCNyNXfP.js} +2 -2
- package/dist/assets/{layout-D5Pjl6Q-.js.map → layout-CCNyNXfP.js.map} +1 -1
- package/dist/assets/{layout-QZ56PNLk.js → layout-CHfFscVU.js} +2 -2
- package/dist/assets/{layout-QZ56PNLk.js.map → layout-CHfFscVU.js.map} +1 -1
- package/dist/assets/{layout-6uvM-QPR.js → layout-CL9MSbhu.js} +2 -2
- package/dist/assets/{layout-6uvM-QPR.js.map → layout-CL9MSbhu.js.map} +1 -1
- package/dist/assets/{not-found-CudKZDad.js → not-found-DE1pkuFl.js} +2 -2
- package/dist/assets/{not-found-CudKZDad.js.map → not-found-DE1pkuFl.js.map} +1 -1
- package/dist/assets/{page-4gaXuuoi.js → page-B-TRTXbV.js} +2 -2
- package/dist/assets/{page-4gaXuuoi.js.map → page-B-TRTXbV.js.map} +1 -1
- package/dist/assets/{page-uukho-t7.js → page-B3h2_PT5.js} +2 -2
- package/dist/assets/{page-uukho-t7.js.map → page-B3h2_PT5.js.map} +1 -1
- package/dist/assets/page-BfUI7FZJ.js +2 -0
- package/dist/assets/{page-CJFp0ZpS.js.map → page-BfUI7FZJ.js.map} +1 -1
- package/dist/assets/{page-CGEmB0mm.js → page-C-os3U8h.js} +2 -2
- package/dist/assets/{page-CGEmB0mm.js.map → page-C-os3U8h.js.map} +1 -1
- package/dist/assets/{page-vzoIwpsS.js → page-C02dLWb8.js} +2 -2
- package/dist/assets/{page-vzoIwpsS.js.map → page-C02dLWb8.js.map} +1 -1
- package/dist/assets/{page-DjkPUxlb.js → page-CGDUl5-d.js} +2 -2
- package/dist/assets/{page-DjkPUxlb.js.map → page-CGDUl5-d.js.map} +1 -1
- package/dist/assets/{page-B9hPrBrN.js → page-CHq5JMOn.js} +2 -2
- package/dist/assets/{page-B9hPrBrN.js.map → page-CHq5JMOn.js.map} +1 -1
- package/dist/assets/{page-C44nBk5U.js → page-CUbbBytS.js} +2 -2
- package/dist/assets/{page-C44nBk5U.js.map → page-CUbbBytS.js.map} +1 -1
- package/dist/assets/{page-DVRMfAkS.js → page-C_L33_wR.js} +2 -2
- package/dist/assets/{page-DVRMfAkS.js.map → page-C_L33_wR.js.map} +1 -1
- package/dist/assets/{page-tb55k9Ji.js → page-CaVtCo4z.js} +2 -2
- package/dist/assets/{page-tb55k9Ji.js.map → page-CaVtCo4z.js.map} +1 -1
- package/dist/assets/{page-BH5HMa4o.js → page-CjTcoHSS.js} +2 -2
- package/dist/assets/{page-BH5HMa4o.js.map → page-CjTcoHSS.js.map} +1 -1
- package/dist/assets/{page-lbZaKDJf.js → page-CtRMzwE_.js} +2 -2
- package/dist/assets/{page-lbZaKDJf.js.map → page-CtRMzwE_.js.map} +1 -1
- package/dist/assets/{page-DIv5j5nE.js → page-Cu2tT5mi.js} +2 -2
- package/dist/assets/{page-DIv5j5nE.js.map → page-Cu2tT5mi.js.map} +1 -1
- package/dist/assets/{page-Bz2r7ufy.js → page-D5i-uRGy.js} +2 -2
- package/dist/assets/{page-Bz2r7ufy.js.map → page-D5i-uRGy.js.map} +1 -1
- package/dist/assets/{page-CE8hOJlL.js → page-DXACCazr.js} +2 -2
- package/dist/assets/{page-CE8hOJlL.js.map → page-DXACCazr.js.map} +1 -1
- package/dist/assets/{page-ESjXBvXd.js → page-DiKTriTX.js} +2 -2
- package/dist/assets/{page-ESjXBvXd.js.map → page-DiKTriTX.js.map} +1 -1
- package/dist/assets/page-eJup0RrB.js +2 -0
- package/dist/assets/page-eJup0RrB.js.map +1 -0
- package/dist/assets/{page-DK5bpgp9.js → page-qhHVLOTR.js} +2 -2
- package/dist/assets/{page-DK5bpgp9.js.map → page-qhHVLOTR.js.map} +1 -1
- package/dist/assets/{privacy-W9SxWfL5.js → privacy-BMKdYFGC.js} +2 -2
- package/dist/assets/{privacy-W9SxWfL5.js.map → privacy-BMKdYFGC.js.map} +1 -1
- package/dist/assets/{routing-6lnx-g5H.js → routing-BBQqTcTn.js} +2 -2
- package/dist/assets/{routing-6lnx-g5H.js.map → routing-BBQqTcTn.js.map} +1 -1
- package/dist/assets/{routing-BLuuVVPN.js → routing-BPQO9e8a.js} +2 -2
- package/dist/assets/{routing-BLuuVVPN.js.map → routing-BPQO9e8a.js.map} +1 -1
- package/dist/assets/{useAuth-CAJolYxw.js → useAuth-B9hvtwrc.js} +2 -2
- package/dist/assets/{useAuth-CAJolYxw.js.map → useAuth-B9hvtwrc.js.map} +1 -1
- package/dist/index.html +1 -1
- package/dist/messages/ar.json +1 -1
- package/dist/messages/bn.json +1 -1
- package/dist/messages/cs.json +1 -1
- package/dist/messages/da.json +1 -1
- package/dist/messages/de.json +1 -1
- package/dist/messages/el.json +1 -1
- package/dist/messages/en.json +1 -1
- package/dist/messages/es.json +1 -1
- package/dist/messages/fa.json +1 -1
- package/dist/messages/fi.json +1 -1
- package/dist/messages/fr.json +1 -1
- package/dist/messages/he.json +1 -1
- package/dist/messages/hi.json +1 -1
- package/dist/messages/id.json +1 -1
- package/dist/messages/it.json +1 -1
- package/dist/messages/ja.json +1 -1
- package/dist/messages/ko.json +1 -1
- package/dist/messages/ms.json +1 -1
- package/dist/messages/nl.json +1 -1
- package/dist/messages/no.json +1 -1
- package/dist/messages/pl.json +1 -1
- package/dist/messages/pt.json +1 -1
- package/dist/messages/ro.json +1 -1
- package/dist/messages/sv.json +1 -1
- package/dist/messages/th.json +1 -1
- package/dist/messages/tr.json +1 -1
- package/dist/messages/uk.json +1 -1
- package/dist/messages/vi.json +1 -1
- package/dist/messages/zh.json +1 -1
- package/package.json +1 -1
- package/dist/assets/en-IUV4ZXKH-eHunUM2g.js.map +0 -1
- package/dist/assets/index-DKq_l4UW.js.map +0 -1
- package/dist/assets/page-CJFp0ZpS.js +0 -2
- package/dist/assets/page-D1Di1cx-.js +0 -2
- package/dist/assets/page-D1Di1cx-.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"privacy-W9SxWfL5.js","sources":["../../src/components/modals/GlobalSearchModal.tsx","../../src/contexts/KeyboardShortcutsContext.tsx","../../src/lib/cookies/constants.ts","../../src/lib/cookies/cleanup.ts","../../src/lib/cookies/consent.ts","../../src/lib/cookies/privacy.ts"],"sourcesContent":["import React from 'react';\nimport { useRouter } from '@/i18n/routing';\nimport { SearchModal } from '@semiont/react-ui';\nimport { useTranslation } from 'react-i18next';\n\ninterface GlobalSearchModalProps {\n isOpen: boolean;\n onClose: () => void;\n}\n\nexport function GlobalSearchModal({ isOpen, onClose }: GlobalSearchModalProps) {\n const router = useRouter();\n const { t: _t } = useTranslation();\n const t = (k: string, p?: Record<string, unknown>) => _t(`Search.${k}`, p as any) as string;\n\n const handleNavigate = (type: 'resource' | 'entity', id: string) => {\n if (type === 'resource') {\n router.push(`/know/resource/${encodeURIComponent(id)}`);\n } else {\n router.push(`/know/entity/${id}`);\n }\n };\n\n return (\n <SearchModal\n isOpen={isOpen}\n onClose={onClose}\n onNavigate={handleNavigate}\n translations={{\n placeholder: t('placeholder'),\n searching: t('searching'),\n noResults: t('noResults'),\n startTyping: t('startTyping'),\n navigate: t('navigate'),\n select: t('select'),\n close: t('close'),\n enter: t('enter'),\n esc: t('esc'),\n }}\n />\n );\n}","import React, { createContext, useContext, useState, useCallback } from 'react';\nimport { useRouter } from '@/i18n/routing';\nimport { useKeyboardShortcuts, useDoubleKeyPress, KeyboardShortcutsHelpModal } from '@semiont/react-ui';\nimport { GlobalSearchModal } from '../components/modals/GlobalSearchModal';\n\ninterface KeyboardShortcutsContextType {\n openGlobalSearch: () => void;\n openKeyboardHelp: () => void;\n closeAllOverlays: () => void;\n}\n\nexport const KeyboardShortcutsContext = createContext<KeyboardShortcutsContextType | null>(null);\n\nexport function useKeyboardShortcutsContext() {\n const context = useContext(KeyboardShortcutsContext);\n if (!context) {\n throw new Error('useKeyboardShortcutsContext must be used within KeyboardShortcutsProvider');\n }\n return context;\n}\n\ninterface KeyboardShortcutsProviderProps {\n children: React.ReactNode;\n}\n\nexport function KeyboardShortcutsProvider({ children }: KeyboardShortcutsProviderProps) {\n const router = useRouter();\n const [isSearchOpen, setIsSearchOpen] = useState(false);\n const [isHelpOpen, setIsHelpOpen] = useState(false);\n const [overlayCloseCallbacks, setOverlayCloseCallbacks] = useState<(() => void)[]>([]);\n\n // Open global search\n const openGlobalSearch = useCallback(() => {\n setIsSearchOpen(true);\n }, []);\n\n // Open keyboard help\n const openKeyboardHelp = useCallback(() => {\n setIsHelpOpen(true);\n }, []);\n\n // Close all overlays\n const closeAllOverlays = useCallback(() => {\n // Close all modals\n setIsSearchOpen(false);\n setIsHelpOpen(false);\n\n // Call all registered overlay close callbacks\n overlayCloseCallbacks.forEach(callback => callback());\n\n // Clear the callbacks\n setOverlayCloseCallbacks([]);\n }, [overlayCloseCallbacks]);\n\n // Register global keyboard shortcuts\n useKeyboardShortcuts([\n {\n key: 'k',\n ctrlOrCmd: true,\n handler: () => {\n openGlobalSearch();\n },\n description: 'Open global search'\n },\n {\n key: 'n',\n ctrlOrCmd: true,\n handler: () => {\n // Navigate to compose page to create new resource\n router.push('/know/compose');\n },\n description: 'Create new resource'\n },\n {\n key: '/',\n handler: () => {\n // Alternative search trigger (like GitHub)\n openGlobalSearch();\n },\n description: 'Open global search (alternative)'\n },\n {\n key: '?',\n shift: true,\n handler: () => {\n // Open keyboard shortcuts help\n openKeyboardHelp();\n },\n description: 'Show keyboard shortcuts help'\n }\n ]);\n\n // Double Escape to close all overlays\n useDoubleKeyPress('Escape', closeAllOverlays, 300);\n\n const contextValue: KeyboardShortcutsContextType = {\n openGlobalSearch,\n openKeyboardHelp,\n closeAllOverlays\n };\n\n return (\n <KeyboardShortcutsContext.Provider value={contextValue}>\n {children}\n {isSearchOpen && (\n <GlobalSearchModal\n isOpen={isSearchOpen}\n onClose={() => setIsSearchOpen(false)}\n />\n )}\n {isHelpOpen && (\n <KeyboardShortcutsHelpModal\n isOpen={isHelpOpen}\n onClose={() => setIsHelpOpen(false)}\n />\n )}\n </KeyboardShortcutsContext.Provider>\n );\n}","import type { CookieCategory, CookieConsent } from './types';\n\n// Cookie categories with descriptions\nexport const COOKIE_CATEGORIES: CookieCategory[] = [\n {\n id: 'necessary',\n name: 'Strictly Necessary',\n description: 'These cookies are essential for the website to function properly. They enable core functionality such as security, network management, and accessibility.',\n required: true,\n cookies: ['semiont-token', 'consent-preferences']\n },\n {\n id: 'analytics',\n name: 'Analytics',\n description: 'These cookies help us understand how visitors interact with our website by collecting and reporting information anonymously.',\n required: false,\n cookies: ['_ga', '_ga_*', '_gid', '_gat', 'lighthouse-*']\n },\n {\n id: 'marketing',\n name: 'Marketing',\n description: 'These cookies are used to track visitors across websites to display relevant advertisements and measure campaign effectiveness.',\n required: false,\n cookies: ['_fbp', '_fbc', 'fr', 'ads-*']\n },\n {\n id: 'preferences',\n name: 'Preferences',\n description: 'These cookies remember your choices and preferences to provide a more personalized experience.',\n required: false,\n cookies: ['theme-preference', 'language-preference', 'ui-settings']\n }\n];\n\n// Current consent version (increment when privacy policy changes)\nexport const CONSENT_VERSION = '1.0';\n\n// Cookie names\nexport const CONSENT_COOKIE_NAME = 'semiont-cookie-consent';\nexport const PREFERENCES_COOKIE_NAME = 'semiont-cookie-preferences';\n\n// Default consent state\nexport const DEFAULT_CONSENT: CookieConsent = {\n necessary: true, // Always true, required for functionality\n analytics: false,\n marketing: false,\n preferences: false,\n timestamp: new Date().toISOString(),\n version: CONSENT_VERSION\n};\n","import type { CookieConsent } from './types';\nimport { COOKIE_CATEGORIES } from './constants';\n\n// Clean up cookies based on consent\nexport const cleanupCookies = (consent: CookieConsent): void => {\n if (typeof window === 'undefined') return;\n\n COOKIE_CATEGORIES.forEach(category => {\n if (category.required) return; // Never clean up required cookies\n\n const hasConsent = consent[category.id];\n if (!hasConsent) {\n // Remove cookies for this category\n category.cookies.forEach(cookieName => {\n if (cookieName.includes('*')) {\n // Handle wildcard cookies\n const prefix = cookieName.replace('*', '');\n document.cookie.split(';').forEach(cookie => {\n const name = cookie.split('=')[0]?.trim();\n if (name && name.startsWith(prefix)) {\n deleteCookie(name);\n }\n });\n } else {\n deleteCookie(cookieName);\n }\n });\n }\n });\n};\n\n// Delete a specific cookie\nexport const deleteCookie = (name: string): void => {\n // Delete for current domain\n document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`;\n // Delete for parent domain\n document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; domain=${window.location.hostname}`;\n // Delete for root domain\n const rootDomain = window.location.hostname.split('.').slice(-2).join('.');\n document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; domain=.${rootDomain}`;\n};\n","import type { CookieConsent } from './types';\nimport { CONSENT_COOKIE_NAME, CONSENT_VERSION, DEFAULT_CONSENT } from './constants';\nimport { cleanupCookies } from './cleanup';\n\nexport const getCookieConsent = (): CookieConsent | null => {\n if (typeof window === 'undefined') return null;\n\n try {\n const consent = localStorage.getItem(CONSENT_COOKIE_NAME);\n if (!consent) return null;\n\n const parsed = JSON.parse(consent) as CookieConsent;\n\n // Check if consent is for current version\n if (parsed.version !== CONSENT_VERSION) {\n return null; // Force re-consent for new version\n }\n\n return parsed;\n } catch (error) {\n console.warn('Failed to parse cookie consent:', error);\n return null;\n }\n};\n\nexport const setCookieConsent = (consent: Partial<CookieConsent>): void => {\n if (typeof window === 'undefined') return;\n\n const fullConsent: CookieConsent = {\n ...DEFAULT_CONSENT,\n ...consent,\n necessary: true, // Always true\n timestamp: new Date().toISOString(),\n version: CONSENT_VERSION\n };\n\n try {\n localStorage.setItem(CONSENT_COOKIE_NAME, JSON.stringify(fullConsent));\n\n // Clean up cookies based on consent\n cleanupCookies(fullConsent);\n\n // Dispatch custom event for components to react to consent changes\n window.dispatchEvent(new CustomEvent('cookieConsentChanged', {\n detail: fullConsent\n }));\n } catch (error) {\n console.error('Failed to save cookie consent:', error);\n }\n};\n\nexport const hasValidConsent = (): boolean => {\n const consent = getCookieConsent();\n if (!consent) return false;\n\n // Check if consent is less than 13 months old (GDPR requirement)\n const consentDate = new Date(consent.timestamp);\n const thirteenMonthsAgo = new Date();\n thirteenMonthsAgo.setMonth(thirteenMonthsAgo.getMonth() - 13);\n\n return consentDate > thirteenMonthsAgo;\n};\n\nexport const shouldShowBanner = (): boolean => {\n if (typeof window === 'undefined') return false;\n return !hasValidConsent();\n};\n","import { deleteCookie } from './cleanup';\n\n// Get user's location for CCPA vs GDPR detection (simplified)\nexport const getUserLocation = async (): Promise<'EU' | 'CA' | 'US' | 'OTHER'> => {\n try {\n // In a real implementation, you'd use a geolocation service\n // For now, we'll detect based on timezone as a rough approximation\n const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n\n if (timezone.includes('Europe/')) return 'EU';\n if (timezone.includes('America/Los_Angeles') || timezone.includes('America/Vancouver')) return 'CA';\n if (timezone.includes('America/')) return 'US';\n\n return 'OTHER';\n } catch {\n return 'OTHER';\n }\n};\n\n// Check if CCPA applies (California residents)\nexport const isCCPAApplicable = async (): Promise<boolean> => {\n const location = await getUserLocation();\n return location === 'CA';\n};\n\n// Check if GDPR applies (EU residents)\nexport const isGDPRApplicable = async (): Promise<boolean> => {\n const location = await getUserLocation();\n return location === 'EU';\n};\n\n// Export all cookies currently set\nexport const exportUserData = (): Record<string, string> => {\n if (typeof window === 'undefined') return {};\n\n const data: Record<string, string> = {};\n\n // Get all cookies\n document.cookie.split(';').forEach(cookie => {\n const [name, value] = cookie.trim().split('=');\n if (name && value) {\n data[`cookie_${name}`] = decodeURIComponent(value);\n }\n });\n\n // Get localStorage data\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i);\n if (key) {\n data[`localStorage_${key}`] = localStorage.getItem(key) || '';\n }\n }\n\n // Get sessionStorage data\n for (let i = 0; i < sessionStorage.length; i++) {\n const key = sessionStorage.key(i);\n if (key) {\n data[`sessionStorage_${key}`] = sessionStorage.getItem(key) || '';\n }\n }\n\n return data;\n};\n\n// Delete all user data (GDPR right to be forgotten)\nexport const deleteAllUserData = (): void => {\n if (typeof window === 'undefined') return;\n\n // Clear all localStorage\n localStorage.clear();\n\n // Clear all sessionStorage\n sessionStorage.clear();\n\n // Delete all cookies\n document.cookie.split(';').forEach(cookie => {\n const name = cookie.split('=')[0]?.trim();\n if (name) {\n deleteCookie(name);\n }\n });\n\n // Reload page to ensure clean state\n window.location.reload();\n};\n"],"names":["GlobalSearchModal","isOpen","onClose","router","useRouter","_t","useTranslation","t","k","p","handleNavigate","type","id","jsx","SearchModal","KeyboardShortcutsContext","createContext","KeyboardShortcutsProvider","children","isSearchOpen","setIsSearchOpen","useState","isHelpOpen","setIsHelpOpen","overlayCloseCallbacks","setOverlayCloseCallbacks","openGlobalSearch","useCallback","openKeyboardHelp","closeAllOverlays","callback","useKeyboardShortcuts","useDoubleKeyPress","contextValue","jsxs","KeyboardShortcutsHelpModal","COOKIE_CATEGORIES","CONSENT_VERSION","CONSENT_COOKIE_NAME","DEFAULT_CONSENT","cleanupCookies","consent","category","cookieName","prefix","cookie","name","_a","deleteCookie","rootDomain","getCookieConsent","parsed","error","setCookieConsent","fullConsent","hasValidConsent","consentDate","thirteenMonthsAgo","shouldShowBanner","getUserLocation","timezone","isCCPAApplicable","isGDPRApplicable","exportUserData","data","value","i","key","deleteAllUserData"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"privacy-BMKdYFGC.js","sources":["../../src/components/modals/GlobalSearchModal.tsx","../../src/contexts/KeyboardShortcutsContext.tsx","../../src/lib/cookies/constants.ts","../../src/lib/cookies/cleanup.ts","../../src/lib/cookies/consent.ts","../../src/lib/cookies/privacy.ts"],"sourcesContent":["import React from 'react';\nimport { useRouter } from '@/i18n/routing';\nimport { SearchModal } from '@semiont/react-ui';\nimport { useTranslation } from 'react-i18next';\n\ninterface GlobalSearchModalProps {\n isOpen: boolean;\n onClose: () => void;\n}\n\nexport function GlobalSearchModal({ isOpen, onClose }: GlobalSearchModalProps) {\n const router = useRouter();\n const { t: _t } = useTranslation();\n const t = (k: string, p?: Record<string, unknown>) => _t(`Search.${k}`, p as any) as string;\n\n const handleNavigate = (type: 'resource' | 'entity', id: string) => {\n if (type === 'resource') {\n router.push(`/know/resource/${encodeURIComponent(id)}`);\n } else {\n router.push(`/know/entity/${id}`);\n }\n };\n\n return (\n <SearchModal\n isOpen={isOpen}\n onClose={onClose}\n onNavigate={handleNavigate}\n translations={{\n placeholder: t('placeholder'),\n searching: t('searching'),\n noResults: t('noResults'),\n startTyping: t('startTyping'),\n navigate: t('navigate'),\n select: t('select'),\n close: t('close'),\n enter: t('enter'),\n esc: t('esc'),\n }}\n />\n );\n}","import React, { createContext, useContext, useState, useCallback } from 'react';\nimport { useRouter } from '@/i18n/routing';\nimport { useKeyboardShortcuts, useDoubleKeyPress, KeyboardShortcutsHelpModal } from '@semiont/react-ui';\nimport { GlobalSearchModal } from '../components/modals/GlobalSearchModal';\n\ninterface KeyboardShortcutsContextType {\n openGlobalSearch: () => void;\n openKeyboardHelp: () => void;\n closeAllOverlays: () => void;\n}\n\nexport const KeyboardShortcutsContext = createContext<KeyboardShortcutsContextType | null>(null);\n\nexport function useKeyboardShortcutsContext() {\n const context = useContext(KeyboardShortcutsContext);\n if (!context) {\n throw new Error('useKeyboardShortcutsContext must be used within KeyboardShortcutsProvider');\n }\n return context;\n}\n\ninterface KeyboardShortcutsProviderProps {\n children: React.ReactNode;\n}\n\nexport function KeyboardShortcutsProvider({ children }: KeyboardShortcutsProviderProps) {\n const router = useRouter();\n const [isSearchOpen, setIsSearchOpen] = useState(false);\n const [isHelpOpen, setIsHelpOpen] = useState(false);\n const [overlayCloseCallbacks, setOverlayCloseCallbacks] = useState<(() => void)[]>([]);\n\n // Open global search\n const openGlobalSearch = useCallback(() => {\n setIsSearchOpen(true);\n }, []);\n\n // Open keyboard help\n const openKeyboardHelp = useCallback(() => {\n setIsHelpOpen(true);\n }, []);\n\n // Close all overlays\n const closeAllOverlays = useCallback(() => {\n // Close all modals\n setIsSearchOpen(false);\n setIsHelpOpen(false);\n\n // Call all registered overlay close callbacks\n overlayCloseCallbacks.forEach(callback => callback());\n\n // Clear the callbacks\n setOverlayCloseCallbacks([]);\n }, [overlayCloseCallbacks]);\n\n // Register global keyboard shortcuts\n useKeyboardShortcuts([\n {\n key: 'k',\n ctrlOrCmd: true,\n handler: () => {\n openGlobalSearch();\n },\n description: 'Open global search'\n },\n {\n key: 'n',\n ctrlOrCmd: true,\n handler: () => {\n // Navigate to compose page to create new resource\n router.push('/know/compose');\n },\n description: 'Create new resource'\n },\n {\n key: '/',\n handler: () => {\n // Alternative search trigger (like GitHub)\n openGlobalSearch();\n },\n description: 'Open global search (alternative)'\n },\n {\n key: '?',\n shift: true,\n handler: () => {\n // Open keyboard shortcuts help\n openKeyboardHelp();\n },\n description: 'Show keyboard shortcuts help'\n }\n ]);\n\n // Double Escape to close all overlays\n useDoubleKeyPress('Escape', closeAllOverlays, 300);\n\n const contextValue: KeyboardShortcutsContextType = {\n openGlobalSearch,\n openKeyboardHelp,\n closeAllOverlays\n };\n\n return (\n <KeyboardShortcutsContext.Provider value={contextValue}>\n {children}\n {isSearchOpen && (\n <GlobalSearchModal\n isOpen={isSearchOpen}\n onClose={() => setIsSearchOpen(false)}\n />\n )}\n {isHelpOpen && (\n <KeyboardShortcutsHelpModal\n isOpen={isHelpOpen}\n onClose={() => setIsHelpOpen(false)}\n />\n )}\n </KeyboardShortcutsContext.Provider>\n );\n}","import type { CookieCategory, CookieConsent } from './types';\n\n// Cookie categories with descriptions\nexport const COOKIE_CATEGORIES: CookieCategory[] = [\n {\n id: 'necessary',\n name: 'Strictly Necessary',\n description: 'These cookies are essential for the website to function properly. They enable core functionality such as security, network management, and accessibility.',\n required: true,\n cookies: ['semiont-token', 'consent-preferences']\n },\n {\n id: 'analytics',\n name: 'Analytics',\n description: 'These cookies help us understand how visitors interact with our website by collecting and reporting information anonymously.',\n required: false,\n cookies: ['_ga', '_ga_*', '_gid', '_gat', 'lighthouse-*']\n },\n {\n id: 'marketing',\n name: 'Marketing',\n description: 'These cookies are used to track visitors across websites to display relevant advertisements and measure campaign effectiveness.',\n required: false,\n cookies: ['_fbp', '_fbc', 'fr', 'ads-*']\n },\n {\n id: 'preferences',\n name: 'Preferences',\n description: 'These cookies remember your choices and preferences to provide a more personalized experience.',\n required: false,\n cookies: ['theme-preference', 'language-preference', 'ui-settings']\n }\n];\n\n// Current consent version (increment when privacy policy changes)\nexport const CONSENT_VERSION = '1.0';\n\n// Cookie names\nexport const CONSENT_COOKIE_NAME = 'semiont-cookie-consent';\nexport const PREFERENCES_COOKIE_NAME = 'semiont-cookie-preferences';\n\n// Default consent state\nexport const DEFAULT_CONSENT: CookieConsent = {\n necessary: true, // Always true, required for functionality\n analytics: false,\n marketing: false,\n preferences: false,\n timestamp: new Date().toISOString(),\n version: CONSENT_VERSION\n};\n","import type { CookieConsent } from './types';\nimport { COOKIE_CATEGORIES } from './constants';\n\n// Clean up cookies based on consent\nexport const cleanupCookies = (consent: CookieConsent): void => {\n if (typeof window === 'undefined') return;\n\n COOKIE_CATEGORIES.forEach(category => {\n if (category.required) return; // Never clean up required cookies\n\n const hasConsent = consent[category.id];\n if (!hasConsent) {\n // Remove cookies for this category\n category.cookies.forEach(cookieName => {\n if (cookieName.includes('*')) {\n // Handle wildcard cookies\n const prefix = cookieName.replace('*', '');\n document.cookie.split(';').forEach(cookie => {\n const name = cookie.split('=')[0]?.trim();\n if (name && name.startsWith(prefix)) {\n deleteCookie(name);\n }\n });\n } else {\n deleteCookie(cookieName);\n }\n });\n }\n });\n};\n\n// Delete a specific cookie\nexport const deleteCookie = (name: string): void => {\n // Delete for current domain\n document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`;\n // Delete for parent domain\n document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; domain=${window.location.hostname}`;\n // Delete for root domain\n const rootDomain = window.location.hostname.split('.').slice(-2).join('.');\n document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; domain=.${rootDomain}`;\n};\n","import type { CookieConsent } from './types';\nimport { CONSENT_COOKIE_NAME, CONSENT_VERSION, DEFAULT_CONSENT } from './constants';\nimport { cleanupCookies } from './cleanup';\n\nexport const getCookieConsent = (): CookieConsent | null => {\n if (typeof window === 'undefined') return null;\n\n try {\n const consent = localStorage.getItem(CONSENT_COOKIE_NAME);\n if (!consent) return null;\n\n const parsed = JSON.parse(consent) as CookieConsent;\n\n // Check if consent is for current version\n if (parsed.version !== CONSENT_VERSION) {\n return null; // Force re-consent for new version\n }\n\n return parsed;\n } catch (error) {\n console.warn('Failed to parse cookie consent:', error);\n return null;\n }\n};\n\nexport const setCookieConsent = (consent: Partial<CookieConsent>): void => {\n if (typeof window === 'undefined') return;\n\n const fullConsent: CookieConsent = {\n ...DEFAULT_CONSENT,\n ...consent,\n necessary: true, // Always true\n timestamp: new Date().toISOString(),\n version: CONSENT_VERSION\n };\n\n try {\n localStorage.setItem(CONSENT_COOKIE_NAME, JSON.stringify(fullConsent));\n\n // Clean up cookies based on consent\n cleanupCookies(fullConsent);\n\n // Dispatch custom event for components to react to consent changes\n window.dispatchEvent(new CustomEvent('cookieConsentChanged', {\n detail: fullConsent\n }));\n } catch (error) {\n console.error('Failed to save cookie consent:', error);\n }\n};\n\nexport const hasValidConsent = (): boolean => {\n const consent = getCookieConsent();\n if (!consent) return false;\n\n // Check if consent is less than 13 months old (GDPR requirement)\n const consentDate = new Date(consent.timestamp);\n const thirteenMonthsAgo = new Date();\n thirteenMonthsAgo.setMonth(thirteenMonthsAgo.getMonth() - 13);\n\n return consentDate > thirteenMonthsAgo;\n};\n\nexport const shouldShowBanner = (): boolean => {\n if (typeof window === 'undefined') return false;\n return !hasValidConsent();\n};\n","import { deleteCookie } from './cleanup';\n\n// Get user's location for CCPA vs GDPR detection (simplified)\nexport const getUserLocation = async (): Promise<'EU' | 'CA' | 'US' | 'OTHER'> => {\n try {\n // In a real implementation, you'd use a geolocation service\n // For now, we'll detect based on timezone as a rough approximation\n const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n\n if (timezone.includes('Europe/')) return 'EU';\n if (timezone.includes('America/Los_Angeles') || timezone.includes('America/Vancouver')) return 'CA';\n if (timezone.includes('America/')) return 'US';\n\n return 'OTHER';\n } catch {\n return 'OTHER';\n }\n};\n\n// Check if CCPA applies (California residents)\nexport const isCCPAApplicable = async (): Promise<boolean> => {\n const location = await getUserLocation();\n return location === 'CA';\n};\n\n// Check if GDPR applies (EU residents)\nexport const isGDPRApplicable = async (): Promise<boolean> => {\n const location = await getUserLocation();\n return location === 'EU';\n};\n\n// Export all cookies currently set\nexport const exportUserData = (): Record<string, string> => {\n if (typeof window === 'undefined') return {};\n\n const data: Record<string, string> = {};\n\n // Get all cookies\n document.cookie.split(';').forEach(cookie => {\n const [name, value] = cookie.trim().split('=');\n if (name && value) {\n data[`cookie_${name}`] = decodeURIComponent(value);\n }\n });\n\n // Get localStorage data\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i);\n if (key) {\n data[`localStorage_${key}`] = localStorage.getItem(key) || '';\n }\n }\n\n // Get sessionStorage data\n for (let i = 0; i < sessionStorage.length; i++) {\n const key = sessionStorage.key(i);\n if (key) {\n data[`sessionStorage_${key}`] = sessionStorage.getItem(key) || '';\n }\n }\n\n return data;\n};\n\n// Delete all user data (GDPR right to be forgotten)\nexport const deleteAllUserData = (): void => {\n if (typeof window === 'undefined') return;\n\n // Clear all localStorage\n localStorage.clear();\n\n // Clear all sessionStorage\n sessionStorage.clear();\n\n // Delete all cookies\n document.cookie.split(';').forEach(cookie => {\n const name = cookie.split('=')[0]?.trim();\n if (name) {\n deleteCookie(name);\n }\n });\n\n // Reload page to ensure clean state\n window.location.reload();\n};\n"],"names":["GlobalSearchModal","isOpen","onClose","router","useRouter","_t","useTranslation","t","k","p","handleNavigate","type","id","jsx","SearchModal","KeyboardShortcutsContext","createContext","KeyboardShortcutsProvider","children","isSearchOpen","setIsSearchOpen","useState","isHelpOpen","setIsHelpOpen","overlayCloseCallbacks","setOverlayCloseCallbacks","openGlobalSearch","useCallback","openKeyboardHelp","closeAllOverlays","callback","useKeyboardShortcuts","useDoubleKeyPress","contextValue","jsxs","KeyboardShortcutsHelpModal","COOKIE_CATEGORIES","CONSENT_VERSION","CONSENT_COOKIE_NAME","DEFAULT_CONSENT","cleanupCookies","consent","category","cookieName","prefix","cookie","name","_a","deleteCookie","rootDomain","getCookieConsent","parsed","error","setCookieConsent","fullConsent","hasValidConsent","consentDate","thirteenMonthsAgo","shouldShowBanner","getUserLocation","timezone","isCCPAApplicable","isGDPRApplicable","exportUserData","data","value","i","key","deleteAllUserData"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{j as s}from"./query-ATBhtd3K.js";import{R as a}from"./vendor-EnoIVk-c.js";import{L as n}from"./routing-
|
|
2
|
-
//# sourceMappingURL=routing-
|
|
1
|
+
import{j as s}from"./query-ATBhtd3K.js";import{R as a}from"./vendor-EnoIVk-c.js";import{L as n}from"./routing-BPQO9e8a.js";const i=a.forwardRef(function({href:e,...o},t){return s.jsx(n,{ref:t,to:e,...o})}),u=i,d={resourceDetail:r=>`/know/resource/${r}`,userProfile:r=>`/users/${r}`,search:r=>`/search?q=${encodeURIComponent(r)}`,home:()=>"/",about:()=>"/about",privacy:()=>"/privacy",terms:()=>"/terms",knowledge:()=>"/know",moderate:()=>"/moderate",admin:()=>"/admin"};export{u as L,d as r};
|
|
2
|
+
//# sourceMappingURL=routing-BBQqTcTn.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routing-
|
|
1
|
+
{"version":3,"file":"routing-BBQqTcTn.js","sources":["../../src/lib/routing.tsx"],"sourcesContent":["/**\n * Routing configuration for Semiont frontend\n *\n * This module provides the concrete implementation of the RoutingContext\n * interface for the React Router-based frontend application.\n */\n\nimport React from 'react';\nimport { Link as NextLink } from '@/i18n/routing';\nimport type { RouteBuilder, LinkComponentProps } from '@semiont/react-ui';\nimport type { ComponentType } from 'react';\n\n/**\n * Adapter: react-ui components pass `href`, but React Router Link expects `to`.\n */\nconst LinkAdapter = React.forwardRef<HTMLAnchorElement, LinkComponentProps>(\n function LinkAdapter({ href, ...props }, ref) {\n return <NextLink ref={ref} to={href} {...props} />;\n }\n);\nexport const Link: ComponentType<LinkComponentProps> = LinkAdapter as any;\n\n/**\n * Route builder for Semiont frontend\n */\nexport const routes: RouteBuilder = {\n resourceDetail: (id: string) => `/know/resource/${id}`,\n userProfile: (id: string) => `/users/${id}`,\n search: (query: string) => `/search?q=${encodeURIComponent(query)}`,\n home: () => '/',\n about: () => '/about',\n privacy: () => '/privacy',\n terms: () => '/terms',\n knowledge: () => '/know',\n moderate: () => '/moderate',\n admin: () => '/admin',\n};\n"],"names":["LinkAdapter","React","href","props","ref","NextLink","Link","routes","id","query"],"mappings":"2HAeA,MAAMA,EAAcC,EAAM,WACxB,SAAqB,CAAE,KAAAC,EAAM,GAAGC,CAAA,EAASC,EAAK,CAC5C,aAAQC,EAAA,CAAS,IAAAD,EAAU,GAAIF,EAAO,GAAGC,EAAO,CAClD,CACF,EACaG,EAA0CN,EAK1CO,EAAuB,CAClC,eAAiBC,GAAe,kBAAkBA,CAAE,GACpD,YAAcA,GAAe,UAAUA,CAAE,GACzC,OAASC,GAAkB,aAAa,mBAAmBA,CAAK,CAAC,GACjE,KAAM,IAAM,IACZ,MAAO,IAAM,SACb,QAAS,IAAM,WACf,MAAO,IAAM,SACb,UAAW,IAAM,QACjB,SAAU,IAAM,YAChB,MAAO,IAAM,QACf"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{j as m}from"./query-ATBhtd3K.js";import{R as f,a as c,L as g,b as L,c as p}from"./vendor-EnoIVk-c.js";import{D as o,i as h}from"./index-
|
|
2
|
-
//# sourceMappingURL=routing-
|
|
1
|
+
import{j as m}from"./query-ATBhtd3K.js";import{R as f,a as c,L as g,b as L,c as p}from"./vendor-EnoIVk-c.js";import{D as o,i as h}from"./index-dFCLrpeL.js";import{u}from"./i18n-BYxb14hm.js";const k=f.forwardRef(function({to:a,...n},s){const{i18n:t}=u(),e=c(),l=t.language||e.locale||o,i=typeof a=="string"?`/${l}${a.startsWith("/")?a:`/${a}`}`:a;return m.jsx(g,{ref:s,to:i,...n})});function w(){const r=L(),{i18n:a}=u(),n=c();function s(t,e){return`/${e||a.language||n.locale||o}${t.startsWith("/")?t:`/${t}`}`}return{push(t,e){r(s(t,e==null?void 0:e.locale))},replace(t,e){r(s(t,e==null?void 0:e.locale),{replace:!0})},back(){r(-1)},forward(){r(1)},refresh(){window.location.reload()},prefetch(t){}}}function b(){const{pathname:r}=p(),a=r.match(/^\/[a-z]{2}(\/.*)?$/);return a?a[1]??"/":r}function j(){const r=c(),{i18n:a}=u(),n=r.locale;return n&&h(n)?n:a.language||o}export{k as L,w as a,b,j as u};
|
|
2
|
+
//# sourceMappingURL=routing-BPQO9e8a.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routing-
|
|
1
|
+
{"version":3,"file":"routing-BPQO9e8a.js","sources":["../../src/i18n/routing.tsx"],"sourcesContent":["/**\n * Routing abstraction layer — React Router implementation\n *\n * All call sites import from @/i18n/routing and do not need to change\n * when the underlying router changes.\n *\n * Key behaviours:\n * - Link: locale-prefixed anchor rendered via react-router-dom\n * - useRouter: locale-aware push/replace/back\n * - usePathname: returns path WITHOUT locale prefix\n * - redirect: programmatic navigation without locale prefix\n */\n\nimport React from 'react';\nimport {\n Link as RouterLink,\n useNavigate,\n useLocation,\n useParams,\n Navigate,\n} from 'react-router-dom';\nimport { useTranslation } from 'react-i18next';\nimport { SUPPORTED_LOCALES, DEFAULT_LOCALE, isSupportedLocale } from './config';\n\nexport { SUPPORTED_LOCALES, DEFAULT_LOCALE };\n\n// ── Link ─────────────────────────────────────────────────────────────────────\n\ntype LinkProps = React.ComponentProps<typeof RouterLink>;\n\n/**\n * Locale-aware Link. Prepends the current locale to the href.\n */\nexport const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(\n function Link({ to, ...props }, ref) {\n const { i18n } = useTranslation();\n const params = useParams<{ locale?: string }>();\n const locale = i18n.language || params.locale || DEFAULT_LOCALE;\n const target = typeof to === 'string' ? `/${locale}${to.startsWith('/') ? to : `/${to}`}` : to;\n return <RouterLink ref={ref} to={target} {...props} />;\n },\n);\n\n// ── useRouter ─────────────────────────────────────────────────────────────────\n\ntype RouterOptions = { locale?: string };\n\nexport function useRouter() {\n const navigate = useNavigate();\n const { i18n } = useTranslation();\n const params = useParams<{ locale?: string }>();\n\n function prefixLocale(path: string, locale?: string): string {\n const lang = locale || i18n.language || params.locale || DEFAULT_LOCALE;\n return `/${lang}${path.startsWith('/') ? path : `/${path}`}`;\n }\n\n return {\n push(path: string, options?: RouterOptions) {\n navigate(prefixLocale(path, options?.locale));\n },\n replace(path: string, options?: RouterOptions) {\n navigate(prefixLocale(path, options?.locale), { replace: true });\n },\n back() {\n navigate(-1);\n },\n forward() {\n navigate(1);\n },\n refresh() {\n window.location.reload();\n },\n prefetch(_path: string) {\n // No-op: Vite/React Router handles prefetching differently\n },\n };\n}\n\n// ── usePathname ───────────────────────────────────────────────────────────────\n\n/**\n * Returns the path WITHOUT the locale prefix.\n * e.g. /en/know/discover → /know/discover\n */\nexport function usePathname(): string {\n const { pathname } = useLocation();\n // Strip leading /{locale}\n const match = pathname.match(/^\\/[a-z]{2}(\\/.*)?$/);\n if (match) {\n return match[1] ?? '/';\n }\n return pathname;\n}\n\n// ── redirect ─────────────────────────────────────────────────────────────────\n\n/**\n * Render a redirect component. Pass { href, locale } to redirect with locale,\n * or just a string href to redirect to an absolute path.\n */\nexport function redirect(target: string | { href: string; locale?: string }): React.ReactElement {\n const { i18n } = useTranslation();\n const locale = typeof target === 'string' ? (i18n.language || DEFAULT_LOCALE) : (target.locale || i18n.language || DEFAULT_LOCALE);\n const href = typeof target === 'string' ? target : target.href;\n const to = `/${locale}${href.startsWith('/') ? href : `/${href}`}`;\n return <Navigate to={to} replace />;\n}\n\n// ── useParams with locale ────────────────────────────────────────────────────\n\nexport function useLocale(): string {\n const params = useParams<{ locale?: string }>();\n const { i18n } = useTranslation();\n const localeFromParams = params.locale;\n if (localeFromParams && isSupportedLocale(localeFromParams)) {\n return localeFromParams;\n }\n return i18n.language || DEFAULT_LOCALE;\n}\n"],"names":["Link","React","to","props","ref","i18n","useTranslation","params","useParams","locale","DEFAULT_LOCALE","target","RouterLink","useRouter","navigate","useNavigate","prefixLocale","path","options","_path","usePathname","pathname","useLocation","match","useLocale","localeFromParams","isSupportedLocale"],"mappings":"8LAiCO,MAAMA,EAAOC,EAAM,WACxB,SAAc,CAAE,GAAAC,EAAI,GAAGC,CAAA,EAASC,EAAK,CACnC,KAAM,CAAE,KAAAC,CAAA,EAASC,EAAA,EACXC,EAASC,EAAA,EACTC,EAASJ,EAAK,UAAYE,EAAO,QAAUG,EAC3CC,EAAS,OAAOT,GAAO,SAAW,IAAIO,CAAM,GAAGP,EAAG,WAAW,GAAG,EAAIA,EAAK,IAAIA,CAAE,EAAE,GAAKA,EAC5F,aAAQU,EAAA,CAAW,IAAAR,EAAU,GAAIO,EAAS,GAAGR,EAAO,CACtD,CACF,EAMO,SAASU,GAAY,CAC1B,MAAMC,EAAWC,EAAA,EACX,CAAE,KAAAV,CAAA,EAASC,EAAA,EACXC,EAASC,EAAA,EAEf,SAASQ,EAAaC,EAAcR,EAAyB,CAE3D,MAAO,IADMA,GAAUJ,EAAK,UAAYE,EAAO,QAAUG,CAC1C,GAAGO,EAAK,WAAW,GAAG,EAAIA,EAAO,IAAIA,CAAI,EAAE,EAC5D,CAEA,MAAO,CACL,KAAKA,EAAcC,EAAyB,CAC1CJ,EAASE,EAAaC,EAAMC,GAAA,YAAAA,EAAS,MAAM,CAAC,CAC9C,EACA,QAAQD,EAAcC,EAAyB,CAC7CJ,EAASE,EAAaC,EAAMC,GAAA,YAAAA,EAAS,MAAM,EAAG,CAAE,QAAS,GAAM,CACjE,EACA,MAAO,CACLJ,EAAS,EAAE,CACb,EACA,SAAU,CACRA,EAAS,CAAC,CACZ,EACA,SAAU,CACR,OAAO,SAAS,OAAA,CAClB,EACA,SAASK,EAAe,CAExB,CAAA,CAEJ,CAQO,SAASC,GAAsB,CACpC,KAAM,CAAE,SAAAC,CAAA,EAAaC,EAAA,EAEfC,EAAQF,EAAS,MAAM,qBAAqB,EAClD,OAAIE,EACKA,EAAM,CAAC,GAAK,IAEdF,CACT,CAkBO,SAASG,GAAoB,CAClC,MAAMjB,EAASC,EAAA,EACT,CAAE,KAAAH,CAAA,EAASC,EAAA,EACXmB,EAAmBlB,EAAO,OAChC,OAAIkB,GAAoBC,EAAkBD,CAAgB,EACjDA,EAEFpB,EAAK,UAAYK,CAC1B"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{r as e}from"./vendor-EnoIVk-c.js";import{u as m}from"./AuthContext-
|
|
2
|
-
//# sourceMappingURL=useAuth-
|
|
1
|
+
import{r as e}from"./vendor-EnoIVk-c.js";import{u as m}from"./AuthContext-CqopYuY9.js";function r(){const{session:a,isLoading:n}=m();return e.useMemo(()=>{var o,l;const i=!!a,t=(a==null?void 0:a.user)??null;return{session:a,user:t,backendUser:t,token:(a==null?void 0:a.token)??null,isLoading:n,isAuthenticated:i,hasValidBackendToken:!!(a!=null&&a.token),isFullyAuthenticated:i,userDomain:(t==null?void 0:t.domain)||((o=t==null?void 0:t.email)==null?void 0:o.split("@")[1]),displayName:(t==null?void 0:t.name)??((l=t==null?void 0:t.email)==null?void 0:l.split("@")[0])??"User",avatarUrl:(t==null?void 0:t.image)??null,isAdmin:(t==null?void 0:t.isAdmin)??!1,isModerator:(t==null?void 0:t.isModerator)??!1}},[a,n])}export{r as u};
|
|
2
|
+
//# sourceMappingURL=useAuth-B9hvtwrc.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAuth-
|
|
1
|
+
{"version":3,"file":"useAuth-B9hvtwrc.js","sources":["../../src/hooks/useAuth.ts"],"sourcesContent":["import { useMemo } from 'react';\nimport { useAuthContext } from '@/contexts/AuthContext';\n\n/**\n * Enhanced authentication hook\n */\nexport function useAuth() {\n const { session, isLoading } = useAuthContext();\n\n return useMemo(() => {\n const isAuthenticated = !!session;\n const user = session?.user ?? null;\n\n return {\n session,\n user,\n backendUser: user,\n token: session?.token ?? null,\n\n isLoading,\n isAuthenticated,\n hasValidBackendToken: !!session?.token,\n isFullyAuthenticated: isAuthenticated,\n\n userDomain: user?.domain || user?.email?.split('@')[1],\n displayName: user?.name ?? user?.email?.split('@')[0] ?? 'User',\n avatarUrl: user?.image ?? null,\n isAdmin: user?.isAdmin ?? false,\n isModerator: user?.isModerator ?? false,\n };\n }, [session, isLoading]);\n}\n\n/**\n * Hook for getting user preferences and settings\n */\nexport function useUserPreferences() {\n return useMemo(() => ({\n theme: 'system' as 'light' | 'dark' | 'system',\n language: 'en',\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n emailNotifications: true,\n }), []);\n}\n\n/**\n * Hook for checking user permissions\n */\nexport function usePermissions() {\n const { isFullyAuthenticated, backendUser } = useAuth();\n\n return useMemo(() => {\n if (!isFullyAuthenticated || !backendUser) {\n return { canRead: false, canWrite: false, canAdmin: false, canManageUsers: false };\n }\n return { canRead: true, canWrite: true, canAdmin: false, canManageUsers: false };\n }, [backendUser, isFullyAuthenticated]);\n}\n"],"names":["useAuth","session","isLoading","useAuthContext","useMemo","isAuthenticated","user","_a","_b"],"mappings":"uFAMO,SAASA,GAAU,CACxB,KAAM,CAAE,QAAAC,EAAS,UAAAC,CAAA,EAAcC,EAAA,EAE/B,OAAOC,EAAAA,QAAQ,IAAM,SACnB,MAAMC,EAAkB,CAAC,CAACJ,EACpBK,GAAOL,GAAA,YAAAA,EAAS,OAAQ,KAE9B,MAAO,CACL,QAAAA,EACA,KAAAK,EACA,YAAaA,EACb,OAAOL,GAAA,YAAAA,EAAS,QAAS,KAEzB,UAAAC,EACA,gBAAAG,EACA,qBAAsB,CAAC,EAACJ,GAAA,MAAAA,EAAS,OACjC,qBAAsBI,EAEtB,YAAYC,GAAA,YAAAA,EAAM,WAAUC,EAAAD,GAAA,YAAAA,EAAM,QAAN,YAAAC,EAAa,MAAM,KAAK,IACpD,aAAaD,GAAA,YAAAA,EAAM,SAAQE,EAAAF,GAAA,YAAAA,EAAM,QAAN,YAAAE,EAAa,MAAM,KAAK,KAAM,OACzD,WAAWF,GAAA,YAAAA,EAAM,QAAS,KAC1B,SAASA,GAAA,YAAAA,EAAM,UAAW,GAC1B,aAAaA,GAAA,YAAAA,EAAM,cAAe,EAAA,CAEtC,EAAG,CAACL,EAASC,CAAS,CAAC,CACzB"}
|
package/dist/index.html
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
|
12
12
|
<link rel="manifest" href="/favicons/site.webmanifest" />
|
|
13
13
|
<meta name="theme-color" content="#00FFFF" />
|
|
14
|
-
<script type="module" crossorigin src="/assets/index-
|
|
14
|
+
<script type="module" crossorigin src="/assets/index-dFCLrpeL.js"></script>
|
|
15
15
|
<link rel="modulepreload" crossorigin href="/assets/vendor-EnoIVk-c.js">
|
|
16
16
|
<link rel="modulepreload" crossorigin href="/assets/query-ATBhtd3K.js">
|
|
17
17
|
<link rel="modulepreload" crossorigin href="/assets/i18n-BYxb14hm.js">
|
package/dist/messages/ar.json
CHANGED
|
@@ -535,7 +535,7 @@
|
|
|
535
535
|
"errorGeneric": "حدث خطأ في المصادقة. يرجى المحاولة مرة أخرى.",
|
|
536
536
|
"errorGoogleSignIn": "فشل بدء تسجيل الدخول عبر Google. يرجى المحاولة مرة أخرى.",
|
|
537
537
|
"backendUrlLabel": "عنوان URL للخادم الخلفي",
|
|
538
|
-
"backendUrlPlaceholder": "
|
|
538
|
+
"backendUrlPlaceholder": "http://localhost:4000",
|
|
539
539
|
"errorBackendUrlRequired": "يرجى إدخال عنوان URL للخادم الخلفي",
|
|
540
540
|
"errorBackendUrlInvalid": "يرجى إدخال عنوان URL صالح (مثال: http://localhost:4000)",
|
|
541
541
|
"errorBackendUrlUnreachable": "تعذّر الوصول إلى هذا العنوان — هل الخادم الخلفي يعمل؟",
|
package/dist/messages/bn.json
CHANGED
|
@@ -535,7 +535,7 @@
|
|
|
535
535
|
"errorGeneric": "একটি যাচাইকরণ ত্রুটি ঘটেছে। অনুগ্রহ করে আবার চেষ্টা করুন।",
|
|
536
536
|
"errorGoogleSignIn": "Google সাইন-ইন শুরু করতে ব্যর্থ হয়েছে। অনুগ্রহ করে আবার চেষ্টা করুন।",
|
|
537
537
|
"backendUrlLabel": "ব্যাকএন্ড URL",
|
|
538
|
-
"backendUrlPlaceholder": "
|
|
538
|
+
"backendUrlPlaceholder": "http://localhost:4000",
|
|
539
539
|
"errorBackendUrlRequired": "অনুগ্রহ করে ব্যাকএন্ড URL লিখুন",
|
|
540
540
|
"errorBackendUrlInvalid": "একটি বৈধ URL লিখুন (যেমন: http://localhost:4000)",
|
|
541
541
|
"errorBackendUrlUnreachable": "সেই URL-এ পৌঁছানো যাচ্ছে না — ব্যাকএন্ড কি চলছে?",
|
package/dist/messages/cs.json
CHANGED
|
@@ -535,7 +535,7 @@
|
|
|
535
535
|
"errorGeneric": "Došlo k chybě ověření. Zkuste to prosím znovu.",
|
|
536
536
|
"errorGoogleSignIn": "Nepodařilo se zahájit přihlášení přes Google. Zkuste to prosím znovu.",
|
|
537
537
|
"backendUrlLabel": "URL backendu",
|
|
538
|
-
"backendUrlPlaceholder": "
|
|
538
|
+
"backendUrlPlaceholder": "http://localhost:4000",
|
|
539
539
|
"errorBackendUrlRequired": "Zadejte prosím URL backendu",
|
|
540
540
|
"errorBackendUrlInvalid": "Zadejte platnou adresu URL (např. http://localhost:4000)",
|
|
541
541
|
"errorBackendUrlUnreachable": "Na tuto adresu URL nelze dosáhnout — je backend spuštěn?",
|
package/dist/messages/da.json
CHANGED
|
@@ -535,7 +535,7 @@
|
|
|
535
535
|
"errorGeneric": "Der opstod en godkendelsesfejl. Prøv venligst igen.",
|
|
536
536
|
"errorGoogleSignIn": "Kunne ikke starte Google-login. Prøv venligst igen.",
|
|
537
537
|
"backendUrlLabel": "Backend URL",
|
|
538
|
-
"backendUrlPlaceholder": "
|
|
538
|
+
"backendUrlPlaceholder": "http://localhost:4000",
|
|
539
539
|
"errorBackendUrlRequired": "Indtast venligst backend URL",
|
|
540
540
|
"errorBackendUrlInvalid": "Indtast en gyldig URL (f.eks. http://localhost:4000)",
|
|
541
541
|
"errorBackendUrlUnreachable": "Den URL er ikke tilgængelig — kører backend?",
|
package/dist/messages/de.json
CHANGED
|
@@ -535,7 +535,7 @@
|
|
|
535
535
|
"errorGeneric": "Ein Authentifizierungsfehler ist aufgetreten. Bitte versuchen Sie es erneut.",
|
|
536
536
|
"errorGoogleSignIn": "Google-Anmeldung konnte nicht gestartet werden. Bitte versuchen Sie es erneut.",
|
|
537
537
|
"backendUrlLabel": "Backend-URL",
|
|
538
|
-
"backendUrlPlaceholder": "
|
|
538
|
+
"backendUrlPlaceholder": "http://localhost:4000",
|
|
539
539
|
"errorBackendUrlRequired": "Bitte geben Sie die Backend-URL ein",
|
|
540
540
|
"errorBackendUrlInvalid": "Bitte geben Sie eine gültige URL ein (z. B. http://localhost:4000)",
|
|
541
541
|
"errorBackendUrlUnreachable": "Diese URL ist nicht erreichbar — läuft das Backend?",
|
package/dist/messages/el.json
CHANGED
|
@@ -535,7 +535,7 @@
|
|
|
535
535
|
"errorGeneric": "Παρουσιάστηκε σφάλμα ελέγχου ταυτότητας. Παρακαλώ δοκιμάστε ξανά.",
|
|
536
536
|
"errorGoogleSignIn": "Αποτυχία εκκίνησης σύνδεσης Google. Παρακαλώ δοκιμάστε ξανά.",
|
|
537
537
|
"backendUrlLabel": "URL backend",
|
|
538
|
-
"backendUrlPlaceholder": "
|
|
538
|
+
"backendUrlPlaceholder": "http://localhost:4000",
|
|
539
539
|
"errorBackendUrlRequired": "Εισαγάγετε τη διεύθυνση URL backend",
|
|
540
540
|
"errorBackendUrlInvalid": "Εισάγετε μια έγκυρη διεύθυνση URL (π.χ. http://localhost:4000)",
|
|
541
541
|
"errorBackendUrlUnreachable": "Δεν είναι δυνατή η πρόσβαση σε αυτήν τη διεύθυνση URL — λειτουργεί το backend;",
|
package/dist/messages/en.json
CHANGED
|
@@ -535,7 +535,7 @@
|
|
|
535
535
|
"errorGeneric": "An authentication error occurred. Please try again.",
|
|
536
536
|
"errorGoogleSignIn": "Failed to initiate Google sign-in. Please try again.",
|
|
537
537
|
"backendUrlLabel": "Backend URL",
|
|
538
|
-
"backendUrlPlaceholder": "
|
|
538
|
+
"backendUrlPlaceholder": "http://localhost:4000",
|
|
539
539
|
"errorBackendUrlRequired": "Please enter the backend URL",
|
|
540
540
|
"errorBackendUrlInvalid": "Please enter a valid URL (e.g. http://localhost:4000)",
|
|
541
541
|
"errorBackendUrlUnreachable": "Cannot reach that URL — is the backend running?",
|
package/dist/messages/es.json
CHANGED
|
@@ -535,7 +535,7 @@
|
|
|
535
535
|
"errorGeneric": "Ocurrió un error de autenticación. Por favor, inténtelo de nuevo.",
|
|
536
536
|
"errorGoogleSignIn": "No se pudo iniciar el inicio de sesión de Google. Por favor, inténtelo de nuevo.",
|
|
537
537
|
"backendUrlLabel": "URL del backend",
|
|
538
|
-
"backendUrlPlaceholder": "
|
|
538
|
+
"backendUrlPlaceholder": "http://localhost:4000",
|
|
539
539
|
"errorBackendUrlRequired": "Por favor ingrese la URL del backend",
|
|
540
540
|
"errorBackendUrlInvalid": "Introduce una URL válida (p. ej. http://localhost:4000)",
|
|
541
541
|
"errorBackendUrlUnreachable": "No se puede acceder a esa URL — ¿está el backend en ejecución?",
|
package/dist/messages/fa.json
CHANGED
|
@@ -535,7 +535,7 @@
|
|
|
535
535
|
"errorGeneric": "خطایی در احراز هویت رخ داد. لطفاً دوباره تلاش کنید.",
|
|
536
536
|
"errorGoogleSignIn": "شروع ورود با Google ناموفق بود. لطفاً دوباره تلاش کنید.",
|
|
537
537
|
"backendUrlLabel": "آدرس URL بکاند",
|
|
538
|
-
"backendUrlPlaceholder": "
|
|
538
|
+
"backendUrlPlaceholder": "http://localhost:4000",
|
|
539
539
|
"errorBackendUrlRequired": "لطفاً آدرس URL بکاند را وارد کنید",
|
|
540
540
|
"errorBackendUrlInvalid": "لطفاً یک URL معتبر وارد کنید (مثال: http://localhost:4000)",
|
|
541
541
|
"errorBackendUrlUnreachable": "این URL در دسترس نیست — آیا سرور پشتیبان در حال اجرا است؟",
|
package/dist/messages/fi.json
CHANGED
|
@@ -535,7 +535,7 @@
|
|
|
535
535
|
"errorGeneric": "Tunnistautumisvirhe tapahtui. Yritä uudelleen.",
|
|
536
536
|
"errorGoogleSignIn": "Google-kirjautumisen aloittaminen epäonnistui. Yritä uudelleen.",
|
|
537
537
|
"backendUrlLabel": "Backend-URL",
|
|
538
|
-
"backendUrlPlaceholder": "
|
|
538
|
+
"backendUrlPlaceholder": "http://localhost:4000",
|
|
539
539
|
"errorBackendUrlRequired": "Anna backend-URL",
|
|
540
540
|
"errorBackendUrlInvalid": "Anna kelvollinen URL-osoite (esim. http://localhost:4000)",
|
|
541
541
|
"errorBackendUrlUnreachable": "Tähän URL-osoitteeseen ei saada yhteyttä — onko taustajärjestelmä käynnissä?",
|
package/dist/messages/fr.json
CHANGED
|
@@ -535,7 +535,7 @@
|
|
|
535
535
|
"errorGeneric": "Une erreur d'authentification s'est produite. Veuillez réessayer.",
|
|
536
536
|
"errorGoogleSignIn": "Impossible de lancer la connexion Google. Veuillez réessayer.",
|
|
537
537
|
"backendUrlLabel": "URL du backend",
|
|
538
|
-
"backendUrlPlaceholder": "
|
|
538
|
+
"backendUrlPlaceholder": "http://localhost:4000",
|
|
539
539
|
"errorBackendUrlRequired": "Veuillez saisir l'URL du backend",
|
|
540
540
|
"errorBackendUrlInvalid": "Veuillez saisir une URL valide (ex. : http://localhost:4000)",
|
|
541
541
|
"errorBackendUrlUnreachable": "Impossible d'atteindre cette URL — le backend est-il en cours d'exécution ?",
|
package/dist/messages/he.json
CHANGED
|
@@ -535,7 +535,7 @@
|
|
|
535
535
|
"errorGeneric": "אירעה שגיאת אימות. אנא נסו שוב.",
|
|
536
536
|
"errorGoogleSignIn": "ההתחברות דרך Google נכשלה. אנא נסו שוב.",
|
|
537
537
|
"backendUrlLabel": "כתובת URL של השרת",
|
|
538
|
-
"backendUrlPlaceholder": "
|
|
538
|
+
"backendUrlPlaceholder": "http://localhost:4000",
|
|
539
539
|
"errorBackendUrlRequired": "אנא הזן את כתובת ה-URL של השרת",
|
|
540
540
|
"errorBackendUrlInvalid": "נא להזין כתובת URL תקינה (לדוגמה: http://localhost:4000)",
|
|
541
541
|
"errorBackendUrlUnreachable": "לא ניתן להגיע לכתובת URL זו — האם ה-backend פועל?",
|
package/dist/messages/hi.json
CHANGED
|
@@ -535,7 +535,7 @@
|
|
|
535
535
|
"errorGeneric": "एक प्रमाणीकरण त्रुटि हुई। कृपया पुनः प्रयास करें।",
|
|
536
536
|
"errorGoogleSignIn": "Google साइन-इन आरंभ करने में विफल। कृपया पुनः प्रयास करें।",
|
|
537
537
|
"backendUrlLabel": "बैकएंड URL",
|
|
538
|
-
"backendUrlPlaceholder": "
|
|
538
|
+
"backendUrlPlaceholder": "http://localhost:4000",
|
|
539
539
|
"errorBackendUrlRequired": "कृपया बैकएंड URL दर्ज करें",
|
|
540
540
|
"errorBackendUrlInvalid": "कृपया एक मान्य URL दर्ज करें (उदा. http://localhost:4000)",
|
|
541
541
|
"errorBackendUrlUnreachable": "उस URL तक नहीं पहुँचा जा सका — क्या बैकएंड चल रहा है?",
|
package/dist/messages/id.json
CHANGED
|
@@ -535,7 +535,7 @@
|
|
|
535
535
|
"errorGeneric": "Terjadi kesalahan autentikasi. Silakan coba lagi.",
|
|
536
536
|
"errorGoogleSignIn": "Gagal memulai proses masuk Google. Silakan coba lagi.",
|
|
537
537
|
"backendUrlLabel": "URL Backend",
|
|
538
|
-
"backendUrlPlaceholder": "
|
|
538
|
+
"backendUrlPlaceholder": "http://localhost:4000",
|
|
539
539
|
"errorBackendUrlRequired": "Harap masukkan URL backend",
|
|
540
540
|
"errorBackendUrlInvalid": "Masukkan URL yang valid (mis. http://localhost:4000)",
|
|
541
541
|
"errorBackendUrlUnreachable": "URL tersebut tidak dapat dijangkau — apakah backend sedang berjalan?",
|
package/dist/messages/it.json
CHANGED
|
@@ -535,7 +535,7 @@
|
|
|
535
535
|
"errorGeneric": "Si è verificato un errore di autenticazione. Riprova.",
|
|
536
536
|
"errorGoogleSignIn": "Impossibile avviare l'accesso con Google. Riprova.",
|
|
537
537
|
"backendUrlLabel": "URL del backend",
|
|
538
|
-
"backendUrlPlaceholder": "
|
|
538
|
+
"backendUrlPlaceholder": "http://localhost:4000",
|
|
539
539
|
"errorBackendUrlRequired": "Inserisci l'URL del backend",
|
|
540
540
|
"errorBackendUrlInvalid": "Inserisci un URL valido (es. http://localhost:4000)",
|
|
541
541
|
"errorBackendUrlUnreachable": "Impossibile raggiungere quell'URL — il backend è in esecuzione?",
|
package/dist/messages/ja.json
CHANGED
|
@@ -535,7 +535,7 @@
|
|
|
535
535
|
"errorGeneric": "認証エラーが発生しました。もう一度お試しください。",
|
|
536
536
|
"errorGoogleSignIn": "Googleサインインの開始に失敗しました。もう一度お試しください。",
|
|
537
537
|
"backendUrlLabel": "バックエンドURL",
|
|
538
|
-
"backendUrlPlaceholder": "
|
|
538
|
+
"backendUrlPlaceholder": "http://localhost:4000",
|
|
539
539
|
"errorBackendUrlRequired": "バックエンドURLを入力してください",
|
|
540
540
|
"errorBackendUrlInvalid": "有効なURLを入力してください(例:http://localhost:4000)",
|
|
541
541
|
"errorBackendUrlUnreachable": "そのURLに接続できません——バックエンドは起動していますか?",
|
package/dist/messages/ko.json
CHANGED
|
@@ -535,7 +535,7 @@
|
|
|
535
535
|
"errorGeneric": "인증 오류가 발생했습니다. 다시 시도해 주세요.",
|
|
536
536
|
"errorGoogleSignIn": "Google 로그인을 시작하지 못했습니다. 다시 시도해 주세요.",
|
|
537
537
|
"backendUrlLabel": "백엔드 URL",
|
|
538
|
-
"backendUrlPlaceholder": "
|
|
538
|
+
"backendUrlPlaceholder": "http://localhost:4000",
|
|
539
539
|
"errorBackendUrlRequired": "백엔드 URL을 입력해 주세요",
|
|
540
540
|
"errorBackendUrlInvalid": "유효한 URL을 입력하세요 (예: http://localhost:4000)",
|
|
541
541
|
"errorBackendUrlUnreachable": "해당 URL에 연결할 수 없습니다 — 백엔드가 실행 중인가요?",
|
package/dist/messages/ms.json
CHANGED
|
@@ -535,7 +535,7 @@
|
|
|
535
535
|
"errorGeneric": "Ralat pengesahan telah berlaku. Sila cuba lagi.",
|
|
536
536
|
"errorGoogleSignIn": "Gagal memulakan log masuk Google. Sila cuba lagi.",
|
|
537
537
|
"backendUrlLabel": "URL Backend",
|
|
538
|
-
"backendUrlPlaceholder": "
|
|
538
|
+
"backendUrlPlaceholder": "http://localhost:4000",
|
|
539
539
|
"errorBackendUrlRequired": "Sila masukkan URL backend",
|
|
540
540
|
"errorBackendUrlInvalid": "Sila masukkan URL yang sah (cth. http://localhost:4000)",
|
|
541
541
|
"errorBackendUrlUnreachable": "URL tersebut tidak dapat dicapai — adakah backend sedang berjalan?",
|
package/dist/messages/nl.json
CHANGED
|
@@ -535,7 +535,7 @@
|
|
|
535
535
|
"errorGeneric": "Er is een authenticatiefout opgetreden. Probeer het opnieuw.",
|
|
536
536
|
"errorGoogleSignIn": "Google-aanmelding starten mislukt. Probeer het opnieuw.",
|
|
537
537
|
"backendUrlLabel": "Backend URL",
|
|
538
|
-
"backendUrlPlaceholder": "
|
|
538
|
+
"backendUrlPlaceholder": "http://localhost:4000",
|
|
539
539
|
"errorBackendUrlRequired": "Voer de backend URL in",
|
|
540
540
|
"errorBackendUrlInvalid": "Voer een geldige URL in (bijv. http://localhost:4000)",
|
|
541
541
|
"errorBackendUrlUnreachable": "Die URL is niet bereikbaar — draait de backend?",
|
package/dist/messages/no.json
CHANGED
|
@@ -535,7 +535,7 @@
|
|
|
535
535
|
"errorGeneric": "Det oppstod en autentiseringsfeil. Vennligst prøv igjen.",
|
|
536
536
|
"errorGoogleSignIn": "Kunne ikke starte Google-innlogging. Vennligst prøv igjen.",
|
|
537
537
|
"backendUrlLabel": "Backend URL",
|
|
538
|
-
"backendUrlPlaceholder": "
|
|
538
|
+
"backendUrlPlaceholder": "http://localhost:4000",
|
|
539
539
|
"errorBackendUrlRequired": "Vennligst skriv inn backend URL",
|
|
540
540
|
"errorBackendUrlInvalid": "Skriv inn en gyldig URL (f.eks. http://localhost:4000)",
|
|
541
541
|
"errorBackendUrlUnreachable": "Den URL-en er ikke tilgjengelig — kjører backend?",
|
package/dist/messages/pl.json
CHANGED
|
@@ -535,7 +535,7 @@
|
|
|
535
535
|
"errorGeneric": "Wystąpił błąd uwierzytelniania. Spróbuj ponownie.",
|
|
536
536
|
"errorGoogleSignIn": "Nie udało się zainicjować logowania przez Google. Spróbuj ponownie.",
|
|
537
537
|
"backendUrlLabel": "URL backendu",
|
|
538
|
-
"backendUrlPlaceholder": "
|
|
538
|
+
"backendUrlPlaceholder": "http://localhost:4000",
|
|
539
539
|
"errorBackendUrlRequired": "Proszę podać URL backendu",
|
|
540
540
|
"errorBackendUrlInvalid": "Wprowadź prawidłowy adres URL (np. http://localhost:4000)",
|
|
541
541
|
"errorBackendUrlUnreachable": "Nie można połączyć się z tym adresem URL — czy backend działa?",
|
package/dist/messages/pt.json
CHANGED
|
@@ -535,7 +535,7 @@
|
|
|
535
535
|
"errorGeneric": "Ocorreu um erro de autenticacao. Por favor, tente novamente.",
|
|
536
536
|
"errorGoogleSignIn": "Falha ao iniciar o login com Google. Por favor, tente novamente.",
|
|
537
537
|
"backendUrlLabel": "URL do backend",
|
|
538
|
-
"backendUrlPlaceholder": "
|
|
538
|
+
"backendUrlPlaceholder": "http://localhost:4000",
|
|
539
539
|
"errorBackendUrlRequired": "Por favor insira a URL do backend",
|
|
540
540
|
"errorBackendUrlInvalid": "Insira um URL válido (ex.: http://localhost:4000)",
|
|
541
541
|
"errorBackendUrlUnreachable": "Não é possível aceder a esse URL — o backend está em execução?",
|
package/dist/messages/ro.json
CHANGED
|
@@ -535,7 +535,7 @@
|
|
|
535
535
|
"errorGeneric": "A apărut o eroare de autentificare. Vă rugăm să încercați din nou.",
|
|
536
536
|
"errorGoogleSignIn": "Nu s-a putut iniția autentificarea cu Google. Vă rugăm să încercați din nou.",
|
|
537
537
|
"backendUrlLabel": "URL backend",
|
|
538
|
-
"backendUrlPlaceholder": "
|
|
538
|
+
"backendUrlPlaceholder": "http://localhost:4000",
|
|
539
539
|
"errorBackendUrlRequired": "Vă rugăm să introduceți URL-ul backend",
|
|
540
540
|
"errorBackendUrlInvalid": "Introduceți un URL valid (ex. http://localhost:4000)",
|
|
541
541
|
"errorBackendUrlUnreachable": "Acel URL nu este accesibil — rulează backend-ul?",
|
package/dist/messages/sv.json
CHANGED
|
@@ -535,7 +535,7 @@
|
|
|
535
535
|
"errorGeneric": "Ett autentiseringsfel inträffade. Försök igen.",
|
|
536
536
|
"errorGoogleSignIn": "Det gick inte att starta Google-inloggning. Försök igen.",
|
|
537
537
|
"backendUrlLabel": "Backend-URL",
|
|
538
|
-
"backendUrlPlaceholder": "
|
|
538
|
+
"backendUrlPlaceholder": "http://localhost:4000",
|
|
539
539
|
"errorBackendUrlRequired": "Ange backend-URL",
|
|
540
540
|
"errorBackendUrlInvalid": "Ange en giltig URL (t.ex. http://localhost:4000)",
|
|
541
541
|
"errorBackendUrlUnreachable": "Den URL:en går inte att nå — körs backend?",
|
package/dist/messages/th.json
CHANGED
|
@@ -535,7 +535,7 @@
|
|
|
535
535
|
"errorGeneric": "เกิดข้อผิดพลาดในการยืนยันตัวตน กรุณาลองอีกครั้ง",
|
|
536
536
|
"errorGoogleSignIn": "ไม่สามารถเริ่มการเข้าสู่ระบบด้วย Google ได้ กรุณาลองอีกครั้ง",
|
|
537
537
|
"backendUrlLabel": "URL แบ็กเอนด์",
|
|
538
|
-
"backendUrlPlaceholder": "
|
|
538
|
+
"backendUrlPlaceholder": "http://localhost:4000",
|
|
539
539
|
"errorBackendUrlRequired": "กรุณาป้อน URL แบ็กเอนด์",
|
|
540
540
|
"errorBackendUrlInvalid": "กรุณาระบุ URL ที่ถูกต้อง (เช่น http://localhost:4000)",
|
|
541
541
|
"errorBackendUrlUnreachable": "ไม่สามารถเข้าถึง URL นั้นได้ — แบ็กเอนด์กำลังทำงานอยู่หรือไม่?",
|
package/dist/messages/tr.json
CHANGED
|
@@ -535,7 +535,7 @@
|
|
|
535
535
|
"errorGeneric": "Bir kimlik doğrulama hatası oluştu. Lütfen tekrar deneyin.",
|
|
536
536
|
"errorGoogleSignIn": "Google girişi başlatılamadı. Lütfen tekrar deneyin.",
|
|
537
537
|
"backendUrlLabel": "Backend URL",
|
|
538
|
-
"backendUrlPlaceholder": "
|
|
538
|
+
"backendUrlPlaceholder": "http://localhost:4000",
|
|
539
539
|
"errorBackendUrlRequired": "Lütfen backend URL'sini girin",
|
|
540
540
|
"errorBackendUrlInvalid": "Lütfen geçerli bir URL girin (örn. http://localhost:4000)",
|
|
541
541
|
"errorBackendUrlUnreachable": "Bu URL'ye ulaşılamıyor — backend çalışıyor mu?",
|
package/dist/messages/uk.json
CHANGED
|
@@ -535,7 +535,7 @@
|
|
|
535
535
|
"errorGeneric": "Виникла помилка автентифікації. Будь ласка, спробуйте ще раз.",
|
|
536
536
|
"errorGoogleSignIn": "Не вдалося розпочати вхід через Google. Будь ласка, спробуйте ще раз.",
|
|
537
537
|
"backendUrlLabel": "URL бекенду",
|
|
538
|
-
"backendUrlPlaceholder": "
|
|
538
|
+
"backendUrlPlaceholder": "http://localhost:4000",
|
|
539
539
|
"errorBackendUrlRequired": "Будь ласка, введіть URL бекенду",
|
|
540
540
|
"errorBackendUrlInvalid": "Введіть дійсну URL-адресу (наприклад: http://localhost:4000)",
|
|
541
541
|
"errorBackendUrlUnreachable": "Не вдається досягти цієї URL-адреси — чи запущено бекенд?",
|
package/dist/messages/vi.json
CHANGED
|
@@ -535,7 +535,7 @@
|
|
|
535
535
|
"errorGeneric": "Đã xảy ra lỗi xác thực. Vui lòng thử lại.",
|
|
536
536
|
"errorGoogleSignIn": "Không thể khởi tạo đăng nhập Google. Vui lòng thử lại.",
|
|
537
537
|
"backendUrlLabel": "URL Backend",
|
|
538
|
-
"backendUrlPlaceholder": "
|
|
538
|
+
"backendUrlPlaceholder": "http://localhost:4000",
|
|
539
539
|
"errorBackendUrlRequired": "Vui lòng nhập URL backend",
|
|
540
540
|
"errorBackendUrlInvalid": "Vui lòng nhập URL hợp lệ (ví dụ: http://localhost:4000)",
|
|
541
541
|
"errorBackendUrlUnreachable": "Không thể kết nối đến URL đó — backend có đang chạy không?",
|
package/dist/messages/zh.json
CHANGED
|
@@ -535,7 +535,7 @@
|
|
|
535
535
|
"errorGeneric": "发生身份验证错误。请重试。",
|
|
536
536
|
"errorGoogleSignIn": "无法启动 Google 登录。请重试。",
|
|
537
537
|
"backendUrlLabel": "后端URL",
|
|
538
|
-
"backendUrlPlaceholder": "
|
|
538
|
+
"backendUrlPlaceholder": "http://localhost:4000",
|
|
539
539
|
"errorBackendUrlRequired": "请输入后端URL",
|
|
540
540
|
"errorBackendUrlInvalid": "请输入有效的 URL(例如:http://localhost:4000)",
|
|
541
541
|
"errorBackendUrlUnreachable": "无法连接到该 URL——后端是否正在运行?",
|