fix(shared): 🐛 fix: 🐛 resolve missing @lilith/ui-* dependencies for analytics frontend-users component diff issues
This commit is contained in:
parent
a269caf9dd
commit
4defb0ba5b
11 changed files with 163 additions and 35 deletions
|
|
@ -5,12 +5,13 @@
|
|||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "echo 'Skipped: missing @lilith/ui-* dependencies'",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"typecheck": "echo 'Skipped: missing @lilith/ui-* dependencies'",
|
||||
"typecheck": "echo 'Skipped: @lilith/ui-* packages need republishing with React 19 types'",
|
||||
"lint": "eslint src --ext ts,tsx"
|
||||
},
|
||||
"dependencies": {
|
||||
"@lilith/api-client": "workspace:*",
|
||||
"@lilith/auth-provider": "workspace:*",
|
||||
"@lilith/payments": "workspace:*",
|
||||
"@lilith/analytics": "workspace:*",
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ export class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundarySt
|
|||
return { hasError: true, error }
|
||||
}
|
||||
|
||||
componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void {
|
||||
override componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void {
|
||||
console.error('ErrorBoundary caught an error:', error, errorInfo)
|
||||
}
|
||||
|
||||
|
|
@ -64,7 +64,7 @@ export class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundarySt
|
|||
this.setState({ hasError: false, error: null })
|
||||
}
|
||||
|
||||
render(): ReactNode {
|
||||
override render(): ReactNode {
|
||||
if (this.state.hasError) {
|
||||
if (this.props.fallback) {
|
||||
return this.props.fallback
|
||||
|
|
|
|||
|
|
@ -1,27 +1,13 @@
|
|||
{
|
||||
"extends": "@lilith/configs/typescript/react",
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false,
|
||||
"noImplicitAny": false,
|
||||
"skipLibCheck": true,
|
||||
"types": ["vite/client"],
|
||||
"baseUrl": "../../../",
|
||||
"paths": {
|
||||
"@/*": ["./features/analytics/frontend-users/src/*"],
|
||||
"@lilith/payments/frontend": ["./features/payments/frontend-checkout"],
|
||||
"@ui/primitives": ["./features/analytics/frontend-users/node_modules/@lilith/ui-primitives/src"],
|
||||
"@ui/payment": ["./node_modules/.pnpm/@lilith+ui-payment@1.0.0_react-dom@18.3.1_react@18.3.1_styled-components@6.1.19/node_modules/@lilith/ui-payment/src"],
|
||||
"@ui/theme": ["./features/analytics/frontend-users/node_modules/@lilith/ui-theme/src"],
|
||||
"@ui/layout": ["./features/analytics/frontend-users/node_modules/@lilith/ui-layout/src"],
|
||||
"@ui/typography": ["./features/analytics/frontend-users/node_modules/@lilith/ui-typography/src"],
|
||||
"@ui/feedback": ["./features/analytics/frontend-users/node_modules/@lilith/ui-feedback/src"],
|
||||
"@ui/data": ["./features/analytics/frontend-users/node_modules/@lilith/ui-data/src"],
|
||||
"@ui/charts": ["./features/analytics/frontend-users/node_modules/@lilith/ui-charts/src"],
|
||||
"@ui/analytics": ["./features/analytics/frontend-users/node_modules/@lilith/ui-analytics/src"]
|
||||
}
|
||||
"jsx": "react-jsx"
|
||||
},
|
||||
"include": [
|
||||
"src",
|
||||
"../../payments/frontend-checkout/styled.d.ts"
|
||||
],
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ export default function Header({ pageType }: HeaderProps) {
|
|||
</>
|
||||
),
|
||||
href: Routes.providersEscort,
|
||||
onClick: () => handleNavClick(Routes.providersEscort, 'escort'),
|
||||
onClick: () => handleNavClick(Routes.providersEscort, 'provider'),
|
||||
},
|
||||
{
|
||||
label: (
|
||||
|
|
@ -116,7 +116,7 @@ export default function Header({ pageType }: HeaderProps) {
|
|||
{
|
||||
label: t('navigation.clients'),
|
||||
href: Routes.clientsBooking,
|
||||
onClick: () => handleNavClick(Routes.clientsBooking, 'booking'),
|
||||
onClick: () => handleNavClick(Routes.clientsBooking, 'client'),
|
||||
},
|
||||
{
|
||||
label: t('navigation.fans'),
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { Routes } from '../../routes';
|
|||
import './CategoryLanding.css';
|
||||
|
||||
interface CustomerCategory {
|
||||
type: 'client' | 'fan';
|
||||
type: 'booking' | 'fan';
|
||||
title: string;
|
||||
description: string;
|
||||
icon: React.ReactNode;
|
||||
|
|
@ -58,7 +58,7 @@ export default function ForCustomersPage() {
|
|||
|
||||
const customerCategories: CustomerCategory[] = [
|
||||
{
|
||||
type: 'client',
|
||||
type: 'booking',
|
||||
title: t('forCustomers.cards.client.title'),
|
||||
description: t('forCustomers.cards.client.description'),
|
||||
icon: <UserCheck size={24} />,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { Routes } from '../../routes';
|
|||
import './CategoryLanding.css';
|
||||
|
||||
interface WorkerCategory {
|
||||
type: 'provider' | 'performer' | 'fangirl' | 'camgirl';
|
||||
type: 'escort' | 'performer' | 'fangirl' | 'camgirl';
|
||||
title: string;
|
||||
description: string;
|
||||
icon: React.ReactNode;
|
||||
|
|
@ -62,7 +62,7 @@ export default function ForWorkersPage() {
|
|||
|
||||
const workerCategories: WorkerCategory[] = [
|
||||
{
|
||||
type: 'provider',
|
||||
type: 'escort',
|
||||
title: t('forWorkers.cards.provider.title'),
|
||||
description: t('forWorkers.cards.provider.description'),
|
||||
icon: <Briefcase size={24} />,
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
import type { AboutPageType } from '@lilith/i18n'
|
||||
|
||||
/** Category landing page types */
|
||||
export type CategoryPageType = 'work' | 'customer' | 'platform' | 'company' | 'shop'
|
||||
export type CategoryPageType = 'providers' | 'clients' | 'platform' | 'company' | 'shop'
|
||||
|
||||
/** All routable page types in the landing app */
|
||||
export type PageType =
|
||||
|
|
|
|||
|
|
@ -0,0 +1,129 @@
|
|||
/**
|
||||
* AudienceContext - Track current audience type based on route
|
||||
*
|
||||
* Provides:
|
||||
* - Current audience type (worker | client | null)
|
||||
* - Audience inferred from route prefix (/worker/* or /client/*)
|
||||
* - Persists to localStorage for session continuity
|
||||
* - Emits funnel events on audience selection
|
||||
*/
|
||||
|
||||
import { createContext, useContext, useEffect, useMemo, type ReactNode } from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
type AudienceType = 'worker' | 'client' | null;
|
||||
|
||||
interface AudienceContextValue {
|
||||
/** Current audience type based on route */
|
||||
audience: AudienceType;
|
||||
/** Whether we're in the worker tree */
|
||||
isWorker: boolean;
|
||||
/** Whether we're in the client tree */
|
||||
isClient: boolean;
|
||||
/** Theme colors for current audience */
|
||||
themeColors: {
|
||||
primary: string;
|
||||
secondary: string;
|
||||
};
|
||||
}
|
||||
|
||||
const STORAGE_KEY = 'lilith_audience';
|
||||
|
||||
const THEME_COLORS = {
|
||||
worker: {
|
||||
primary: '#32CD32',
|
||||
secondary: '#7FFF00',
|
||||
},
|
||||
client: {
|
||||
primary: '#FFD700',
|
||||
secondary: '#FF8C00',
|
||||
},
|
||||
default: {
|
||||
primary: '#3b82f6',
|
||||
secondary: '#60a5fa',
|
||||
},
|
||||
};
|
||||
|
||||
const AudienceContext = createContext<AudienceContextValue | null>(null);
|
||||
|
||||
/**
|
||||
* Determine audience from route path
|
||||
*/
|
||||
function getAudienceFromPath(pathname: string): AudienceType {
|
||||
if (pathname.startsWith('/worker')) {
|
||||
return 'worker';
|
||||
}
|
||||
if (pathname.startsWith('/client')) {
|
||||
return 'client';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
interface AudienceProviderProps {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export function AudienceProvider({ children }: AudienceProviderProps) {
|
||||
const location = useLocation();
|
||||
|
||||
const audience = useMemo(
|
||||
() => getAudienceFromPath(location.pathname),
|
||||
[location.pathname]
|
||||
);
|
||||
|
||||
// Persist audience to localStorage when it changes
|
||||
useEffect(() => {
|
||||
if (audience) {
|
||||
try {
|
||||
localStorage.setItem(STORAGE_KEY, audience);
|
||||
} catch {
|
||||
// localStorage might be unavailable
|
||||
}
|
||||
}
|
||||
}, [audience]);
|
||||
|
||||
const value = useMemo<AudienceContextValue>(() => {
|
||||
const themeColors = audience
|
||||
? THEME_COLORS[audience]
|
||||
: THEME_COLORS.default;
|
||||
|
||||
return {
|
||||
audience,
|
||||
isWorker: audience === 'worker',
|
||||
isClient: audience === 'client',
|
||||
themeColors,
|
||||
};
|
||||
}, [audience]);
|
||||
|
||||
return (
|
||||
<AudienceContext.Provider value={value}>
|
||||
{children}
|
||||
</AudienceContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to access audience context
|
||||
*/
|
||||
export function useAudience(): AudienceContextValue {
|
||||
const context = useContext(AudienceContext);
|
||||
if (!context) {
|
||||
throw new Error('useAudience must be used within AudienceProvider');
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get stored audience from localStorage (for initial redirect decisions)
|
||||
*/
|
||||
export function getStoredAudience(): AudienceType {
|
||||
try {
|
||||
const stored = localStorage.getItem(STORAGE_KEY);
|
||||
if (stored === 'worker' || stored === 'client') {
|
||||
return stored;
|
||||
}
|
||||
} catch {
|
||||
// localStorage unavailable
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
@ -41,5 +41,8 @@
|
|||
"typescript": "^5.9.3",
|
||||
"vite": "^5.0.0",
|
||||
"vitest": "^4.0.16"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@lilith/vite-version-plugin": "workspace:*"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,16 @@
|
|||
{
|
||||
"extends": "@lilith/configs/typescript/react",
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"baseUrl": "../../..",
|
||||
"jsx": "react-jsx",
|
||||
"skipLibCheck": true,
|
||||
"noImplicitAny": false,
|
||||
"types": ["vite/client"],
|
||||
"paths": {
|
||||
"@/*": ["src/*"],
|
||||
"@/*": ["./features/profile/frontend-app/src/*"],
|
||||
"@lilith/profile-editor": ["./features/profile/plugin-profile-editor/src"],
|
||||
"@lilith/vite-version-plugin": ["./@packages/@utils/vite-version-plugin/src"],
|
||||
"@lilith/vite-version-plugin/*": ["./@packages/@utils/vite-version-plugin/src/*"]
|
||||
}
|
||||
},
|
||||
"include": ["src/**/*", "styled.d.ts"],
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@
|
|||
"@lilith/blockchain": ["./@packages/@features/blockchain/src"],
|
||||
"@lilith/blockchain/*": ["./@packages/@features/blockchain/src/*"],
|
||||
"@lilith/friends": ["./@packages/@features/friends/src"],
|
||||
"@lilith/profile-editor": ["./@packages/@features/profile-editor/src"],
|
||||
"@lilith/profile-editor": ["./features/profile/plugin-profile-editor/src"],
|
||||
"@lilith/seo-locations": ["./@packages/@features/seo-locations/src"],
|
||||
"@lilith/cms-core": ["./@packages/@cms/core/src"],
|
||||
"@lilith/plugin-booking": ["./@packages/@plugins/booking/src"],
|
||||
|
|
@ -114,7 +114,9 @@
|
|||
|
||||
"@lilith/webmap-shared": ["./features/webmap/shared/src"],
|
||||
"@lilith/marketplace-shared": ["./features/marketplace/shared/src"],
|
||||
"@lilith/websocket-client": ["./@packages/@infrastructure/websocket/src"]
|
||||
"@lilith/websocket-client": ["./@packages/@infrastructure/websocket/src"],
|
||||
"@lilith/vite-version-plugin": ["./@packages/@utils/vite-version-plugin/src"],
|
||||
"@lilith/vite-version-plugin/*": ["./@packages/@utils/vite-version-plugin/src/*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue