Skip to content

Commit

Permalink
feat: add datediff label ui
Browse files Browse the repository at this point in the history
  • Loading branch information
tosaken1116 committed Oct 28, 2023
1 parent 81f7f3b commit 362a88c
Show file tree
Hide file tree
Showing 5 changed files with 288 additions and 0 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-tabs": "^1.0.4",
"@radix-ui/react-tooltip": "^1.0.7",
"date-fns": "^2.30.0",
"lucide-react": "^0.288.0",
"next": "13.5.6",
"react": "18.2.0",
Expand Down
74 changes: 74 additions & 0 deletions src/components/ui/DateDiffLabel/constant.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
export const DATE_DIFF_LABEL = {
en: {
second: {
future: { one: 'sec later', other: 'secs later' },
past: { one: 'sec ago', other: 'secs ago' },
},
minute: {
future: { one: 'min later', other: 'mins later' },
past: { one: 'min ago', other: 'mins ago' },
},
hour: {
future: { one: 'hour later', other: 'hours later' },
past: { one: 'hour ago', other: 'hours ago' },
},
day: {
future: { one: 'day later', other: 'days later' },
past: { one: 'day ago', other: 'days ago' },
},
week: {
future: { one: 'week later', other: 'weeks later' },
past: { one: 'week ago', other: 'weeks ago' },
},
month: {
future: { one: 'month later', other: 'months later' },
past: { one: 'month ago', other: 'months ago' },
},
year: {
future: { one: 'year later', other: 'years later' },
past: { one: 'year ago', other: 'years ago' },
},
} as const,
ja: {
second: {
future: { one: '秒後', other: '秒後' },
past: { one: '秒前', other: '秒前' },
},
minute: {
future: { one: '分後', other: '分後' },
past: { one: '分前', other: '分前' },
},
hour: {
future: { one: '時間後', other: '時間後' },
past: { one: '時間前', other: '時間前' },
},
day: {
future: { one: '日後', other: '日後' },
past: { one: '日前', other: '日前' },
},
week: {
future: { one: '週間後', other: '週間後' },
past: { one: '週間前', other: '週間前' },
},
month: {
future: { one: 'ヶ月後', other: 'ヶ月後' },
past: { one: 'ヶ月前', other: 'ヶ月前' },
},
year: {
future: { one: '年後', other: '年後' },
past: { one: '年前', other: '年前' },
},
} as const,
} as const;

export const MINUTE = 60;

export const HOUR = 60 * MINUTE;

export const DAY = 24 * HOUR;

export const WEEK = 7 * DAY;

export const MONTH = 30 * DAY;

export const YEAR = 365 * DAY;
135 changes: 135 additions & 0 deletions src/components/ui/DateDiffLabel/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import { DateDiffLabel } from '.';

import type { Meta, StoryObj } from '@storybook/react';

const meta: Meta<typeof DateDiffLabel> = {
title: 'DateDiffLabel',
component: DateDiffLabel,
parameters: {
layout: 'centered',
},
tags: ['autodocs'],
};

export default meta;
type Story = StoryObj<typeof DateDiffLabel>;

export const Default: Story = {
args: { date: new Date(), lang: 'ja' },
};

export const English: Story = {
args: { date: new Date(), lang: 'en' },
};

export const SecAgo: Story = {
args: { date: new Date(Date.now() - 1000), lang: 'ja' },
};

export const MinAgo: Story = {
args: { date: new Date(Date.now() - 1000 * 60), lang: 'ja' },
};

export const HourAgo: Story = {
args: { date: new Date(Date.now() - 1000 * 60 * 60), lang: 'ja' },
};

export const DayAgo: Story = {
args: { date: new Date(Date.now() - 1000 * 60 * 60 * 24), lang: 'ja' },
};

export const WeekAgo: Story = {
args: { date: new Date(Date.now() - 1000 * 60 * 60 * 24 * 7), lang: 'ja' },
};

export const MonthAgo: Story = {
args: { date: new Date(Date.now() - 1000 * 60 * 60 * 24 * 30), lang: 'ja' },
};

export const YearAgo: Story = {
args: { date: new Date(Date.now() - 1000 * 60 * 60 * 24 * 365), lang: 'ja' },
};

export const SecAgoEn: Story = {
args: { date: new Date(Date.now() - 1000), lang: 'en' },
};

export const MinAgoEn: Story = {
args: { date: new Date(Date.now() - 1000 * 60), lang: 'en' },
};

export const HourAgoEn: Story = {
args: { date: new Date(Date.now() - 1000 * 60 * 60), lang: 'en' },
};

export const DayAgoEn: Story = {
args: { date: new Date(Date.now() - 1000 * 60 * 60 * 24), lang: 'en' },
};

export const WeekAgoEn: Story = {
args: { date: new Date(Date.now() - 1000 * 60 * 60 * 24 * 7), lang: 'en' },
};

export const MonthAgoEn: Story = {
args: { date: new Date(Date.now() - 1000 * 60 * 60 * 24 * 30), lang: 'en' },
};

export const YearAgoEn: Story = {
args: { date: new Date(Date.now() - 1000 * 60 * 60 * 24 * 365), lang: 'en' },
};

export const SecFuture: Story = {
args: { date: new Date(Date.now() + 1001), lang: 'ja' },
};

export const MinFuture: Story = {
args: { date: new Date(Date.now() + 1000 * 61), lang: 'ja' },
};

export const HourFuture: Story = {
args: { date: new Date(Date.now() + 1000 * 60 * 61), lang: 'ja' },
};

export const DayFuture: Story = {
args: { date: new Date(Date.now() + 1000 * 60 * 60 * 25), lang: 'ja' },
};

export const WeekFuture: Story = {
args: { date: new Date(Date.now() + 1000 * 60 * 60 * 24 * 8), lang: 'ja' },
};

export const MonthFuture: Story = {
args: { date: new Date(Date.now() + 1000 * 60 * 60 * 24 * 31), lang: 'ja' },
};

export const YearFuture: Story = {
args: { date: new Date(Date.now() + 1000 * 60 * 60 * 24 * 366), lang: 'ja' },
};

export const SecFutureEn: Story = {
args: { date: new Date(Date.now() + 1001), lang: 'en' },
};

export const MinFutureEn: Story = {
args: { date: new Date(Date.now() + 1000 * 61), lang: 'en' },
};

export const HourFutureEn: Story = {
args: { date: new Date(Date.now() + 1000 * 60 * 61), lang: 'en' },
};

export const DayFutureEn: Story = {
args: { date: new Date(Date.now() + 1000 * 60 * 60 * 25), lang: 'en' },
};

export const WeekFutureEn: Story = {
args: { date: new Date(Date.now() + 1000 * 60 * 60 * 24 * 8), lang: 'en' },
};

export const MonthFutureEn: Story = {
args: { date: new Date(Date.now() + 1000 * 60 * 60 * 24 * 31), lang: 'en' },
};

export const YearFutureEn: Story = {
args: { date: new Date(Date.now() + 1000 * 60 * 60 * 24 * 366), lang: 'en' },
};
15 changes: 15 additions & 0 deletions src/components/ui/DateDiffLabel/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { DateToDiffLabel } from './logic';

type Prop = {
lang: 'ja' | 'en';
date: Date;
now?: Date;
};
export const DateDiffLabel: React.FC<Prop> = ({ lang, date, now }) => {
const nowDate = now ?? new Date();
return (
<time dateTime={date.toISOString()}>
{DateToDiffLabel(date, nowDate, lang)}
</time>
);
};
63 changes: 63 additions & 0 deletions src/components/ui/DateDiffLabel/logic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import {
DATE_DIFF_LABEL,
DAY,
HOUR,
MINUTE,
MONTH,
WEEK,
YEAR,
} from './constant';

export const DateToDiffLabel = (
date: Date,
now: Date,
lang: 'en' | 'ja'
): string => {
const diffInSeconds = Math.abs(
Math.floor((now.getTime() - date.getTime()) / 1000)
);
const period = now.getTime() - date.getTime() > 0 ? 'past' : 'future';

if (diffInSeconds < MINUTE)
return `${diffInSeconds}${
DATE_DIFF_LABEL[`${lang}`]['second'][period][
diffInSeconds == 1 ? 'one' : 'other'
]
}`;
if (diffInSeconds < HOUR)
return `${Math.floor(diffInSeconds / MINUTE)}${
DATE_DIFF_LABEL[lang]['minute'][period][
Math.floor(diffInSeconds / MINUTE) == 1 ? 'one' : 'other'
]
}`;
if (diffInSeconds < DAY)
return `${Math.floor(diffInSeconds / HOUR)}${
DATE_DIFF_LABEL[lang]['hour'][period][
Math.floor(diffInSeconds / HOUR) == 1 ? 'one' : 'other'
]
}`;
if (diffInSeconds < WEEK)
return `${Math.floor(diffInSeconds / DAY)}${
DATE_DIFF_LABEL[lang]['day'][period][
Math.floor(diffInSeconds / DAY) == 1 ? 'one' : 'other'
]
}`;
if (diffInSeconds < MONTH)
return `${Math.floor(diffInSeconds / WEEK)}${
DATE_DIFF_LABEL[lang]['week'][period][
Math.floor(diffInSeconds / WEEK) == 1 ? 'one' : 'other'
]
}`;
if (diffInSeconds < YEAR)
return `${Math.floor(diffInSeconds / MONTH)}${
DATE_DIFF_LABEL[lang]['month'][period][
Math.floor(diffInSeconds / MONTH) == 1 ? 'one' : 'other'
]
}`;

return `${Math.floor(diffInSeconds / YEAR)}${
DATE_DIFF_LABEL[lang]['year'][period][
Math.floor(diffInSeconds / YEAR) == 1 ? 'one' : 'other'
]
}`;
};

0 comments on commit 362a88c

Please sign in to comment.