fix: user dashboard greeting timezone (#2267)

* chore: user greeting timezone

* fix: group by labels not working on workspace level
This commit is contained in:
Aaryan Khandelwal 2023-09-26 18:08:01 +05:30 committed by GitHub
parent 4c333d5767
commit a187e7765c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 97 additions and 35 deletions

View File

@ -93,7 +93,9 @@ export const IssuesFilterView: React.FC = () => {
<Tooltip <Tooltip
key={option.type} key={option.type}
tooltipContent={ tooltipContent={
<span className="capitalize">{replaceUnderscoreIfSnakeCase(option.type)} Layout</span> <span className="capitalize">
{replaceUnderscoreIfSnakeCase(option.type)} Layout
</span>
} }
position="bottom" position="bottom"
> >
@ -318,7 +320,7 @@ export const IssuesFilterView: React.FC = () => {
displayFilters.layout !== "spreadsheet" && displayFilters.layout !== "spreadsheet" &&
displayFilters.layout !== "gantt_chart" && ( displayFilters.layout !== "gantt_chart" && (
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<h4 className="text-custom-text-200">Show empty states</h4> <h4 className="text-custom-text-200">Show empty groups</h4>
<div className="w-28"> <div className="w-28">
<ToggleSwitch <ToggleSwitch
value={displayFilters.show_empty_groups ?? true} value={displayFilters.show_empty_groups ?? true}

View File

@ -20,7 +20,7 @@ import { renderEmoji } from "helpers/emoji.helper";
// types // types
import { IIssueViewProps, IState, TIssuePriorities, TStateGroups } from "types"; import { IIssueViewProps, IState, TIssuePriorities, TStateGroups } from "types";
// fetch-keys // fetch-keys
import { PROJECT_ISSUE_LABELS, PROJECT_MEMBERS } from "constants/fetch-keys"; import { PROJECT_ISSUE_LABELS, PROJECT_MEMBERS, WORKSPACE_LABELS } from "constants/fetch-keys";
// constants // constants
import { STATE_GROUP_COLORS } from "constants/state"; import { STATE_GROUP_COLORS } from "constants/state";
@ -59,6 +59,15 @@ export const BoardHeader: React.FC<Props> = ({
: null : null
); );
const { data: workspaceLabels } = useSWR(
workspaceSlug && displayFilters?.group_by === "labels"
? WORKSPACE_LABELS(workspaceSlug.toString())
: null,
workspaceSlug && displayFilters?.group_by === "labels"
? () => issuesService.getWorkspaceLabels(workspaceSlug.toString())
: null
);
const { data: members } = useSWR( const { data: members } = useSWR(
workspaceSlug && workspaceSlug &&
projectId && projectId &&
@ -82,7 +91,10 @@ export const BoardHeader: React.FC<Props> = ({
title = addSpaceIfCamelCase(currentState?.name ?? ""); title = addSpaceIfCamelCase(currentState?.name ?? "");
break; break;
case "labels": case "labels":
title = issueLabels?.find((label) => label.id === groupTitle)?.name ?? "None"; title =
[...(issueLabels ?? []), ...(workspaceLabels ?? [])]?.find(
(label) => label.id === groupTitle
)?.name ?? "None";
break; break;
case "project": case "project":
title = projects?.find((p) => p.id === groupTitle)?.name ?? "None"; title = projects?.find((p) => p.id === groupTitle)?.name ?? "None";
@ -137,7 +149,9 @@ export const BoardHeader: React.FC<Props> = ({
break; break;
case "labels": case "labels":
const labelColor = const labelColor =
issueLabels?.find((label) => label.id === groupTitle)?.color ?? "#000000"; [...(issueLabels ?? []), ...(workspaceLabels ?? [])]?.find(
(label) => label.id === groupTitle
)?.color ?? "#000000";
icon = ( icon = (
<span <span
className="h-3.5 w-3.5 flex-shrink-0 rounded-full" className="h-3.5 w-3.5 flex-shrink-0 rounded-full"

View File

@ -34,7 +34,7 @@ import {
UserAuth, UserAuth,
} from "types"; } from "types";
// fetch-keys // fetch-keys
import { PROJECT_ISSUE_LABELS, PROJECT_MEMBERS } from "constants/fetch-keys"; import { PROJECT_ISSUE_LABELS, PROJECT_MEMBERS, WORKSPACE_LABELS } from "constants/fetch-keys";
// constants // constants
import { STATE_GROUP_COLORS } from "constants/state"; import { STATE_GROUP_COLORS } from "constants/state";
@ -86,16 +86,33 @@ export const SingleList: React.FC<Props> = (props) => {
const { displayFilters, groupedIssues } = viewProps; const { displayFilters, groupedIssues } = viewProps;
const { data: issueLabels } = useSWR<IIssueLabels[]>( const { data: issueLabels } = useSWR(
workspaceSlug && projectId ? PROJECT_ISSUE_LABELS(projectId as string) : null, workspaceSlug && projectId && displayFilters?.group_by === "labels"
workspaceSlug && projectId ? PROJECT_ISSUE_LABELS(projectId.toString())
? () => issuesService.getIssueLabels(workspaceSlug as string, projectId as string) : null,
workspaceSlug && projectId && displayFilters?.group_by === "labels"
? () => issuesService.getIssueLabels(workspaceSlug.toString(), projectId.toString())
: null
);
const { data: workspaceLabels } = useSWR(
workspaceSlug && displayFilters?.group_by === "labels"
? WORKSPACE_LABELS(workspaceSlug.toString())
: null,
workspaceSlug && displayFilters?.group_by === "labels"
? () => issuesService.getWorkspaceLabels(workspaceSlug.toString())
: null : null
); );
const { data: members } = useSWR( const { data: members } = useSWR(
workspaceSlug && projectId ? PROJECT_MEMBERS(projectId as string) : null, workspaceSlug &&
workspaceSlug && projectId projectId &&
(displayFilters?.group_by === "created_by" || displayFilters?.group_by === "assignees")
? PROJECT_MEMBERS(projectId as string)
: null,
workspaceSlug &&
projectId &&
(displayFilters?.group_by === "created_by" || displayFilters?.group_by === "assignees")
? () => projectService.projectMembers(workspaceSlug as string, projectId as string) ? () => projectService.projectMembers(workspaceSlug as string, projectId as string)
: null : null
); );
@ -110,7 +127,10 @@ export const SingleList: React.FC<Props> = (props) => {
title = addSpaceIfCamelCase(currentState?.name ?? ""); title = addSpaceIfCamelCase(currentState?.name ?? "");
break; break;
case "labels": case "labels":
title = issueLabels?.find((label) => label.id === groupTitle)?.name ?? "None"; title =
[...(issueLabels ?? []), ...(workspaceLabels ?? [])]?.find(
(label) => label.id === groupTitle
)?.name ?? "None";
break; break;
case "project": case "project":
title = projects?.find((p) => p.id === groupTitle)?.name ?? "None"; title = projects?.find((p) => p.id === groupTitle)?.name ?? "None";
@ -164,7 +184,9 @@ export const SingleList: React.FC<Props> = (props) => {
break; break;
case "labels": case "labels":
const labelColor = const labelColor =
issueLabels?.find((label) => label.id === groupTitle)?.color ?? "#000000"; [...(issueLabels ?? []), ...(workspaceLabels ?? [])]?.find(
(label) => label.id === groupTitle
)?.color ?? "#000000";
icon = ( icon = (
<span <span
className="h-3 w-3 flex-shrink-0 rounded-full" className="h-3 w-3 flex-shrink-0 rounded-full"

View File

@ -234,7 +234,7 @@ export const MyIssuesViewOptions: React.FC = () => {
displayFilters?.layout !== "spreadsheet" && ( displayFilters?.layout !== "spreadsheet" && (
<> <>
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<h4 className="text-custom-text-200">Show empty states</h4> <h4 className="text-custom-text-200">Show empty groups</h4>
<div className="w-28"> <div className="w-28">
<ToggleSwitch <ToggleSwitch
value={displayFilters?.show_empty_groups ?? true} value={displayFilters?.show_empty_groups ?? true}

View File

@ -266,7 +266,7 @@ export const ProfileIssuesViewOptions: React.FC = () => {
displayFilters?.layout !== "spreadsheet" && ( displayFilters?.layout !== "spreadsheet" && (
<> <>
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<h4 className="text-custom-text-200">Show empty states</h4> <h4 className="text-custom-text-200">Show empty groups</h4>
<div className="w-28"> <div className="w-28">
<ToggleSwitch <ToggleSwitch
value={displayFilters?.show_empty_groups ?? true} value={displayFilters?.show_empty_groups ?? true}

View File

@ -31,15 +31,53 @@ import { BoltOutlined, GridViewOutlined } from "@mui/icons-material";
import emptyDashboard from "public/empty-state/dashboard.svg"; import emptyDashboard from "public/empty-state/dashboard.svg";
import githubBlackImage from "/public/logos/github-black.png"; import githubBlackImage from "/public/logos/github-black.png";
import githubWhiteImage from "/public/logos/github-white.png"; import githubWhiteImage from "/public/logos/github-white.png";
// helpers
import { render12HourFormatTime, renderShortDate } from "helpers/date-time.helper";
// types // types
import { ICurrentUserResponse } from "types"; import { ICurrentUserResponse } from "types";
import type { NextPage } from "next"; import type { NextPage } from "next";
// fetch-keys // fetch-keys
import { CURRENT_USER, USER_WORKSPACE_DASHBOARD } from "constants/fetch-keys"; import { CURRENT_USER, USER_WORKSPACE_DASHBOARD } from "constants/fetch-keys";
// constants
import { DAYS } from "constants/project"; const Greeting = ({ user }: { user: ICurrentUserResponse | undefined }) => {
const currentTime = new Date();
const hour = new Intl.DateTimeFormat("en-US", {
hour12: false,
hour: "numeric",
}).format(currentTime);
const date = new Intl.DateTimeFormat("en-US", {
month: "short",
day: "numeric",
}).format(currentTime);
const weekDay = new Intl.DateTimeFormat("en-US", {
weekday: "long",
}).format(currentTime);
const timeString = new Intl.DateTimeFormat("en-US", {
timeZone: user?.user_timezone,
hour12: false, // Use 24-hour format
hour: "2-digit",
minute: "2-digit",
}).format(currentTime);
const greeting =
parseInt(hour, 10) < 12 ? "morning" : parseInt(hour, 10) < 18 ? "afternoon" : "evening";
return (
<div>
<h3 className="text-2xl font-semibold">
Good {greeting}, {user?.first_name} {user?.last_name}
</h3>
<h6 className="text-custom-text-400 font-medium flex items-center gap-2">
<div>{greeting === "morning" ? "🌤️" : greeting === "afternoon" ? "🌥️" : "🌙️"}</div>
<div>
{weekDay}, {date} {timeString}
</div>
</h6>
</div>
);
};
const WorkspacePage: NextPage = () => { const WorkspacePage: NextPage = () => {
const [month, setMonth] = useState(new Date().getMonth() + 1); const [month, setMonth] = useState(new Date().getMonth() + 1);
@ -58,10 +96,6 @@ const WorkspacePage: NextPage = () => {
workspaceSlug ? () => userService.userWorkspaceDashboard(workspaceSlug as string, month) : null workspaceSlug ? () => userService.userWorkspaceDashboard(workspaceSlug as string, month) : null
); );
const today = new Date();
const greeting =
today.getHours() < 12 ? "morning" : today.getHours() < 18 ? "afternoon" : "evening";
useEffect(() => { useEffect(() => {
if (!workspaceSlug) return; if (!workspaceSlug) return;
@ -128,17 +162,7 @@ const WorkspacePage: NextPage = () => {
</div> </div>
)} )}
<div className="p-8 space-y-8"> <div className="p-8 space-y-8">
<div> <Greeting user={user} />
<h3 className="text-2xl font-semibold">
Good {greeting}, {user?.first_name} {user?.last_name}
</h3>
<h6 className="text-custom-text-400 font-medium flex items-center gap-2">
<div>{greeting === "morning" ? "🌤️" : greeting === "afternoon" ? "🌥️" : "🌙️"}</div>
<div>
{DAYS[today.getDay()]}, {renderShortDate(today)} {render12HourFormatTime(today)}
</div>
</h6>
</div>
{projects ? ( {projects ? (
projects.length > 0 ? ( projects.length > 0 ? (