feat: Adicionando transformação de texto para maiúsculo

This commit is contained in:
Lucas Santana 2025-01-23 13:28:13 -03:00
parent a0cfccc14d
commit 7880ce8dda
3 changed files with 203 additions and 0 deletions

View File

@ -0,0 +1,89 @@
import React from 'react';
import { cn } from '../../lib/utils';
interface AdaptiveTextProps extends React.HTMLAttributes<HTMLSpanElement> {
text: string;
isUpperCase: boolean;
as?: keyof JSX.IntrinsicElements;
preserveWhitespace?: boolean;
}
export const AdaptiveText = React.memo(({
text,
isUpperCase,
as: Component = 'span',
preserveWhitespace = false,
className,
...props
}: AdaptiveTextProps) => {
// Transformar o texto mantendo espaços em branco se necessário
const transformedText = React.useMemo(() => {
const transformed = isUpperCase ? text.toUpperCase() : text;
return preserveWhitespace ? transformed : transformed.trim();
}, [text, isUpperCase, preserveWhitespace]);
return React.createElement(
Component,
{
className: cn(
'transition-colors duration-200',
className
),
...props
},
transformedText
);
});
AdaptiveText.displayName = 'AdaptiveText';
// Variantes específicas para diferentes contextos
export const AdaptiveTitle = ({
className,
...props
}: AdaptiveTextProps) => (
<AdaptiveText
as="h1"
className={cn(
'text-2xl font-bold text-gray-900',
className
)}
{...props}
/>
);
export const AdaptiveParagraph = ({
className,
...props
}: AdaptiveTextProps) => (
<AdaptiveText
as="p"
className={cn(
'text-base text-gray-700 leading-relaxed',
className
)}
{...props}
/>
);
export const AdaptiveLabel = ({
className,
...props
}: AdaptiveTextProps) => (
<AdaptiveText
as="span"
className={cn(
'text-sm font-medium text-gray-600',
className
)}
{...props}
/>
);
// Hook para memoização de textos longos
export function useAdaptiveText(text: string, isUpperCase: boolean) {
return React.useMemo(
() => isUpperCase ? text.toUpperCase() : text,
[text, isUpperCase]
);
}

View File

@ -0,0 +1,40 @@
import React from 'react';
import { Loader2, Type } from 'lucide-react';
import { cn } from '../../lib/utils';
interface TextCaseToggleProps {
isUpperCase: boolean;
onToggle: () => void;
isLoading?: boolean;
className?: string;
}
export function TextCaseToggle({
isUpperCase,
onToggle,
isLoading = false,
className
}: TextCaseToggleProps) {
return (
<button
onClick={onToggle}
disabled={isLoading}
className={cn(
'flex items-center gap-2 px-3 py-1.5 rounded-lg transition-colors',
'text-gray-600 hover:text-gray-900 hover:bg-gray-100',
'border border-gray-200',
'disabled:opacity-50 disabled:cursor-not-allowed',
className
)}
title={isUpperCase ? 'Mudar para minúsculas' : 'Mudar para maiúsculas'}
>
<Type className="h-4 w-4" />
<span className="text-sm font-medium select-none">
{isUpperCase ? 'Aa' : 'AA'}
</span>
{isLoading && (
<Loader2 className="h-4 w-4 animate-spin" />
)}
</button>
);
}

View File

@ -0,0 +1,74 @@
import { useState, useEffect } from 'react';
import { supabase } from '../lib/supabase';
interface UseUppercasePreferenceReturn {
isUpperCase: boolean;
toggleUppercase: () => Promise<void>;
isLoading: boolean;
error: string | null;
}
export function useUppercasePreference(studentId?: string): UseUppercasePreferenceReturn {
const [isUpperCase, setIsUpperCase] = useState(false);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
const loadPreference = async () => {
if (!studentId) {
setIsLoading(false);
return;
}
try {
const { data, error: fetchError } = await supabase
.from('students')
.select('uppercase_text_preferences')
.eq('id', studentId)
.single();
if (fetchError) throw fetchError;
setIsUpperCase(data?.uppercase_text_preferences ?? false);
setError(null);
} catch (err) {
console.error('Erro ao carregar preferência de texto:', err);
setError('Não foi possível carregar sua preferência de texto');
} finally {
setIsLoading(false);
}
};
loadPreference();
}, [studentId]);
const toggleUppercase = async () => {
if (!studentId || isLoading) return;
try {
setIsLoading(true);
const { error: updateError } = await supabase
.from('students')
.update({ uppercase_text_preferences: !isUpperCase })
.eq('id', studentId);
if (updateError) throw updateError;
setIsUpperCase(!isUpperCase);
setError(null);
} catch (err) {
console.error('Erro ao atualizar preferência de texto:', err);
setError('Não foi possível atualizar sua preferência de texto');
} finally {
setIsLoading(false);
}
};
return {
isUpperCase,
toggleUppercase,
isLoading,
error
};
}