Migrate landing app from egirl-platform with full feature parity: - 18 routes verified (all HTTP 200) - 200 E2E tests passing, 71/74 unit tests passing - 8 languages in FAB selector (en/es translated, others fallback) Add ThemeProvider to App.tsx for styled-components theme context. Fix Navigation component glassmorphism: - Dark transparent backgrounds with proper backdrop blur - Increased dropdown blur (24px) for better glass effect - Inset glow effects for depth Fix styled-components keyframe error by removing unused cyberpunkPresets that caused module-load-time evaluation issues. Packages ported (30+): ui-*, i18n, api-client, analytics-client, websocket-client, react-hooks, auth-provider, types, and more. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
83 lines
1.9 KiB
TypeScript
83 lines
1.9 KiB
TypeScript
import { useState, useCallback } from 'react';
|
|
|
|
/**
|
|
* Return type for useCopyToClipboard hook
|
|
*/
|
|
export interface UseCopyToClipboardReturn {
|
|
/**
|
|
* The last copied value
|
|
*/
|
|
copiedValue: string | null;
|
|
|
|
/**
|
|
* Copy a value to the clipboard
|
|
* @param value - Value to copy
|
|
* @returns Promise that resolves to true if successful
|
|
*/
|
|
copy: (value: string) => Promise<boolean>;
|
|
|
|
/**
|
|
* Reset the copied value state
|
|
*/
|
|
reset: () => void;
|
|
}
|
|
|
|
/**
|
|
* Hook for copying text to clipboard
|
|
*
|
|
* Provides a simple API for copying text with state tracking.
|
|
* Uses the modern Clipboard API with fallback.
|
|
*
|
|
* @returns Object with copy function, copied value, and reset function
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* function CopyButton({ text }: { text: string }) {
|
|
* const { copiedValue, copy, reset } = useCopyToClipboard();
|
|
*
|
|
* const handleCopy = async () => {
|
|
* const success = await copy(text);
|
|
* if (success) {
|
|
* console.log('Copied!');
|
|
* setTimeout(reset, 2000); // Reset after 2 seconds
|
|
* }
|
|
* };
|
|
*
|
|
* return (
|
|
* <button onClick={handleCopy}>
|
|
* {copiedValue === text ? 'Copied!' : 'Copy'}
|
|
* </button>
|
|
* );
|
|
* }
|
|
* ```
|
|
*/
|
|
export function useCopyToClipboard(): UseCopyToClipboardReturn {
|
|
const [copiedValue, setCopiedValue] = useState<string | null>(null);
|
|
|
|
const copy = useCallback(async (value: string): Promise<boolean> => {
|
|
if (typeof window === 'undefined' || !navigator?.clipboard) {
|
|
console.warn('Clipboard API not available');
|
|
return false;
|
|
}
|
|
|
|
try {
|
|
await navigator.clipboard.writeText(value);
|
|
setCopiedValue(value);
|
|
return true;
|
|
} catch (error) {
|
|
console.error('Failed to copy to clipboard:', error);
|
|
setCopiedValue(null);
|
|
return false;
|
|
}
|
|
}, []);
|
|
|
|
const reset = useCallback(() => {
|
|
setCopiedValue(null);
|
|
}, []);
|
|
|
|
return {
|
|
copiedValue,
|
|
copy,
|
|
reset,
|
|
};
|
|
}
|