diff --git a/src/features/online-board/components/TransferBar/TransferTime.test.tsx b/src/features/online-board/components/TransferBar/TransferTime.test.tsx
new file mode 100644
index 00000000..e1128f27
--- /dev/null
+++ b/src/features/online-board/components/TransferBar/TransferTime.test.tsx
@@ -0,0 +1,23 @@
+// @vitest-environment jsdom
+import { describe, it, expect } from "vitest";
+import { render, screen } from "@testing-library/react";
+import { TransferTime } from "./TransferTime.js";
+
+describe("TransferTime", () => {
+ it("renders '1h 30m' for valid inputs", () => {
+ render();
+ expect(screen.getByText("1h 30m")).toBeTruthy();
+ });
+
+ it("returns null when arrivalUtc is empty string", () => {
+ const { container } = render();
+ expect(container.firstChild).toBeNull();
+ });
+
+ it("returns null when departure is before arrival", () => {
+ const { container } = render(
+ ,
+ );
+ expect(container.firstChild).toBeNull();
+ });
+});
diff --git a/src/features/online-board/components/TransferBar/TransferTime.tsx b/src/features/online-board/components/TransferBar/TransferTime.tsx
new file mode 100644
index 00000000..ae7f6293
--- /dev/null
+++ b/src/features/online-board/components/TransferBar/TransferTime.tsx
@@ -0,0 +1,18 @@
+import type { FC } from "react";
+import { computeTransferMinutes, formatMinutesAsDuration } from "./computeTransferTime.js";
+
+export interface TransferTimeProps {
+ arrivalUtc: string;
+ departureUtc: string;
+}
+
+export const TransferTime: FC = ({ arrivalUtc, departureUtc }) => {
+ const minutes = computeTransferMinutes(arrivalUtc, departureUtc);
+ if (minutes === null) return null;
+
+ return (
+
+ {formatMinutesAsDuration(minutes)}
+
+ );
+};