taskcafe/web/src/shared/components/TopNavbar/index.tsx

202 lines
5.8 KiB
TypeScript
Raw Normal View History

2020-05-31 06:11:19 +02:00
import React, { useRef, useState, useEffect } from 'react';
import { Star, Ellipsis, Bell, Cog, AngleDown } from 'shared/icons';
2020-06-13 00:21:58 +02:00
import ProfileIcon from 'shared/components/ProfileIcon';
2020-04-10 04:40:22 +02:00
import {
NotificationContainer,
2020-05-31 06:11:19 +02:00
ProjectNameTextarea,
2020-05-27 23:18:50 +02:00
InviteButton,
2020-04-10 04:40:22 +02:00
GlobalActions,
ProjectActions,
2020-05-27 02:53:31 +02:00
ProjectSwitcher,
Separator,
2020-04-21 01:04:27 +02:00
ProjectMeta,
ProjectName,
ProjectTabs,
ProjectTab,
2020-04-10 04:40:22 +02:00
NavbarWrapper,
NavbarHeader,
Breadcrumbs,
BreadcrumpSeparator,
2020-05-27 02:53:31 +02:00
ProjectSettingsButton,
2020-04-10 04:40:22 +02:00
ProfileContainer,
ProfileNameWrapper,
ProfileNamePrimary,
ProfileNameSecondary,
2020-05-27 23:18:50 +02:00
ProjectMembers,
2020-04-10 04:40:22 +02:00
} from './Styles';
2020-05-27 23:18:50 +02:00
import TaskAssignee from 'shared/components/TaskAssignee';
import { usePopup, Popup } from 'shared/components/PopupMenu';
import MiniProfile from 'shared/components/MiniProfile';
2020-04-10 04:40:22 +02:00
2020-05-31 06:11:19 +02:00
type ProjectHeadingProps = {
projectName: string;
onSaveProjectName?: (projectName: string) => void;
onOpenSettings: ($target: React.RefObject<HTMLElement>) => void;
2020-05-31 06:11:19 +02:00
};
const ProjectHeading: React.FC<ProjectHeadingProps> = ({
projectName: initialProjectName,
onSaveProjectName,
onOpenSettings,
}) => {
2020-05-31 06:11:19 +02:00
const [isEditProjectName, setEditProjectName] = useState(false);
const [projectName, setProjectName] = useState(initialProjectName);
const $projectName = useRef<HTMLTextAreaElement>(null);
useEffect(() => {
if (isEditProjectName && $projectName && $projectName.current) {
$projectName.current.focus();
$projectName.current.select();
}
}, [isEditProjectName]);
useEffect(() => {
setProjectName(initialProjectName);
}, [initialProjectName]);
const onProjectNameChange = (event: React.FormEvent<HTMLTextAreaElement>): void => {
setProjectName(event.currentTarget.value);
};
const onProjectNameBlur = () => {
if (onSaveProjectName) {
onSaveProjectName(projectName);
}
setEditProjectName(false);
};
const onProjectNameKeyDown = (e: React.KeyboardEvent) => {
if (e.key === 'Enter') {
e.preventDefault();
if ($projectName && $projectName.current) {
$projectName.current.blur();
}
}
};
const $settings = useRef<HTMLButtonElement>(null);
2020-05-31 06:11:19 +02:00
return (
<>
<Separator>»</Separator>
{isEditProjectName ? (
<ProjectNameTextarea
ref={$projectName}
onChange={onProjectNameChange}
onKeyDown={onProjectNameKeyDown}
onBlur={onProjectNameBlur}
spellCheck={false}
value={projectName}
/>
) : (
<ProjectName
onClick={() => {
setEditProjectName(true);
}}
>
{projectName}
</ProjectName>
)}
<ProjectSettingsButton
onClick={() => {
onOpenSettings($settings);
}}
ref={$settings}
>
<AngleDown color="#c2c6dc" />
</ProjectSettingsButton>
<ProjectSettingsButton>
<Star width={16} height={16} color="#c2c6dc" />
</ProjectSettingsButton>
2020-05-31 06:11:19 +02:00
</>
);
};
2020-04-10 04:40:22 +02:00
type NavBarProps = {
projectName: string | null;
2020-06-13 00:21:58 +02:00
onProfileClick: ($target: React.RefObject<HTMLElement>) => void;
2020-05-31 06:11:19 +02:00
onSaveProjectName?: (projectName: string) => void;
2020-04-10 04:40:22 +02:00
onNotificationClick: () => void;
2020-06-13 00:21:58 +02:00
user: TaskUser | null;
onOpenSettings: ($target: React.RefObject<HTMLElement>) => void;
2020-05-27 23:18:50 +02:00
projectMembers?: Array<TaskUser> | null;
2020-04-10 04:40:22 +02:00
};
2020-05-31 06:11:19 +02:00
2020-04-21 01:04:27 +02:00
const NavBar: React.FC<NavBarProps> = ({
2020-05-27 02:53:31 +02:00
projectName,
2020-05-31 06:11:19 +02:00
onSaveProjectName,
2020-04-21 01:04:27 +02:00
onProfileClick,
onNotificationClick,
2020-06-13 00:21:58 +02:00
user,
2020-05-27 23:18:50 +02:00
projectMembers,
onOpenSettings,
2020-04-21 01:04:27 +02:00
}) => {
2020-06-13 00:21:58 +02:00
const handleProfileClick = ($target: React.RefObject<HTMLElement>) => {
if ($target && $target.current) {
onProfileClick($target);
}
2020-04-10 04:40:22 +02:00
};
2020-05-27 23:18:50 +02:00
const { showPopup } = usePopup();
const onMemberProfile = ($targetRef: React.RefObject<HTMLElement>, memberID: string) => {
showPopup(
$targetRef,
<Popup title={null} onClose={() => {}} tab={0}>
<MiniProfile
profileIcon={projectMembers ? projectMembers[0].profileIcon : { url: null, initials: 'JK', bgColor: '#000' }}
displayName="Jordan Knott"
username="@jordanthedev"
bio="None"
onRemoveFromTask={() => {}}
/>
</Popup>,
);
};
2020-05-31 06:11:19 +02:00
2020-04-10 04:40:22 +02:00
return (
<NavbarWrapper>
<NavbarHeader>
<ProjectActions>
2020-04-21 01:04:27 +02:00
<ProjectMeta>
2020-05-27 02:53:31 +02:00
<ProjectSwitcher>Projects</ProjectSwitcher>
{projectName && (
<ProjectHeading
onOpenSettings={onOpenSettings}
projectName={projectName}
onSaveProjectName={onSaveProjectName}
/>
)}
2020-04-21 01:04:27 +02:00
</ProjectMeta>
{projectName && (
<ProjectTabs>
<ProjectTab active>Board</ProjectTab>
<ProjectTab>Calender</ProjectTab>
<ProjectTab>Timeline</ProjectTab>
<ProjectTab>Wiki</ProjectTab>
</ProjectTabs>
)}
2020-04-10 04:40:22 +02:00
</ProjectActions>
<GlobalActions>
2020-05-27 23:18:50 +02:00
{projectMembers && (
<ProjectMembers>
{projectMembers.map(member => (
2020-05-31 06:11:19 +02:00
<TaskAssignee key={member.id} size={28} member={member} onMemberProfile={onMemberProfile} />
2020-05-27 23:18:50 +02:00
))}
<InviteButton>Invite</InviteButton>
</ProjectMembers>
)}
2020-04-10 04:40:22 +02:00
<NotificationContainer onClick={onNotificationClick}>
<Bell color="#c2c6dc" size={20} />
</NotificationContainer>
2020-06-13 00:21:58 +02:00
{user && (
<ProfileContainer>
<ProfileNameWrapper>
<ProfileNamePrimary>{user.fullName}</ProfileNamePrimary>
<ProfileNameSecondary>Manager</ProfileNameSecondary>
</ProfileNameWrapper>
<ProfileIcon user={user} size={40} onProfileClick={handleProfileClick} />}
</ProfileContainer>
)}
2020-04-10 04:40:22 +02:00
</GlobalActions>
</NavbarHeader>
</NavbarWrapper>
);
};
export default NavBar;