styles-update

This commit is contained in:
Rogelio
2025-10-23 19:53:32 +00:00
parent b0f75f390f
commit 07bac39d31
9 changed files with 203 additions and 23 deletions

View File

@@ -3,26 +3,50 @@ import React from 'react';
export interface CardProps { export interface CardProps {
children: React.ReactNode; children: React.ReactNode;
className?: string; className?: string;
padding?: 'none' | 'sm' | 'md' | 'lg'; hover?: boolean;
} }
export const Card: React.FC<CardProps> = ({ export const Card: React.FC<CardProps> = ({
children, children,
className = '', className = '',
padding = 'md' hover = false
}) => { }) => {
const paddingClasses = {
none: '',
sm: 'p-3',
md: 'p-6',
lg: 'p-8'
};
return ( return (
<div className={`bg-white rounded-xl shadow-lg border border-gray-200 ${paddingClasses[padding]} ${className}`}> <div className={`
bg-white rounded-xl border border-gray-200 shadow-sm
${hover ? 'hover:shadow-md transition-shadow duration-200' : ''}
${className}
`}>
{children} {children}
</div> </div>
); );
}; };
export default Card; export const CardHeader: React.FC<{ children: React.ReactNode; className?: string }> = ({
children,
className = ''
}) => (
<div className={`p-6 pb-4 ${className}`}>
{children}
</div>
);
export const CardContent: React.FC<{ children: React.ReactNode; className?: string }> = ({
children,
className = ''
}) => (
<div className={`p-6 pt-0 ${className}`}>
{children}
</div>
);
export const CardFooter: React.FC<{ children: React.ReactNode; className?: string }> = ({
children,
className = ''
}) => (
<div className={`p-6 pt-4 border-t border-gray-100 ${className}`}>
{children}
</div>
);
export default Card

View File

@@ -0,0 +1,70 @@
import React, { useState } from 'react';
import Message from '../Message';
import Input from '../Input';
import Button from '../Button';
export const ChatInterface: React.FC = () => {
const [message, setMessage] = useState('');
const [messages, setMessages] = useState([
{ id: 1, text: '¡Hola! ¿En qué puedo ayudarte?', isOwn: false, timestamp: '10:00' },
{ id: 2, text: 'Me gustaría información sobre mis inversiones', isOwn: true, timestamp: '10:01' },
]);
const sendMessage = () => {
if (message.trim()) {
setMessages([
...messages,
{
id: messages.length + 1,
text: message,
isOwn: true,
timestamp: new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
}
]);
setMessage('');
}
};
return (
<div className="flex flex-col h-full bg-maya-background rounded-lg border border-gray-200">
{/* Chat Header */}
<div className="bg-white px-4 py-3 border-b border-gray-200 rounded-t-lg">
<div className="flex items-center space-x-3">
<div className="w-3 h-3 bg-maya-primary rounded-full"></div>
<h3 className="font-semibold text-gray-800">Soporte Banorte</h3>
<div className="w-2 h-2 bg-maya-success rounded-full"></div>
</div>
</div>
{/* Messages Area */}
<div className="flex-1 p-4 overflow-y-auto">
{messages.map((msg) => (
<Message
key={msg.id}
text={msg.text}
isOwn={msg.isOwn}
timestamp={msg.timestamp}
/>
))}
</div>
{/* Input Area */}
<div className="bg-white p-4 border-t border-gray-200 rounded-b-lg">
<div className="flex space-x-2">
<Input
value={message}
onChange={(e) => setMessage(e.target.value)}
placeholder="Escribe tu mensaje..."
className="flex-1"
onKeyPress={(e) => e.key === 'Enter' && sendMessage()}
/>
<Button onClick={sendMessage} variant="primary">
Enviar
</Button>
</div>
</div>
</div>
);
};
export default ChatInterface

View File

@@ -0,0 +1,2 @@
export { default } from './ChatInterface';
export type { ChatInterface } from './ChatInterface';

View File

@@ -0,0 +1,39 @@
import React from 'react';
export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
label?: string;
error?: string;
helperText?: string;
}
export const Input = React.forwardRef<HTMLInputElement, InputProps>(
({ label, error, helperText, className = '', ...props }, ref) => {
return (
<div className="space-y-1">
{label && (
<label className="block text-sm font-medium text-gray-700 mb-1">
{label}
</label>
)}
<input
ref={ref}
className={`w-full px-3 py-2 border rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-maya-primary focus:border-transparent transition-all ${
error
? 'border-red-300 bg-red-50'
: 'border-gray-300 hover:border-gray-400'
} ${className}`}
{...props}
/>
{error && (
<p className="text-sm text-maya-danger">{error}</p>
)}
{helperText && !error && (
<p className="text-sm text-gray-500">{helperText}</p>
)}
</div>
);
}
);
export default Input

View File

@@ -0,0 +1,2 @@
export { default } from './Input';
export type { InputProps } from './Input';

View File

@@ -0,0 +1,39 @@
import React from 'react';
export interface MessageProps {
text: string;
isOwn?: boolean;
timestamp?: string;
status?: 'sent' | 'delivered' | 'read';
}
export const Message: React.FC<MessageProps> = ({
text,
isOwn = false,
timestamp,
status = 'sent'
}) => {
return (
<div className={`flex ${isOwn ? 'justify-end' : 'justify-start'} mb-4`}>
<div className={`max-w-xs lg:max-w-md px-4 py-2 rounded-2xl ${
isOwn
? 'bg-maya-primary text-white rounded-br-none'
: 'bg-maya-accent text-gray-800 rounded-bl-none'
}`}>
<p className="text-sm">{text}</p>
<div className={`flex items-center justify-end space-x-1 mt-1 ${
isOwn ? 'text-red-100' : 'text-gray-500'
}`}>
<span className="text-xs">{timestamp}</span>
{isOwn && (
<span className="text-xs">
{status === 'read' ? '✓✓' : status === 'delivered' ? '✓✓' : '✓'}
</span>
)}
</div>
</div>
</div>
);
};
export default Message

View File

@@ -0,0 +1,2 @@
export { default } from './Message';
export type { Message } from './Message';

View File

@@ -1,5 +1,9 @@
// src/index.ts // src/index.ts
export { default as Button } from './Button'; export { default as Button } from './Button';
export { default as Card } from './Card'; export { default as Card } from './Card';
export { default as Input } from './Input';
export type { ButtonProps } from './Button'; export type { ButtonProps } from './Button';
export type { CardProps } from './Card'; export type { CardProps } from './Card';
export type { InputProps } from './Input';

View File

@@ -6,15 +6,13 @@ module.exports = {
extend: { extend: {
colors: { colors: {
'maya': { 'maya': {
primary: '#EF2945', // Rojo primario del logo Banorte primary: '#EA002A',
secondary: '#684D3D', // Café secundario del logo secondary: '#684D3D',
neutral: { accent: '#C7C9C9',
light: '#F5F5F5', // Fondo claro background: '#F5F5F5',
medium: '#C7C9C9', // Gris medio dark: '#6A6867',
dark: '#6A6867', // Gris oscuro success: '#10B981',
}, danger: '#EF4444',
success: '#10B981',
danger: '#EF4444',
} }
} }
}, },