Skip to content

Commit

Permalink
Added status expiration and general status stuff;
Browse files Browse the repository at this point in the history
  • Loading branch information
stef-coenen committed Dec 23, 2024
1 parent 46c8d6e commit 56422cc
Showing 1 changed file with 121 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ import {
ActionButton,
DialogWrapper,
EmojiSelector,
formatDateExludingYearIfCurrent,
Input,
Label,
Select,
t,
usePortal,
} from '@homebase-id/common-app';
import { Ellipsis, Save, Times } from '@homebase-id/common-app/icons';
import { useEffect, useState } from 'react';
import { useEffect, useMemo, useState } from 'react';
import { createPortal } from 'react-dom';
import { useMyStatus } from '../../../hooks/community/status/useMyStatus';
import { useCommunity } from '../../../hooks/community/useCommunity';
Expand All @@ -30,17 +33,23 @@ export const MyProfileStatus = ({ className }: { className?: string }) => {
return (
<>
<ActionButton
key={myStatus?.status || myStatus?.emoji || 'none'}
icon={hasStatus ? undefined : Ellipsis}
size="none"
type="mute"
className={`opacity-50 hover:opacity-100 ${className || ''}`}
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
setManageStatusDialogOpen(true);
}}
title={myStatus?.status}
title={
hasStatus
? `"${myStatus?.status || myStatus?.emoji}" ${myStatus?.validTill ? `${t('till')} ${formatDateExludingYearIfCurrent(new Date(myStatus.validTill))}` : ''}`
: undefined
}
>
{myStatus?.emoji}
{hasStatus && (myStatus?.emoji || '💬')}
</ActionButton>
{community && isManageStatusDialogOpen ? (
<StatusDialog
Expand All @@ -60,12 +69,21 @@ export const ProfileStatus = ({ odinId, className }: { odinId: string; className
const {
get: { data: myStatus, isFetched },
} = useMyStatus({ community, odinId });
const hasStatus = myStatus?.emoji || myStatus?.status;
const hasStatus =
(myStatus?.emoji || myStatus?.status) &&
(!myStatus?.validTill || new Date(myStatus.validTill) > new Date());

if (!community || !isFetched || !hasStatus) return null;

return (
<span title={myStatus.status} className={className}>
<span
title={
hasStatus
? `"${myStatus?.status || myStatus?.emoji}" ${myStatus?.validTill ? `${t('till')} ${formatDateExludingYearIfCurrent(new Date(myStatus.validTill))}` : ''}`
: undefined
}
className={className}
>
{myStatus?.emoji || '💬'}
</span>
);
Expand Down Expand Up @@ -120,56 +138,107 @@ export const StatusDialog = ({
});
};

const options = useMemo(() => {
const thirtyMinutes = new Date();
thirtyMinutes.setMinutes(thirtyMinutes.getMinutes() + 30);

const oneHour = new Date();
oneHour.setHours(oneHour.getHours() + 1);

const fourHours = new Date();
fourHours.setHours(fourHours.getHours() + 4);

const endOfDay = new Date();
endOfDay.setHours(23, 59, 59, 999);

return [
{ label: t(`Don't clear`), value: undefined },
{ label: t('30 minutes'), value: thirtyMinutes },
{ label: t('1 hour'), value: oneHour },
{ label: t('4 hours'), value: fourHours },
{ label: t('Today'), value: endOfDay },
];
}, []);

if (!isOpen) return null;

const dialog = (
<DialogWrapper
title={t('Set a status')}
onClose={onClose}
isSidePanel={false}
isOverflowLess={true}
>
<form onSubmit={doSubmit}>
<div className="relative flex w-full flex-row rounded-lg border">
<EmojiSelector
wrapperClassName="relative flex flex-row justify-center items-center"
className="text-xl text-foreground/70 hover:text-opacity-100"
onInput={(val) => setDraftStatus((old) => ({ ...(old || {}), emoji: val }))}
isOpen={isEmojiOpen}
onClose={() => setIsEmojiOpen(false)}
defaultValue={draftStatus?.emoji}
/>
<Input
className="border-0"
placeholder={t(`What's your status?`)}
onChange={(e) => setDraftStatus((old) => ({ ...old, status: e.target.value }))}
/>
</div>
<div className="mt-5 flex flex-col gap-4 md:flex-row-reverse">
<ActionButton
type={'primary'}
disabled={!draftStatus}
state={saveStatus}
onClick={doSubmit}
icon={Save}
>
{t('Save')}
</ActionButton>
<ActionButton
type={'secondary'}
onClick={(e) => {
e.preventDefault();
onClose();
}}
>
{t('Cancel')}
</ActionButton>
<ActionButton type={'secondary'} icon={Times} onClick={doClear} className="mr-auto">
{t('Clear')}
</ActionButton>
</div>
</form>
</DialogWrapper>
<div onClick={(e) => e.stopPropagation()}>
<DialogWrapper
title={t('Set a status')}
onClose={onClose}
isSidePanel={false}
isOverflowLess={true}
>
<form onSubmit={doSubmit}>
<div className="relative flex w-full flex-row rounded-lg border">
<EmojiSelector
wrapperClassName="relative flex flex-row justify-center items-center"
className="text-xl text-foreground/70 hover:text-opacity-100"
onInput={(val) => setDraftStatus((old) => ({ ...(old || {}), emoji: val }))}
isOpen={isEmojiOpen}
onClose={() => setIsEmojiOpen(false)}
defaultValue={draftStatus?.emoji || '💬'}
/>
<Input
className="border-0"
placeholder={t(`What's your status?`)}
onChange={(e) => setDraftStatus((old) => ({ ...old, status: e.target.value }))}
/>
</div>
<div className="mt-5">
<Label>{t('Remove status after...')}</Label>
<Select
className="border py-3"
onChange={(e) => {
const expiry = options.find((o) => o.value?.getTime() === Number(e.target.value));
setDraftStatus((old) => ({
...old,
validTill: expiry?.value?.getTime() || undefined,
}));
}}
>
{options.map((option) => (
<option key={option.label} value={option.value?.getTime()}>
{option.label}
</option>
))}
</Select>
</div>
<div className="mt-5 flex flex-col gap-4 md:flex-row-reverse">
<ActionButton
type={'primary'}
disabled={!draftStatus}
state={saveStatus}
onClick={doSubmit}
icon={Save}
>
{t('Save')}
</ActionButton>
<ActionButton
type={'secondary'}
onClick={(e) => {
e.preventDefault();
onClose();
}}
className="hidden md:flex"
>
{t('Cancel')}
</ActionButton>
{draftStatus ? (
<ActionButton
type={'secondary'}
icon={Times}
onClick={doClear}
className="md:mr-auto"
>
{t('Clear')}
</ActionButton>
) : null}
</div>
</form>
</DialogWrapper>
</div>
);

return createPortal(dialog, target);
Expand Down

0 comments on commit 56422cc

Please sign in to comment.