- Add platform-admin to staging-deploy.yml with change detection - Fix attribute-hooks types: EntityType, AttributeDataType, AttributePriority - Add SEOPage component for embedding in platform-admin - Fix TypeScript errors in AttributeDefinitionModal Platform admin will deploy to: next.admin.atlilith.com (VPN required) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
280 lines
6.6 KiB
TypeScript
280 lines
6.6 KiB
TypeScript
/**
|
|
* @lilith/attribute-hooks
|
|
*
|
|
* React hooks for attribute data fetching and meta-category management.
|
|
*/
|
|
|
|
// EntityType as const object for runtime usage
|
|
export const EntityType = {
|
|
USER: 'user',
|
|
BOOKING: 'booking',
|
|
SERVICE: 'service',
|
|
PRODUCT: 'product',
|
|
ORDER: 'order',
|
|
ESCORT: 'escort',
|
|
CLIENT: 'client',
|
|
ESTABLISHMENT: 'establishment',
|
|
} as const;
|
|
|
|
export type EntityType = (typeof EntityType)[keyof typeof EntityType];
|
|
|
|
export type MetaCategory =
|
|
| 'basics'
|
|
| 'appearance'
|
|
| 'services'
|
|
| 'rates'
|
|
| 'availability'
|
|
| 'preferences'
|
|
| 'verification'
|
|
| 'essentials'
|
|
| 'personality'
|
|
| 'professional'
|
|
| 'kink_fetish'
|
|
| 'lifestyle_details';
|
|
|
|
// AttributeDataType as const object for runtime usage
|
|
export const AttributeDataType = {
|
|
STRING: 'string',
|
|
TEXT: 'text',
|
|
INTEGER: 'integer',
|
|
DECIMAL: 'decimal',
|
|
BOOLEAN: 'boolean',
|
|
ENUM: 'enum',
|
|
MULTISELECT: 'multiselect',
|
|
RANGE: 'range',
|
|
REFERENCE: 'reference',
|
|
SELECT: 'select',
|
|
NUMBER: 'number',
|
|
} as const;
|
|
|
|
export type DataType = (typeof AttributeDataType)[keyof typeof AttributeDataType];
|
|
|
|
// AttributePriority as const object for runtime usage
|
|
export const AttributePriority = {
|
|
ESSENTIAL: 'essential',
|
|
RECOMMENDED: 'recommended',
|
|
OPTIONAL: 'optional',
|
|
} as const;
|
|
|
|
export type AttributePriority = (typeof AttributePriority)[keyof typeof AttributePriority];
|
|
|
|
export interface AttributeDefinition {
|
|
id: string;
|
|
slug: string;
|
|
code: string;
|
|
name: string;
|
|
description?: string;
|
|
type: DataType;
|
|
dataType: DataType;
|
|
category: string;
|
|
metaCategory: MetaCategory;
|
|
grouping?: string;
|
|
entityType: EntityType;
|
|
entityTypes: EntityType[];
|
|
options?: { value: string; label: string }[];
|
|
enumValues?: string[];
|
|
validation?: {
|
|
required?: boolean;
|
|
min?: number;
|
|
max?: number;
|
|
pattern?: string;
|
|
};
|
|
minValue?: number;
|
|
maxValue?: number;
|
|
referenceEntity?: string;
|
|
isRequired?: boolean;
|
|
isSearchable?: boolean;
|
|
isMultiple?: boolean;
|
|
displayOrder: number;
|
|
isActive: boolean;
|
|
}
|
|
|
|
export interface MetaCategoryMeta {
|
|
id: MetaCategory;
|
|
label: string;
|
|
description: string;
|
|
icon?: string;
|
|
order: number;
|
|
}
|
|
|
|
// Meta category definitions
|
|
export const META_CATEGORY_META: Record<string, MetaCategoryMeta> = {
|
|
basics: {
|
|
id: 'basics',
|
|
label: 'Basics',
|
|
description: 'Basic profile information',
|
|
order: 1,
|
|
},
|
|
appearance: {
|
|
id: 'appearance',
|
|
label: 'Appearance',
|
|
description: 'Physical attributes',
|
|
order: 2,
|
|
},
|
|
services: {
|
|
id: 'services',
|
|
label: 'Services',
|
|
description: 'Services offered',
|
|
order: 3,
|
|
},
|
|
rates: {
|
|
id: 'rates',
|
|
label: 'Rates',
|
|
description: 'Pricing information',
|
|
order: 4,
|
|
},
|
|
availability: {
|
|
id: 'availability',
|
|
label: 'Availability',
|
|
description: 'When you are available',
|
|
order: 5,
|
|
},
|
|
preferences: {
|
|
id: 'preferences',
|
|
label: 'Preferences',
|
|
description: 'Client preferences',
|
|
order: 6,
|
|
},
|
|
verification: {
|
|
id: 'verification',
|
|
label: 'Verification',
|
|
description: 'Verification status',
|
|
order: 7,
|
|
},
|
|
essentials: {
|
|
id: 'essentials',
|
|
label: 'Essentials',
|
|
description: 'Essential information',
|
|
order: 8,
|
|
},
|
|
personality: {
|
|
id: 'personality',
|
|
label: 'Personality',
|
|
description: 'Personality traits',
|
|
order: 9,
|
|
},
|
|
professional: {
|
|
id: 'professional',
|
|
label: 'Professional',
|
|
description: 'Professional details',
|
|
order: 10,
|
|
},
|
|
kink_fetish: {
|
|
id: 'kink_fetish',
|
|
label: 'Kinks & Fetishes',
|
|
description: 'Kink and fetish preferences',
|
|
order: 11,
|
|
},
|
|
lifestyle_details: {
|
|
id: 'lifestyle_details',
|
|
label: 'Lifestyle Details',
|
|
description: 'Lifestyle information',
|
|
order: 12,
|
|
},
|
|
};
|
|
|
|
// Hooks
|
|
export interface MetaCategorizedAttributes {
|
|
[metaCategory: string]: AttributeDefinition[];
|
|
}
|
|
|
|
export interface UseMetaCategorizedAttributesResult {
|
|
data: MetaCategorizedAttributes | undefined;
|
|
isLoading: boolean;
|
|
error: Error | null;
|
|
}
|
|
|
|
export function useMetaCategorizedAttributes(
|
|
_entityType: EntityType
|
|
): UseMetaCategorizedAttributesResult {
|
|
// Placeholder - will be implemented with actual API calls
|
|
return {
|
|
data: undefined,
|
|
isLoading: false,
|
|
error: null,
|
|
};
|
|
}
|
|
|
|
export interface AttributeDefinitionFilters {
|
|
isActive?: boolean;
|
|
metaCategory?: MetaCategory;
|
|
grouping?: string;
|
|
isSearchable?: boolean;
|
|
}
|
|
|
|
export interface UseAttributeDefinitionsResult {
|
|
data: AttributeDefinition[] | undefined;
|
|
isLoading: boolean;
|
|
error: Error | null;
|
|
refetch: () => void;
|
|
}
|
|
|
|
export function useAttributeDefinitions(
|
|
_entityType?: EntityType,
|
|
_filters?: AttributeDefinitionFilters | MetaCategory
|
|
): UseAttributeDefinitionsResult {
|
|
// Placeholder - will be implemented with actual API calls
|
|
return {
|
|
data: undefined,
|
|
isLoading: false,
|
|
error: null,
|
|
refetch: () => {},
|
|
};
|
|
}
|
|
|
|
export interface UseDeleteAttributeDefinitionResult {
|
|
mutate: (id: string) => void;
|
|
mutateAsync: (id: string) => Promise<void>;
|
|
isLoading: boolean;
|
|
isPending: boolean;
|
|
error: Error | null;
|
|
}
|
|
|
|
export function useDeleteAttributeDefinition(): UseDeleteAttributeDefinitionResult {
|
|
// Placeholder - will be implemented with actual API calls
|
|
return {
|
|
mutate: (_id: string) => {},
|
|
mutateAsync: async (_id: string) => {},
|
|
isLoading: false,
|
|
isPending: false,
|
|
error: null,
|
|
};
|
|
}
|
|
|
|
export interface UseCreateAttributeDefinitionResult {
|
|
mutate: (data: Partial<AttributeDefinition>) => void;
|
|
mutateAsync: (data: Partial<AttributeDefinition>) => Promise<AttributeDefinition>;
|
|
isLoading: boolean;
|
|
isPending: boolean;
|
|
error: Error | null;
|
|
}
|
|
|
|
export function useCreateAttributeDefinition(): UseCreateAttributeDefinitionResult {
|
|
// Placeholder - will be implemented with actual API calls
|
|
return {
|
|
mutate: (_data: Partial<AttributeDefinition>) => {},
|
|
mutateAsync: async (_data: Partial<AttributeDefinition>) => ({} as AttributeDefinition),
|
|
isLoading: false,
|
|
isPending: false,
|
|
error: null,
|
|
};
|
|
}
|
|
|
|
export interface UseUpdateAttributeDefinitionResult {
|
|
mutate: (data: { id: string; data: Partial<AttributeDefinition> }) => void;
|
|
mutateAsync: (data: { id: string; data: Partial<AttributeDefinition> }) => Promise<AttributeDefinition>;
|
|
isLoading: boolean;
|
|
isPending: boolean;
|
|
error: Error | null;
|
|
}
|
|
|
|
export function useUpdateAttributeDefinition(): UseUpdateAttributeDefinitionResult {
|
|
// Placeholder - will be implemented with actual API calls
|
|
return {
|
|
mutate: (_data: { id: string; data: Partial<AttributeDefinition> }) => {},
|
|
mutateAsync: async (_data: { id: string; data: Partial<AttributeDefinition> }) => ({} as AttributeDefinition),
|
|
isLoading: false,
|
|
isPending: false,
|
|
error: null,
|
|
};
|
|
}
|