diff --git a/src/__tests__/BerlinClock.test.tsx b/src/__tests__/BerlinClock.test.tsx index f30e9d2..ff10d83 100644 --- a/src/__tests__/BerlinClock.test.tsx +++ b/src/__tests__/BerlinClock.test.tsx @@ -1,54 +1,61 @@ -import { render, screen } from '@testing-library/react'; -import { BerlinClock } from '../containers/BerlinClock'; -import { LampState } from '../types'; +import { render, screen } from "@testing-library/react"; +import { BerlinClock } from "../containers/BerlinClock"; +import { LampState } from "../types"; -describe('BerlinClock', () => { +describe("BerlinClock", () => { const testClock = { secondsRow: [LampState.Y], fiveHours: [LampState.R, LampState.R, LampState.R, LampState.O], oneHour: [LampState.R, LampState.R, LampState.R, LampState.R], fiveMinutes: [ - LampState.Y, LampState.Y, LampState.R, - LampState.Y, LampState.Y, LampState.R, - LampState.O, LampState.O, LampState.O, - LampState.O, LampState.O, + LampState.Y, + LampState.Y, + LampState.R, + LampState.Y, + LampState.Y, + LampState.R, + LampState.O, + LampState.O, + LampState.O, + LampState.O, + LampState.O, ], oneMinute: [LampState.O, LampState.O, LampState.O, LampState.O], }; - it('renders nothing when disabled', () => { - const { container } = render(); - expect(container.innerHTML).toBe(''); + it("renders nothing when disabled", () => { + const { container } = render( + , + ); + expect(container.innerHTML).toBe(""); }); - it('renders all five rows when enabled', () => { + it("renders all five rows when enabled", () => { render(); - expect(screen.getByTestId('seconds-row')).toBeInTheDocument(); - expect(screen.getByTestId('five-hours-row')).toBeInTheDocument(); - expect(screen.getByTestId('single-hours-row')).toBeInTheDocument(); - expect(screen.getByTestId('five-minutes-row')).toBeInTheDocument(); - expect(screen.getByTestId('single-minutes-row')).toBeInTheDocument(); + expect(screen.getByTestId("seconds-row")).toBeInTheDocument(); + expect(screen.getByTestId("five-hours-row")).toBeInTheDocument(); + expect(screen.getByTestId("single-hours-row")).toBeInTheDocument(); + expect(screen.getByTestId("five-minutes-row")).toBeInTheDocument(); + expect(screen.getByTestId("single-minutes-row")).toBeInTheDocument(); }); - it('renders the correct number of lamps in seconds-row', () => { + it("renders the correct number of lamps in seconds-row", () => { render(); - const secRow = screen.getByTestId('seconds-row'); - const lampLine = secRow.querySelector('[data-testid="lamp-line"]'); - expect(lampLine?.children).toHaveLength(1); + const secRow = screen.getByTestId("seconds-row"); + expect(secRow.children).toHaveLength(1); }); - it('renders the correct number of lamps in five-hours-row', () => { + it("renders the correct number of lamps in five-hours-row", () => { render(); - const row = screen.getByTestId('five-hours-row'); - const lampLine = row.querySelector('[data-testid="lamp-line"]'); - expect(lampLine?.children).toHaveLength(4); + const row = screen.getByTestId("five-hours-row"); + expect(row.children).toHaveLength(4); }); - it('renders correct aria-labels in the seconds lamp', () => { + it("renders correct aria-labels in the seconds lamp", () => { render(); - const secRow = screen.getByTestId('seconds-row'); - const span = secRow.querySelector('span'); - expect(span).toHaveAttribute('aria-label', 'Y'); + const secRow = screen.getByTestId("seconds-row"); + const span = secRow.querySelector("span"); + expect(span).toHaveAttribute("aria-label", "Y"); }); }); diff --git a/src/__tests__/DigitalClock.test.tsx b/src/__tests__/DigitalClock.test.tsx index 20e53f5..8c6b710 100644 --- a/src/__tests__/DigitalClock.test.tsx +++ b/src/__tests__/DigitalClock.test.tsx @@ -1,20 +1,20 @@ -import { render, screen, fireEvent } from '@testing-library/react'; -import { DigitalClock } from '../containers/DigitalClock'; -import * as utils from '../utils'; +import { render, screen, fireEvent } from "@testing-library/react"; +import { DigitalClock } from "../containers/DigitalClock"; +import * as utils from "../utils"; -vi.mock('../utils'); +vi.mock("../utils"); const mockedDateToDigital = vi.mocked(utils.dateToDigital); const mockedDigitalToDate = vi.mocked(utils.digitalToDate); -describe('DigitalClock', () => { +describe("DigitalClock", () => { const onTimeChangeMock = vi.fn(); beforeEach(() => { vi.clearAllMocks(); - mockedDateToDigital.mockReturnValue('14:30:15'); + mockedDateToDigital.mockReturnValue("14:30:15"); mockedDigitalToDate.mockImplementation((str: string) => { - const parts = str.split(':'); + const parts = str.split(":"); if (parts.length !== 3) return new Date(NaN); const [h, m, s] = parts.map(Number); if (isNaN(h) || isNaN(m) || isNaN(s)) return new Date(NaN); @@ -24,58 +24,58 @@ describe('DigitalClock', () => { }); }); - it('renders nothing when disabled', () => { + it("renders nothing when disabled", () => { const { container } = render( , ); - expect(container.innerHTML).toBe(''); + expect(container.innerHTML).toBe(""); }); - it('renders the digital time and input when enabled', () => { + it("renders the digital time and input when enabled", () => { render( , ); - expect(screen.getByTestId('digital-clock')).toHaveTextContent('14:30:15'); - expect(screen.getByTestId('time-input')).toBeInTheDocument(); + expect(screen.getByTestId("digital-clock")).toHaveTextContent("14:30:15"); + expect(screen.getByTestId("time-input")).toBeInTheDocument(); }); - it('calls onTimeChange when a valid time is entered', () => { + it("calls onTimeChange when a valid time is entered", () => { render( , ); - const input = screen.getByTestId('time-input'); - fireEvent.change(input, { target: { value: '12:00:00' } }); + const input = screen.getByTestId("time-input"); + fireEvent.change(input, { target: { value: "12:00:00" } }); expect(onTimeChangeMock).toHaveBeenCalledTimes(1); const expectedDate = new Date(2025, 0, 1, 12, 0, 0, 0); expect(onTimeChangeMock).toHaveBeenCalledWith(expectedDate); - expect(input).toHaveValue('12:00:00'); + expect(input).toHaveValue("12:00:00"); }); - it('does not call onTimeChange when an invalid time is entered', () => { + it("does not call onTimeChange when an invalid time is entered", () => { render( , ); - const input = screen.getByTestId('time-input'); - fireEvent.change(input, { target: { value: 'notatime' } }); + const input = screen.getByTestId("time-input"); + fireEvent.change(input, { target: { value: "notatime" } }); expect(onTimeChangeMock).not.toHaveBeenCalled(); - expect(input).toHaveValue('notatime'); + expect(input).toHaveValue("notatime"); }); }); diff --git a/src/__tests__/Lamp.test.tsx b/src/__tests__/Lamp.test.tsx index 96495b1..fcb839f 100644 --- a/src/__tests__/Lamp.test.tsx +++ b/src/__tests__/Lamp.test.tsx @@ -1,22 +1,22 @@ -import { render } from '@testing-library/react'; -import { Lamp } from '../components/Lamp'; -import { LampState } from '../types'; +import { render } from "@testing-library/react"; +import { Lamp } from "../components/Lamp"; +import { LampState } from "../types"; -describe('Lamp', () => { - it('renders without crashing', () => { +describe("Lamp", () => { + it("renders without crashing", () => { render(); // If it doesn't throw, we're good. }); it.each([ - ['Y' as LampState, 'Y'], - ['R' as LampState, 'R'], - ['O' as LampState, 'O'], - ['N' as LampState, 'N'], + ["Y" as LampState, "Y"], + ["R" as LampState, "R"], + ["O" as LampState, "O"], + ["N" as LampState, "N"], ])('displays aria-label "%s" for state %s', (state, expectedLabel) => { const { container } = render(); // The root element should have the correct aria-label const lampElement = container.firstChild as HTMLElement; - expect(lampElement).toHaveAttribute('aria-label', expectedLabel); + expect(lampElement).toHaveAttribute("aria-label", expectedLabel); }); }); diff --git a/src/__tests__/LampLine.test.tsx b/src/__tests__/LampLine.test.tsx index 77dbec3..7264838 100644 --- a/src/__tests__/LampLine.test.tsx +++ b/src/__tests__/LampLine.test.tsx @@ -1,33 +1,33 @@ -import { render, screen } from '@testing-library/react'; -import { LampLine } from '../components/LampLine'; -import { LampState } from '../types'; +import { render, screen } from "@testing-library/react"; +import { LampLine } from "../components/LampLine"; +import { LampState } from "../types"; -describe('LampLine', () => { - it('renders without crashing', () => { +describe("LampLine", () => { + it("renders without crashing", () => { render(); }); - it('renders the correct number of lamps', () => { + it("renders the correct number of lamps", () => { const states = [LampState.Y, LampState.R, LampState.O]; render(); - const container = screen.getByTestId('lamp-line'); + const container = screen.getByTestId("lamp-line"); expect(container.children).toHaveLength(states.length); }); - it('displays correct aria-labels for each lamp', () => { + it("displays correct aria-labels for each lamp", () => { const states = [LampState.Y, LampState.R, LampState.O, LampState.N]; render(); - const container = screen.getByTestId('lamp-line'); - const lampSpans = container.querySelectorAll('span'); + const container = screen.getByTestId("lamp-line"); + const lampSpans = container.querySelectorAll("span"); expect(lampSpans).toHaveLength(states.length); lampSpans.forEach((span, index) => { - expect(span).toHaveAttribute('aria-label', states[index]); + expect(span).toHaveAttribute("aria-label", states[index]); }); }); - it('renders no lamps when given an empty array', () => { + it("renders no lamps when given an empty array", () => { render(); - const container = screen.getByTestId('lamp-line'); + const container = screen.getByTestId("lamp-line"); expect(container.children).toHaveLength(0); }); }); diff --git a/src/__tests__/TimeConverter.test.tsx b/src/__tests__/TimeConverter.test.tsx index db0d02b..12198ae 100644 --- a/src/__tests__/TimeConverter.test.tsx +++ b/src/__tests__/TimeConverter.test.tsx @@ -1,18 +1,29 @@ -import { render, screen, fireEvent } from '@testing-library/react'; -import { TimeConverter } from '../containers/TimeConverter'; -import { useCurrentTime } from '../hooks/useCurrentTime'; +import { render, screen, fireEvent } from "@testing-library/react"; +import { TimeConverter } from "../containers/TimeConverter"; +import { useCurrentTime } from "../hooks/useCurrentTime"; -vi.mock('../hooks/useCurrentTime'); -vi.mock('../containers/BerlinClock', () => ({ +vi.mock("../hooks/useCurrentTime"); +vi.mock("../containers/BerlinClock", () => ({ BerlinClock: ({ enabled }: { enabled: boolean }) => ( -
{enabled ? 'enabled' : 'disabled'}
+
{enabled ? "enabled" : "disabled"}
), })); -vi.mock('../containers/DigitalClock', () => ({ - DigitalClock: ({ enabled, currentTime, onTimeChange }: { enabled: boolean; currentTime: Date; onTimeChange: (d: Date) => void }) => ( +vi.mock("../containers/DigitalClock", () => ({ + DigitalClock: ({ + enabled, + currentTime, + onTimeChange, + }: { + enabled: boolean; + currentTime: Date; + onTimeChange: (d: Date) => void; + }) => (
{currentTime.toISOString()} - {!enabled && disabled} @@ -22,7 +33,7 @@ vi.mock('../containers/DigitalClock', () => ({ const mockedUseCurrentTime = vi.mocked(useCurrentTime); -describe('TimeConverter', () => { +describe("TimeConverter", () => { const setCurrentTimeMock = vi.fn(); const baseDate = new Date(2025, 0, 1, 14, 30, 15); @@ -34,23 +45,25 @@ describe('TimeConverter', () => { }); }); - it('renders the checkbox, BerlinClock, and DigitalClock', () => { + it("renders the checkbox, BerlinClock, and DigitalClock", () => { render(); - expect(screen.getByTestId('use-system-time')).toBeInTheDocument(); - expect(screen.getByTestId('berlin-clock')).toHaveTextContent('enabled'); - expect(screen.getByTestId('digital-clock-wrapper')).toBeInTheDocument(); + expect(screen.getByTestId("use-system-time")).toBeInTheDocument(); + expect(screen.getByTestId("berlin-clock")).toHaveTextContent("enabled"); + expect(screen.getByTestId("digital-clock-wrapper")).toBeInTheDocument(); }); - it('disables both clocks when checkbox is checked', () => { + it("disables both clocks when checkbox is checked", () => { render(); - fireEvent.click(screen.getByTestId('use-system-time')); - expect(screen.getByTestId('berlin-clock')).toHaveTextContent('disabled'); - expect(screen.getByTestId('disabled-indicator')).toBeInTheDocument(); + fireEvent.click(screen.getByTestId("use-system-time")); + expect(screen.getByTestId("berlin-clock")).toHaveTextContent("disabled"); + expect(screen.getByTestId("disabled-indicator")).toBeInTheDocument(); }); - it('calls setCurrentTime when DigitalClock triggers onTimeChange', () => { + it("calls setCurrentTime when DigitalClock triggers onTimeChange", () => { render(); - fireEvent.click(screen.getByTestId('set-time')); - expect(setCurrentTimeMock).toHaveBeenCalledWith(new Date(2025, 0, 1, 12, 0, 0)); + fireEvent.click(screen.getByTestId("set-time")); + expect(setCurrentTimeMock).toHaveBeenCalledWith( + new Date(2025, 0, 1, 12, 0, 0), + ); }); }); diff --git a/src/__tests__/useCurrentTime.test.ts b/src/__tests__/useCurrentTime.test.ts index 5348220..d625fc5 100644 --- a/src/__tests__/useCurrentTime.test.ts +++ b/src/__tests__/useCurrentTime.test.ts @@ -1,10 +1,10 @@ -import { renderHook, act } from '@testing-library/react'; -import { useCurrentTime } from '../hooks/useCurrentTime'; +import { renderHook } from "@testing-library/react"; +import { useCurrentTime } from "../hooks/useCurrentTime"; -describe('useCurrentTime', () => { - it('returns a date and setter', () => { +describe("useCurrentTime", () => { + it("returns a date and setter", () => { const { result } = renderHook(() => useCurrentTime()); expect(result.current.currentTime).toBeInstanceOf(Date); - expect(typeof result.current.setCurrentTime).toBe('function'); + expect(typeof result.current.setCurrentTime).toBe("function"); }); }); diff --git a/src/__tests__/utils.test.ts b/src/__tests__/utils.test.ts index 359c697..264035a 100644 --- a/src/__tests__/utils.test.ts +++ b/src/__tests__/utils.test.ts @@ -1,86 +1,157 @@ -import { dateToDigital, digitalToDate, dateToBerlin, berlinToDate } from '../utils'; -import { LampState } from '../types'; +import { + dateToDigital, + digitalToDate, + dateToBerlin, + berlinToDate, +} from "../utils"; +import { LampState } from "../types"; -describe('Utils', () => { - describe('dateToDigital', () => { +describe("Utils", () => { + describe("dateToDigital", () => { it('returns "HH:mm:ss" for a given date', () => { const date = new Date(2025, 0, 1, 14, 5, 9); - expect(dateToDigital(date)).toBe('14:05:09'); + expect(dateToDigital(date)).toBe("14:05:09"); }); - it('pads single-digit hours, minutes, seconds', () => { + it("pads single-digit hours, minutes, seconds", () => { const date = new Date(2025, 0, 1, 2, 3, 4); - expect(dateToDigital(date)).toBe('02:03:04'); + expect(dateToDigital(date)).toBe("02:03:04"); }); }); - describe('digitalToDate', () => { - it('parses a valid digital string', () => { - const result = digitalToDate('12:34:56'); + describe("digitalToDate", () => { + it("parses a valid digital string", () => { + const result = digitalToDate("12:34:56"); expect(result).toBeInstanceOf(Date); expect(result.getHours()).toBe(12); expect(result.getMinutes()).toBe(34); expect(result.getSeconds()).toBe(56); }); - it('returns an invalid date for invalid input', () => { - const result = digitalToDate('abc'); + it("returns an invalid date for invalid input", () => { + const result = digitalToDate("abc"); expect(isNaN(result.getTime())).toBe(true); }); }); - describe('dateToBerlin', () => { + describe("dateToBerlin", () => { const makeTime = (h: number, m: number, s: number) => { const d = new Date(2025, 0, 1, h, m, s); return d; }; - it('returns correct clock for 00:00:00', () => { + it("returns correct clock for 00:00:00", () => { const clock = dateToBerlin(makeTime(0, 0, 0)); expect(clock.secondsRow).toEqual([LampState.Y]); - expect(clock.fiveHours).toEqual([LampState.O, LampState.O, LampState.O, LampState.O]); - expect(clock.oneHour).toEqual([LampState.O, LampState.O, LampState.O, LampState.O]); - expect(clock.fiveMinutes).toEqual([ - LampState.O, LampState.O, LampState.O, - LampState.O, LampState.O, LampState.O, - LampState.O, LampState.O, LampState.O, - LampState.O, LampState.O, + expect(clock.fiveHours).toEqual([ + LampState.O, + LampState.O, + LampState.O, + LampState.O, + ]); + expect(clock.oneHour).toEqual([ + LampState.O, + LampState.O, + LampState.O, + LampState.O, + ]); + expect(clock.fiveMinutes).toEqual([ + LampState.O, + LampState.O, + LampState.O, + LampState.O, + LampState.O, + LampState.O, + LampState.O, + LampState.O, + LampState.O, + LampState.O, + LampState.O, + ]); + expect(clock.oneMinute).toEqual([ + LampState.O, + LampState.O, + LampState.O, + LampState.O, ]); - expect(clock.oneMinute).toEqual([LampState.O, LampState.O, LampState.O, LampState.O]); }); - it('returns correct clock for 23:59:59', () => { + it("returns correct clock for 23:59:59", () => { const clock = dateToBerlin(makeTime(23, 59, 59)); expect(clock.secondsRow).toEqual([LampState.O]); - expect(clock.fiveHours).toEqual([LampState.R, LampState.R, LampState.R, LampState.R]); - expect(clock.oneHour).toEqual([LampState.R, LampState.R, LampState.R, LampState.O]); - expect(clock.fiveMinutes).toEqual([ - LampState.Y, LampState.Y, LampState.R, - LampState.Y, LampState.Y, LampState.R, - LampState.Y, LampState.Y, LampState.R, - LampState.Y, LampState.Y, + expect(clock.fiveHours).toEqual([ + LampState.R, + LampState.R, + LampState.R, + LampState.R, + ]); + expect(clock.oneHour).toEqual([ + LampState.R, + LampState.R, + LampState.R, + LampState.O, + ]); + expect(clock.fiveMinutes).toEqual([ + LampState.Y, + LampState.Y, + LampState.R, + LampState.Y, + LampState.Y, + LampState.R, + LampState.Y, + LampState.Y, + LampState.R, + LampState.Y, + LampState.Y, + ]); + expect(clock.oneMinute).toEqual([ + LampState.Y, + LampState.Y, + LampState.Y, + LampState.Y, ]); - expect(clock.oneMinute).toEqual([LampState.Y, LampState.Y, LampState.Y, LampState.Y]); }); - it('returns correct clock for 12:34:00', () => { + it("returns correct clock for 12:34:00", () => { const clock = dateToBerlin(makeTime(12, 34, 0)); expect(clock.secondsRow).toEqual([LampState.Y]); - expect(clock.fiveHours).toEqual([LampState.R, LampState.R, LampState.O, LampState.O]); - expect(clock.oneHour).toEqual([LampState.R, LampState.R, LampState.O, LampState.O]); + expect(clock.fiveHours).toEqual([ + LampState.R, + LampState.R, + LampState.O, + LampState.O, + ]); + expect(clock.oneHour).toEqual([ + LampState.R, + LampState.R, + LampState.O, + LampState.O, + ]); const expectedFiveMinutes = [ - LampState.Y, LampState.Y, LampState.R, - LampState.Y, LampState.Y, LampState.R, - LampState.O, LampState.O, LampState.O, - LampState.O, LampState.O, + LampState.Y, + LampState.Y, + LampState.R, + LampState.Y, + LampState.Y, + LampState.R, + LampState.O, + LampState.O, + LampState.O, + LampState.O, + LampState.O, ]; expect(clock.fiveMinutes).toEqual(expectedFiveMinutes); - expect(clock.oneMinute).toEqual([LampState.Y, LampState.Y, LampState.Y, LampState.Y]); + expect(clock.oneMinute).toEqual([ + LampState.Y, + LampState.Y, + LampState.Y, + LampState.Y, + ]); }); }); - describe('berlinToDate', () => { - it('roundtrips correctly: dateToBerlin then berlinToDate returns the original date (seconds floor to even)', () => { + describe("berlinToDate", () => { + it("roundtrips correctly: dateToBerlin then berlinToDate returns the original date (seconds floor to even)", () => { const original = new Date(2025, 0, 1, 14, 30, 0); const clock = dateToBerlin(original); const result = berlinToDate(clock); @@ -89,7 +160,7 @@ describe('Utils', () => { expect(result.getSeconds()).toBe(0); }); - it('roundtrips with odd seconds: result seconds will be zero (only parity stored)', () => { + it("roundtrips with odd seconds: result seconds will be zero (only parity stored)", () => { const original = new Date(2025, 0, 1, 23, 59, 59); const clock = dateToBerlin(original); const result = berlinToDate(clock); @@ -98,16 +169,23 @@ describe('Utils', () => { expect(result.getSeconds()).toBe(0); }); - it('converts a known Berlin clock to the correct time', () => { + it("converts a known Berlin clock to the correct time", () => { const clock = { secondsRow: [LampState.Y], fiveHours: [LampState.R, LampState.R, LampState.O, LampState.O], oneHour: [LampState.R, LampState.R, LampState.O, LampState.O], fiveMinutes: [ - LampState.Y, LampState.Y, LampState.R, - LampState.Y, LampState.Y, LampState.R, - LampState.O, LampState.O, LampState.O, - LampState.O, LampState.O, + LampState.Y, + LampState.Y, + LampState.R, + LampState.Y, + LampState.Y, + LampState.R, + LampState.O, + LampState.O, + LampState.O, + LampState.O, + LampState.O, ], oneMinute: [LampState.Y, LampState.Y, LampState.Y, LampState.Y], }; diff --git a/src/components/Lamp.tsx b/src/components/Lamp.tsx index 84e56b6..2ee0f57 100644 --- a/src/components/Lamp.tsx +++ b/src/components/Lamp.tsx @@ -1,10 +1,41 @@ -import { LampState } from '../types'; +import React from "react"; +import { LampState } from "../types"; interface LampProps { state: LampState; id?: string; + variant?: "alone" | "first" | "last" | "middle"; } -export function Lamp({ state, id }: LampProps) { - return ; +function getBackgroundColor(state: LampState): string { + if (state === LampState.R) return "#ff3333"; + if (state === LampState.Y) return "#ffcc00"; + return "#333"; +} + +function getBorderRadius(variant?: LampProps["variant"]): string { + switch (variant) { + case "alone": + return "50%"; + case "first": + return "50% 0 0 50%"; + case "last": + return "0 50% 50% 0"; + default: + return "0"; + } +} + +export function Lamp({ state, id, variant }: LampProps) { + const style: React.CSSProperties = { + display: "inline-block", + width: 20, + height: 20, + backgroundColor: getBackgroundColor(state), + borderRadius: getBorderRadius(variant), + margin: 1, + transition: "background-color 0.2s", + }; + + return ; } diff --git a/src/components/LampLine.tsx b/src/components/LampLine.tsx index 92432d6..41ac281 100644 --- a/src/components/LampLine.tsx +++ b/src/components/LampLine.tsx @@ -1,5 +1,5 @@ -import { LampState } from '../types'; -import { Lamp } from './Lamp'; +import { LampState } from "../types"; +import { Lamp } from "./Lamp"; interface LampLineProps { states: LampState[]; @@ -7,11 +7,32 @@ interface LampLineProps { } export function LampLine({ states, rowTestId }: LampLineProps) { + const len = states.length; return ( -
- {states.map((state, index) => ( - - ))} +
+ {states.map((state, index) => { + let variant: "alone" | "first" | "last" | "middle" | undefined; + if (len === 1) { + variant = "alone"; + } else if (index === 0) { + variant = "first"; + } else if (index === len - 1) { + variant = "last"; + } else { + variant = "middle"; + } + return ( + + ); + })}
); } diff --git a/src/containers/BerlinClock.tsx b/src/containers/BerlinClock.tsx index 31fb3dc..718063f 100644 --- a/src/containers/BerlinClock.tsx +++ b/src/containers/BerlinClock.tsx @@ -12,8 +12,11 @@ export function BerlinClock({ enabled, clock }: BerlinClockProps) { return (
-
- +
+
diff --git a/src/containers/DigitalClock.tsx b/src/containers/DigitalClock.tsx index c97c4d0..a2c7678 100644 --- a/src/containers/DigitalClock.tsx +++ b/src/containers/DigitalClock.tsx @@ -1,5 +1,5 @@ -import { useState } from 'react'; -import { dateToDigital, digitalToDate } from '../utils'; +import { useState } from "react"; +import { dateToDigital, digitalToDate } from "../utils"; interface DigitalClockProps { enabled: boolean; @@ -7,7 +7,11 @@ interface DigitalClockProps { onTimeChange: (time: Date) => void; } -export function DigitalClock({ enabled, currentTime, onTimeChange }: DigitalClockProps) { +export function DigitalClock({ + enabled, + currentTime, + onTimeChange, +}: DigitalClockProps) { const [inputValue, setInputValue] = useState(dateToDigital(currentTime)); const handleChange = (e: React.ChangeEvent) => { diff --git a/src/hooks/useCurrentTime.ts b/src/hooks/useCurrentTime.ts index da9055d..adc7c3f 100644 --- a/src/hooks/useCurrentTime.ts +++ b/src/hooks/useCurrentTime.ts @@ -1,4 +1,4 @@ -import { useState } from 'react'; +import { useState } from "react"; export function useCurrentTime(): { currentTime: Date; diff --git a/src/setupTests.ts b/src/setupTests.ts index 7b0828b..d0de870 100644 --- a/src/setupTests.ts +++ b/src/setupTests.ts @@ -1 +1 @@ -import '@testing-library/jest-dom'; +import "@testing-library/jest-dom"; diff --git a/src/types/index.ts b/src/types/index.ts index 8ec6dc0..20f7489 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,8 +1,8 @@ export enum LampState { - Y = 'Y', // Yellow - R = 'R', // Red - O = 'O', // Off - N = 'N', // None / undefined + Y = "Y", // Yellow + R = "R", // Red + O = "O", // Off + N = "N", // None / undefined } export interface BerlinClock { diff --git a/src/utils/index.ts b/src/utils/index.ts index f497273..71a8069 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,13 +1,13 @@ -import type { BerlinClock } from '../types'; -import { LampState } from '../types'; +import type { BerlinClock } from "../types"; +import { LampState } from "../types"; export function dateToDigital(date: Date): string { - const pad = (n: number) => n.toString().padStart(2, '0'); + const pad = (n: number) => n.toString().padStart(2, "0"); return `${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`; } export function digitalToDate(digital: string): Date { - const parts = digital.split(':'); + const parts = digital.split(":"); if (parts.length !== 3) return new Date(NaN); const [h, m, s] = parts.map(Number); if (isNaN(h) || isNaN(m) || isNaN(s)) return new Date(NaN); @@ -65,8 +65,7 @@ export function berlinToDate(berlin: BerlinClock): Date { arr.filter((s) => s === LampState.R || s === LampState.Y).length; const hours = countR(berlin.fiveHours) * 5 + countR(berlin.oneHour); - const minutes = - countYorR(berlin.fiveMinutes) * 5 + countY(berlin.oneMinute); + const minutes = countYorR(berlin.fiveMinutes) * 5 + countY(berlin.oneMinute); const d = new Date(); d.setHours(hours, minutes, 0, 0);