You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-11-21 23:00:50 +03:00
DateTime component
This commit is contained in:
18
frontend/package-lock.json
generated
18
frontend/package-lock.json
generated
@@ -8,6 +8,7 @@
|
||||
"name": "mas-frontend",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"date-fns": "^2.29.3",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-relay": "^14.1.0",
|
||||
@@ -9105,6 +9106,18 @@
|
||||
"integrity": "sha512-qTcEYLen3r7ojZNgVUaRggOI+KM7jrKxXeSHhogh/TWxYMeONEMqY+hmkobiYQozsGIyg9OYVzO4ZIfoB4I0pQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/date-fns": {
|
||||
"version": "2.29.3",
|
||||
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz",
|
||||
"integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==",
|
||||
"engines": {
|
||||
"node": ">=0.11"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/date-fns"
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||
@@ -30395,6 +30408,11 @@
|
||||
"integrity": "sha512-qTcEYLen3r7ojZNgVUaRggOI+KM7jrKxXeSHhogh/TWxYMeONEMqY+hmkobiYQozsGIyg9OYVzO4ZIfoB4I0pQ==",
|
||||
"dev": true
|
||||
},
|
||||
"date-fns": {
|
||||
"version": "2.29.3",
|
||||
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz",
|
||||
"integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA=="
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
"build-storybook": "storybook build"
|
||||
},
|
||||
"dependencies": {
|
||||
"date-fns": "^2.29.3",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-relay": "^14.1.0",
|
||||
|
||||
@@ -14,8 +14,10 @@
|
||||
|
||||
import type { BrowserSession_session$key } from "./__generated__/BrowserSession_session.graphql";
|
||||
import { graphql, useFragment } from "react-relay";
|
||||
|
||||
import Block from "./Block";
|
||||
import { Body, Code, Subtitle } from "./Typography";
|
||||
import { Body, Subtitle } from "./Typography";
|
||||
import DateTime from "./DateTime";
|
||||
|
||||
type Props = {
|
||||
session: BrowserSession_session$key;
|
||||
@@ -37,17 +39,22 @@ const BrowserSession: React.FC<Props> = ({ session, isCurrent }) => {
|
||||
session
|
||||
);
|
||||
|
||||
const lastAuthentication = data.lastAuthentication?.createdAt || "never";
|
||||
const lastAuthentication = data.lastAuthentication?.createdAt;
|
||||
const createdAt = data.createdAt;
|
||||
|
||||
return (
|
||||
<Block>
|
||||
{isCurrent && <Subtitle>Current session</Subtitle>}
|
||||
<Body>
|
||||
Started: <Code>{createdAt}</Code>
|
||||
Started: <DateTime datetime={createdAt} />
|
||||
</Body>
|
||||
<Body>
|
||||
Last authentication: <Code>{lastAuthentication}</Code>
|
||||
Last authentication:{" "}
|
||||
{lastAuthentication ? (
|
||||
<DateTime datetime={lastAuthentication} />
|
||||
) : (
|
||||
"never"
|
||||
)}
|
||||
</Body>
|
||||
</Block>
|
||||
);
|
||||
|
||||
@@ -16,6 +16,7 @@ import type { CompatSsoLogin_login$key } from "./__generated__/CompatSsoLogin_lo
|
||||
import { graphql, useFragment } from "react-relay";
|
||||
import Block from "./Block";
|
||||
import { Body, Bold, Code } from "./Typography";
|
||||
import DateTime from "./DateTime";
|
||||
|
||||
type Props = {
|
||||
login: CompatSsoLogin_login$key;
|
||||
@@ -44,11 +45,11 @@ const CompatSsoLogin: React.FC<Props> = ({ login }) => {
|
||||
info = (
|
||||
<>
|
||||
<Body>
|
||||
Started: <Code>{data.session.createdAt}</Code>
|
||||
Started: <DateTime datetime={data.session.createdAt} />
|
||||
</Body>
|
||||
{data.session.finishedAt ? (
|
||||
<Body>
|
||||
Finished: <Code>{data.session.createdAt}</Code>
|
||||
Finished: <DateTime datetime={data.session.finishedAt} />
|
||||
</Body>
|
||||
) : null}
|
||||
<Body>
|
||||
@@ -61,7 +62,7 @@ const CompatSsoLogin: React.FC<Props> = ({ login }) => {
|
||||
return (
|
||||
<Block>
|
||||
<Body>
|
||||
Requested: <Code>{data.createdAt}</Code>
|
||||
Requested: <DateTime datetime={data.createdAt} />
|
||||
</Body>
|
||||
{info}
|
||||
<Body>
|
||||
|
||||
67
frontend/src/components/DateTime.stories.tsx
Normal file
67
frontend/src/components/DateTime.stories.tsx
Normal file
@@ -0,0 +1,67 @@
|
||||
// Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
import { sub } from "date-fns";
|
||||
|
||||
import DateTime from "./DateTime";
|
||||
|
||||
const now = new Date(2022, 11, 16, 15, 32, 10);
|
||||
|
||||
const meta: Meta<typeof DateTime> = {
|
||||
title: "UI/DateTime",
|
||||
component: DateTime,
|
||||
tags: ["docsPage"],
|
||||
args: {
|
||||
now,
|
||||
datetime: sub(now, { minutes: 30 }),
|
||||
},
|
||||
argTypes: {
|
||||
now: {
|
||||
control: "date",
|
||||
},
|
||||
datetime: {
|
||||
control: "date",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof DateTime>;
|
||||
|
||||
export const Basic: Story = {};
|
||||
|
||||
export const Now: Story = {
|
||||
args: {
|
||||
datetime: now,
|
||||
},
|
||||
};
|
||||
|
||||
export const SecondsAgo: Story = {
|
||||
args: {
|
||||
datetime: sub(now, { seconds: 30 }),
|
||||
},
|
||||
};
|
||||
|
||||
export const MinutesAgo: Story = {
|
||||
args: {
|
||||
datetime: sub(now, { minutes: 5 }),
|
||||
},
|
||||
};
|
||||
|
||||
export const HoursAgo: Story = {
|
||||
args: {
|
||||
datetime: sub(now, { hours: 5 }),
|
||||
},
|
||||
};
|
||||
55
frontend/src/components/DateTime.tsx
Normal file
55
frontend/src/components/DateTime.tsx
Normal file
@@ -0,0 +1,55 @@
|
||||
// Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import {
|
||||
formatISO,
|
||||
intlFormat,
|
||||
intlFormatDistance,
|
||||
differenceInHours,
|
||||
parseISO,
|
||||
} from "date-fns";
|
||||
|
||||
type Props = {
|
||||
className?: string;
|
||||
datetime: Date | string;
|
||||
now?: Date;
|
||||
};
|
||||
|
||||
const DateTime = ({
|
||||
datetime: datetimeProps,
|
||||
now: nowProps,
|
||||
className,
|
||||
}: Props) => {
|
||||
const datetime =
|
||||
typeof datetimeProps === "string" ? parseISO(datetimeProps) : datetimeProps;
|
||||
const now = nowProps || new Date();
|
||||
const text =
|
||||
Math.abs(differenceInHours(now, datetime, { roundingMethod: "round" })) > 1
|
||||
? intlFormat(datetime, {
|
||||
year: "numeric",
|
||||
month: "short",
|
||||
day: "numeric",
|
||||
weekday: "short",
|
||||
hour: "numeric",
|
||||
minute: "numeric",
|
||||
})
|
||||
: intlFormatDistance(datetime, now);
|
||||
return (
|
||||
<time className={className} dateTime={formatISO(datetime)}>
|
||||
{text}
|
||||
</time>
|
||||
);
|
||||
};
|
||||
|
||||
export default DateTime;
|
||||
Reference in New Issue
Block a user