mirror of
https://github.com/m4rcel-lol/custom-discord-ai-chatbot-site.git
synced 2025-12-06 19:03:58 +05:30
feat: Initialize Discord-style AI chat project
Sets up the project structure, dependencies, and basic configuration for a Discord-inspired AI chat application. Includes placeholder components and types, Vite configuration for local development, and basic styling for a dark theme and custom scrollbars. Integrates Gemini API key handling and a service for sending messages.
This commit is contained in:
112
components/MiniProfile.tsx
Normal file
112
components/MiniProfile.tsx
Normal file
@@ -0,0 +1,112 @@
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import { StaffBadge, CertifiedBadge, BugHunterBadge, VerifiedBotBadge } from './Badges';
|
||||
|
||||
interface MiniProfileProps {
|
||||
user: {
|
||||
name: string;
|
||||
avatarUrl: string;
|
||||
isBot: boolean;
|
||||
username: string;
|
||||
color: string;
|
||||
theme?: string;
|
||||
bannerUrl?: string;
|
||||
};
|
||||
position: { x: number, y: number };
|
||||
onClose: () => void;
|
||||
onOpenFullProfile: (user: any) => void;
|
||||
}
|
||||
|
||||
const MiniProfile: React.FC<MiniProfileProps> = ({ user, position, onClose, onOpenFullProfile }) => {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const handleClickOutside = (event: MouseEvent) => {
|
||||
if (ref.current && !ref.current.contains(event.target as Node)) {
|
||||
onClose();
|
||||
}
|
||||
};
|
||||
document.addEventListener('mousedown', handleClickOutside);
|
||||
return () => document.removeEventListener('mousedown', handleClickOutside);
|
||||
}, [onClose]);
|
||||
|
||||
const style: React.CSSProperties = {
|
||||
top: Math.min(position.y, window.innerHeight - 400), // Prevent going off bottom
|
||||
left: position.x + 20, // Offset to right
|
||||
background: user.theme || '#232428'
|
||||
};
|
||||
|
||||
const handleAvatarClick = () => {
|
||||
onClose(); // Close mini profile
|
||||
onOpenFullProfile(user); // Open full profile
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
style={style}
|
||||
className="fixed z-50 w-[300px] rounded-xl shadow-[0_8px_16px_rgba(0,0,0,0.24)] overflow-hidden animate-scale-in"
|
||||
>
|
||||
{/* Banner */}
|
||||
<div
|
||||
className="h-[60px] w-full relative bg-cover bg-center"
|
||||
style={{
|
||||
backgroundColor: user.color,
|
||||
backgroundImage: user.bannerUrl ? `url(${user.bannerUrl})` : undefined
|
||||
}}
|
||||
/>
|
||||
|
||||
<div className="relative px-4 pb-4">
|
||||
{/* Avatar */}
|
||||
<div className="absolute -top-[30px] left-4 group cursor-pointer" onClick={handleAvatarClick}>
|
||||
<div
|
||||
className="w-[80px] h-[80px] rounded-full p-[6px] relative"
|
||||
style={{ background: user.theme || '#232428' }}
|
||||
>
|
||||
<div className="w-full h-full bg-[#232428] rounded-full overflow-hidden relative">
|
||||
<img src={user.avatarUrl} alt={user.name} className="w-full h-full rounded-full transition-opacity group-hover:opacity-80 object-cover" />
|
||||
</div>
|
||||
<div className="absolute top-0 left-0 w-full h-full bg-black/40 rounded-full opacity-0 group-hover:opacity-100 flex items-center justify-center text-[10px] text-white font-bold transition-opacity z-10">
|
||||
VIEW PROFILE
|
||||
</div>
|
||||
<div className="absolute bottom-1 right-1 w-5 h-5 bg-[#23a559] border-[4px] border-[#232428] rounded-full z-20"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Badges */}
|
||||
{user.isBot && (
|
||||
<div className="flex justify-end pt-3 pb-1">
|
||||
<div className="bg-[#111214]/50 rounded-lg p-1 flex gap-1 border border-[#1e1f22]/50 backdrop-blur-sm">
|
||||
<StaffBadge />
|
||||
<CertifiedBadge />
|
||||
<BugHunterBadge />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{!user.isBot && <div className="h-6"></div>}
|
||||
|
||||
{/* Info */}
|
||||
<div className={`mt-8 rounded-lg p-3 pb-4 ${user.theme ? 'bg-[#111214]/60 border border-[#1e1f22]/50 backdrop-blur-md' : 'bg-[#111214]'}`}>
|
||||
<div className="flex items-center flex-wrap gap-1">
|
||||
<span className="text-xl font-bold text-white hover:underline cursor-pointer" onClick={handleAvatarClick}>{user.name}</span>
|
||||
{user.isBot && <VerifiedBotBadge />}
|
||||
</div>
|
||||
<div className="text-sm text-[#dbdee1] mb-3">{user.username}</div>
|
||||
|
||||
<div className="h-[1px] bg-[#2e2f34] w-full mb-3" />
|
||||
|
||||
<div className="uppercase text-[11px] font-bold text-[#b5bac1] mb-1">About Me</div>
|
||||
<div className="text-sm text-[#dbdee1]">
|
||||
{user.isBot
|
||||
? "I am a helpful AI assistant residing in your Discord DMs."
|
||||
: "Just a human chatting with an AI."}
|
||||
</div>
|
||||
|
||||
<div className="uppercase text-[11px] font-bold text-[#b5bac1] mt-3 mb-1">Member Since</div>
|
||||
<div className="text-sm text-[#dbdee1]">Feb 21, 2024</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default MiniProfile;
|
||||
Reference in New Issue
Block a user