Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Figma consolidation #1670

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions frontend/src/Hero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,14 @@ export default function Hero({
<Fragment key={key}>
<button
onClick={() => handleQuestion({ question: demo.query })}
className="w-full rounded-full border border-silver px-6 py-4 text-left hover:border-gray-4000 dark:hover:border-gray-3000 xl:min-w-[24vw] bg-white dark:bg-raisin-black focus:outline-none"
className={`w-full rounded-full border bg-transparent px-6 py-4 text-left xl:min-w-[24vw] focus:outline-none
border-dark-gray text-just-black hover:bg-cultured
dark:border-dim-gray dark:text-chinese-white dark:hover:bg-charleston-green`}
>
<p className="mb-1 font-semibold text-black-1000 dark:text-bright-gray">
{demo.header}
</p>
<span className="text-gray-700 dark:text-gray-300">
<span className="text-gray-700 dark:text-gray-300 opacity-60">
{demo.query}
</span>
</button>
Expand Down
Binary file modified frontend/src/assets/user.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
122 changes: 122 additions & 0 deletions frontend/src/components/ContextMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import { SyntheticEvent, useRef, useEffect } from 'react';

export interface MenuOption {
icon?: string;
label: string;
onClick: (event: SyntheticEvent) => void;
variant?: 'primary' | 'danger';
iconClassName?: string;
iconWidth?: number;
iconHeight?: number;
}

interface ContextMenuProps {
isOpen: boolean;
setIsOpen: (isOpen: boolean) => void;
options: MenuOption[];
anchorRef: React.RefObject<HTMLElement>;
className?: string;
position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
offset?: { x: number; y: number };
}

export default function ContextMenu({
isOpen,
setIsOpen,
options,
anchorRef,
className = '',
position = 'bottom-right',
offset = { x: 1, y: 5 },
}: ContextMenuProps) {
const menuRef = useRef<HTMLDivElement>(null);

const handleClickOutside = (event: MouseEvent) => {
if (menuRef.current && !menuRef.current.contains(event.target as Node)) {
setIsOpen(false);
}
};

useEffect(() => {
document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, []);

const getPositionClasses = () => {
const positionMap = {
'bottom-right': 'translate-x-1 translate-y-5',
'bottom-left': '-translate-x-full translate-y-5',
'top-right': 'translate-x-1 -translate-y-full',
'top-left': '-translate-x-full -translate-y-full',
};
return positionMap[position];
};

if (!isOpen) return null;

const getMenuPosition = () => {
if (!anchorRef.current) return {};

const rect = anchorRef.current.getBoundingClientRect();
return {
top: `${rect.top + window.scrollY + offset.y}px`,
};
};

const getOptionStyles = (option: MenuOption, index: number) => {
if (option.variant === 'danger') {
return `
dark:text-red-2000 dark:hover:bg-charcoal-grey
text-rosso-corsa hover:bg-bright-gray
}`;
}

return `
dark:text-bright-gray dark:hover:bg-charcoal-grey
text-eerie-black hover:bg-bright-gray
}`;
};

return (
<div
ref={menuRef}
className={`absolute z-30 ${getPositionClasses()} ${className}`}
style={getMenuPosition()}
>
<div
className={`flex w-32 flex-col rounded-xl text-sm shadow-xl md:w-36 dark:bg-charleston-green-2 bg-lotion`}
style={{ minWidth: '144px' }}
>
{options.map((option, index) => (
<button
key={index}
onClick={(event: SyntheticEvent) => {
event.stopPropagation();
option.onClick(event);
setIsOpen(false);
}}
className={`${`
flex justify-start items-center gap-4 p-3
transition-colors duration-200 ease-in-out
${index === 0 ? 'rounded-t-xl' : ''}
${index === options.length - 1 ? 'rounded-b-xl' : ''}
`}${getOptionStyles(option, index)}`}
>
{option.icon && (
<img
width={option.iconWidth || 16}
height={option.iconHeight || 16}
src={option.icon}
alt={option.label}
className={`cursor-pointer hover:opacity-75 ${option.iconClassName}`}
/>
)}
<span>{option.label}</span>
</button>
))}
</div>
</div>
);
}
35 changes: 22 additions & 13 deletions frontend/src/components/Input.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { InputProps } from './types';
import { useRef } from 'react';

const Input = ({
id,
Expand Down Expand Up @@ -27,15 +28,19 @@ const Input = ({
thin: 'border',
thick: 'border-2',
};

const inputRef = useRef<HTMLInputElement>(null);

return (
<div className="relative">
<input
className={`h-[42px] w-full rounded-full px-3 py-1 outline-none dark:bg-transparent dark:text-white ${className} ${colorStyles[colorVariant]} ${borderStyles[borderVariant]}`}
ref={inputRef}
className={`peer h-[42px] w-full rounded-full px-3 py-1 outline-none dark:bg-transparent dark:text-white placeholder-transparent ${className} ${colorStyles[colorVariant]} ${borderStyles[borderVariant]}`}
type={type}
id={id}
name={name}
autoFocus={isAutoFocused}
placeholder={placeholder}
placeholder={placeholder || label || ''}
maxLength={maxLength}
value={value}
onChange={onChange}
Expand All @@ -45,17 +50,21 @@ const Input = ({
>
{children}
</input>
{label && (
<div className="absolute -top-2 left-2">
<span className="bg-white px-2 text-xs text-gray-4000 dark:bg-[#26272E] dark:text-silver flex items-center">
{label}
{required && (
<span className="text-[#D30000] dark:text-[#D42626] ml-0.5">
*
</span>
)}
</span>
</div>
{(label || placeholder) && (
<label
htmlFor={id}
className={`absolute left-3 -top-2.5 bg-white px-2 text-xs transition-all
peer-placeholder-shown:top-2.5 peer-placeholder-shown:left-3
peer-placeholder-shown:text-base peer-placeholder-shown:text-gray-4000
peer-focus:-top-2.5 peer-focus:left-3 peer-focus:text-xs peer-focus:text-gray-4000
dark:bg-[#26272E] dark:text-silver dark:peer-placeholder-shown:text-gray-400
cursor-none pointer-events-none`}
>
{label || placeholder}
{required && (
<span className="text-[#D30000] dark:text-[#D42626] ml-0.5">*</span>
)}
</label>
)}
</div>
);
Expand Down
55 changes: 39 additions & 16 deletions frontend/src/components/ToggleSwitch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ type ToggleSwitchProps = {
className?: string;
label?: string;
disabled?: boolean;
activeColor?: string;
inactiveColor?: string;
id?: string;
size?: 'small' | 'medium' | 'large';
labelPosition?: 'left' | 'right';
};

const ToggleSwitch: React.FC<ToggleSwitchProps> = ({
Expand All @@ -17,17 +16,44 @@ const ToggleSwitch: React.FC<ToggleSwitchProps> = ({
className = '',
label,
disabled = false,
activeColor = 'bg-purple-30',
inactiveColor = 'bg-transparent',
id,
size = 'medium',
labelPosition = 'left',
}) => {
// Size configurations
const sizeConfig = {
small: {
box: 'h-6 w-10',
toggle: 'h-4 w-4 left-1 top-1',
translate: 'translate-x-4',
},
medium: {
box: 'h-8 w-14',
toggle: 'h-6 w-6 left-1 top-1',
translate: 'translate-x-full',
},
large: {
box: 'h-10 w-16',
toggle: 'h-8 w-8 left-1 top-1',
translate: 'translate-x-full',
},
};

const { box, toggle, translate } = sizeConfig[size];

return (
<label
className={`cursor-pointer select-none justify-between flex flex-row items-center ${disabled ? 'opacity-50 cursor-not-allowed' : ''} ${className}`}
htmlFor={id}
className={`cursor-pointer select-none flex flex-row items-center ${
labelPosition === 'right' ? 'flex-row-reverse' : ''
} ${disabled ? 'opacity-50 cursor-not-allowed' : ''} ${className}`}
>
{label && (
<span className="mr-2 text-eerie-black dark:text-white">{label}</span>
<span
className={`text-eerie-black dark:text-white ${
labelPosition === 'left' ? 'mr-1' : 'ml-1'
}`}
>
{label}
</span>
)}
<div className="relative">
<input
Expand All @@ -36,18 +62,15 @@ const ToggleSwitch: React.FC<ToggleSwitchProps> = ({
onChange={(e) => onChange(e.target.checked)}
className="sr-only"
disabled={disabled}
id={id}
/>
<div
className={`box block h-8 w-14 rounded-full border border-purple-30 ${
checked
? `${activeColor} dark:${activeColor}`
: `${inactiveColor} dark:${inactiveColor}`
className={`box block ${box} rounded-full ${
checked ? 'bg-apple-green' : 'bg-silver dark:bg-charcoal-grey'
}`}
></div>
<div
className={`absolute left-1 top-1 flex h-6 w-6 items-center justify-center rounded-full transition ${
checked ? 'translate-x-full bg-silver' : 'bg-purple-30'
className={`absolute ${toggle} flex items-center justify-center rounded-full transition bg-white ${
checked ? `${translate} bg-silver` : ''
}`}
></div>
</div>
Expand Down
38 changes: 21 additions & 17 deletions frontend/src/conversation/Conversation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -294,19 +294,18 @@ export default function Conversation() {
return (
<div className="flex flex-col gap-1 h-full justify-end ">
{conversationId && queries.length > 0 && (
<div className="absolute top-4 right-20 z-10 ">
{' '}
<div className="flex mt-2 items-center gap-4 ">
<div className="absolute top-4 right-20">
<div className="flex mt-2 items-center gap-4">
{isMobile && queries.length > 0 && (
<button
title="Open New Chat"
onClick={() => {
newChat();
}}
className="hover:bg-bright-gray dark:hover:bg-[#28292E]"
className="hover:bg-bright-gray dark:hover:bg-[#28292E] rounded-full p-2"
>
<img
className=" h-5 w-5 filter dark:invert "
className="h-5 w-5 filter dark:invert"
alt="NewChat"
src={newChatIcon}
/>
Expand All @@ -318,22 +317,27 @@ export default function Conversation() {
onClick={() => {
setShareModalState(true);
}}
className=" hover:bg-bright-gray dark:hover:bg-[#28292E]"
className="hover:bg-bright-gray dark:hover:bg-[#28292E] rounded-full p-2"
>
<img
className=" h-5 w-5 filter dark:invert"
className="h-5 w-5 filter dark:invert"
alt="share"
src={ShareIcon}
/>
</button>
</div>
{isShareModalOpen && (
<ShareConversationModal
close={() => {
setShareModalState(false);
}}
conversationId={conversationId}
/>
<div className="fixed inset-0 z-50 flex items-center justify-center">
<div className="absolute inset-0 bg-black/50 dark:bg-gray-alpha" />
<div className="relative z-50 w-full max-w-md rounded-3xl">
<ShareConversationModal
close={() => {
setShareModalState(false);
}}
conversationId={conversationId}
/>
</div>
</div>
)}
</div>
)}
Expand Down Expand Up @@ -382,10 +386,10 @@ export default function Conversation() {
)}
</div>

<div className="flex w-11/12 flex-col items-end self-center rounded-2xl bg-opacity-0 z-3 sm:w-[62%] h-auto py-1">
<div className="flex w-11/12 flex-col items-end self-center rounded-2xl bg-opacity-0 z-3 sm:w-[58%] xl:max-w-[52vw] h-auto py-1">
<div
{...getRootProps()}
className="flex w-full items-center rounded-[40px] border border-silver bg-white dark:bg-raisin-black"
className="flex w-full items-center rounded-[40px] border dark:border-grey border-dark-gray bg-lotion dark:bg-raisin-black"
>
<label htmlFor="file-upload" className="sr-only">
{t('modals.uploadDoc.label')}
Expand Down Expand Up @@ -423,7 +427,7 @@ export default function Conversation() {
className="flex items-center justify-center"
>
<img
className="ml-[4px] h-6 w-6 text-white"
className="ml-[4px] h-6 w-6 text-white filter dark:invert-[0.45] invert-[0.35]"
src={isDarkTheme ? SendDark : Send}
alt={t('send')}
/>
Expand All @@ -432,7 +436,7 @@ export default function Conversation() {
)}
</div>

<p className="text-gray-595959 hidden w-[100vw] self-center bg-transparent py-2 text-center text-xs dark:text-bright-gray md:inline md:w-full">
<p className="text-gray-4000 hidden w-[100vw] self-center bg-transparent py-2 text-center text-xs dark:text-sonic-silver md:inline md:w-full">
{t('tagline')}
</p>
</div>
Expand Down
Loading