@zthun/romulator-web 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.html CHANGED
@@ -4,7 +4,7 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>Romulator: Organize your Games</title>
7
- <script type="module" crossorigin src="/assets/index-CtJiKvl7.js"></script>
7
+ <script type="module" crossorigin src="/assets/index-Dla_HUr2.js"></script>
8
8
  </head>
9
9
  <body>
10
10
  <div id="zthunworks-romulator"></div>
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zthun/romulator-web",
3
- "version": "1.1.0",
3
+ "version": "1.3.0",
4
4
  "description": "Romulator frontend",
5
5
  "author": "Anthony Bonta",
6
6
  "license": "MIT",
@@ -18,21 +18,21 @@
18
18
  "access": "public"
19
19
  },
20
20
  "devDependencies": {
21
- "@types/node": "^24.0.3",
21
+ "@types/node": "^24.0.7",
22
22
  "@vitejs/plugin-react-swc": "^3.10.2",
23
- "@zthun/cirque": "^7.1.4",
24
- "@zthun/cirque-du-react": "^7.1.4",
25
- "@zthun/fashion-boutique": "^10.1.6",
26
- "@zthun/fashion-tailor": "^10.1.6",
27
- "@zthun/fashion-theme": "^10.1.6",
28
- "@zthun/helpful-fn": "^9.3.0",
29
- "@zthun/helpful-query": "^9.3.0",
30
- "@zthun/helpful-react": "^9.3.0",
31
- "@zthun/janitor-build-config": "^19.2.4",
32
- "@zthun/romulator-client": "^1.1.0",
33
- "@zthun/webigail-http": "^4.0.3",
34
- "@zthun/webigail-rest": "^4.0.3",
35
- "@zthun/webigail-url": "^4.0.3",
23
+ "@zthun/cirque": "^7.1.5",
24
+ "@zthun/cirque-du-react": "^7.1.5",
25
+ "@zthun/fashion-boutique": "^10.2.2",
26
+ "@zthun/fashion-tailor": "^10.2.1",
27
+ "@zthun/fashion-theme": "^10.2.1",
28
+ "@zthun/helpful-fn": "^9.4.0",
29
+ "@zthun/helpful-query": "^9.4.0",
30
+ "@zthun/helpful-react": "^9.4.1",
31
+ "@zthun/janitor-build-config": "^19.2.6",
32
+ "@zthun/romulator-client": "^1.3.0",
33
+ "@zthun/webigail-http": "^4.0.4",
34
+ "@zthun/webigail-rest": "^4.0.4",
35
+ "@zthun/webigail-url": "^4.0.4",
36
36
  "history": "^5.3.0",
37
37
  "lodash-es": "^4.17.21",
38
38
  "react": "^19.1.0",
@@ -44,5 +44,5 @@
44
44
  "vitest": "^3.2.4",
45
45
  "vitest-mock-extended": "^3.1.0"
46
46
  },
47
- "gitHead": "52bd432dd2df0980d450b20de58d7f58c6d0da94"
47
+ "gitHead": "07a97ff0c9df05eca1879b00dfce1a159be7d521"
48
48
  }
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -1,12 +1,7 @@
1
1
  import type { IZCard } from "@zthun/fashion-boutique";
2
- import {
3
- ZCard,
4
- ZIconFontAwesome,
5
- ZImageSource,
6
- ZStack,
7
- } from "@zthun/fashion-boutique";
2
+ import { useCss, ZCard, ZImageSource, ZStack } from "@zthun/fashion-boutique";
8
3
  import { ZSizeFixed } from "@zthun/fashion-tailor";
9
- import { ZOrientation } from "@zthun/helpful-fn";
4
+ import { css, cssJoinDefined, ZOrientation } from "@zthun/helpful-fn";
10
5
 
11
6
  export interface IZRomulatorSystemAvatarCard {
12
7
  system: any;
@@ -16,23 +11,26 @@ export interface IZRomulatorSystemAvatarCard {
16
11
 
17
12
  export function ZRomulatorSystemAvatarCard(props: IZRomulatorSystemAvatarCard) {
18
13
  const { system, CardProps } = props;
19
- // TODO: Add support for other regions
20
- const src = `/systems/us/${system.id}-256x256.png`;
14
+ const src = `/systems/wheel/${system.id}.png`;
15
+
16
+ const _className = useCss(css`
17
+ &.ZRomulatorSystemCard-root .ZRomulatorSystemCard-avatar {
18
+ height: 100%;
19
+ width: 100%;
20
+ }
21
+ `);
21
22
 
22
23
  return (
23
24
  <ZCard
24
- className="ZRomulatorSystemCard-root"
25
- TitleProps={{
26
- avatar: <ZIconFontAwesome name="gamepad" width={ZSizeFixed.Small} />,
27
- heading: system.short,
28
- subHeading: system.name,
29
- }}
25
+ className={cssJoinDefined("ZRomulatorSystemCard-root", _className)}
30
26
  name={system.id}
31
27
  {...CardProps}
32
28
  >
33
29
  <ZStack
30
+ className="ZRomulatorSystemCard-avatar"
34
31
  orientation={ZOrientation.Horizontal}
35
- justify={{ content: "center" }}
32
+ justify={{ content: "center", items: "center" }}
33
+ align={{ content: "center", items: "center" }}
36
34
  >
37
35
  <ZImageSource src={src} width={ZSizeFixed.ExtraLarge} />
38
36
  </ZStack>
@@ -13,7 +13,10 @@ import {
13
13
  ZDataSourceStatic,
14
14
  ZFilterBinaryBuilder,
15
15
  } from "@zthun/helpful-query";
16
- import { ZRomulatorSystemBuilder } from "@zthun/romulator-client";
16
+ import {
17
+ ZRomulatorSystemBuilder,
18
+ ZRomulatorSystemId,
19
+ } from "@zthun/romulator-client";
17
20
  import type { History } from "history";
18
21
  import { createMemoryHistory } from "history";
19
22
  import { noop } from "lodash-es";
@@ -30,7 +33,9 @@ interface ZRomulatorSystemPageProps {
30
33
  }
31
34
 
32
35
  describe("SystemPage", () => {
33
- const nes = new ZRomulatorSystemBuilder().id("nes").build();
36
+ const nes = new ZRomulatorSystemBuilder()
37
+ .id(ZRomulatorSystemId.Nintendo)
38
+ .build();
34
39
 
35
40
  let _driver: IZCircusDriver;
36
41
  let _renderer: IZCircusSetup;
@@ -1,10 +1,8 @@
1
1
  import { ZCircusBy, ZCircusComponentModel } from "@zthun/cirque";
2
2
  import {
3
- ZButtonComponentModel,
3
+ ZBoxComponentModel,
4
4
  ZGridViewComponentModel,
5
5
  } from "@zthun/fashion-boutique";
6
- import { required } from "@zthun/helpful-fn";
7
- import { ZRomulatorSystemAvatarCardComponentModel } from "./system-avatar-card.cm.mjs";
8
6
 
9
7
  export class ZRomulatorSystemsPageComponentModel extends ZCircusComponentModel {
10
8
  public static readonly Selector = ".ZRomulatorSystemsPage-root";
@@ -13,27 +11,17 @@ export class ZRomulatorSystemsPageComponentModel extends ZCircusComponentModel {
13
11
  return Promise.resolve(new ZGridViewComponentModel(this.driver));
14
12
  }
15
13
 
16
- public async system(
17
- id: string,
18
- ): Promise<ZRomulatorSystemAvatarCardComponentModel | null> {
14
+ public async system(id: string): Promise<ZBoxComponentModel | null> {
19
15
  const grid = await this.grid();
20
- return ZCircusBy.optional(
21
- grid.driver,
22
- ZRomulatorSystemAvatarCardComponentModel,
23
- id,
24
- );
16
+ return ZCircusBy.optional(grid.driver, ZBoxComponentModel, id);
25
17
  }
26
18
 
27
- public async systems(): Promise<ZRomulatorSystemAvatarCardComponentModel[]> {
19
+ public async systems(): Promise<ZBoxComponentModel[]> {
28
20
  const grid = await this.grid();
29
- return ZCircusBy.all(grid.driver, ZRomulatorSystemAvatarCardComponentModel);
30
- }
31
-
32
- public async more(id: string): Promise<ZButtonComponentModel> {
33
- const system = await this.system(id);
34
- const card = await system?.card();
35
- const footer = await required(card?.footer());
36
-
37
- return ZCircusBy.first(footer, ZButtonComponentModel, "more");
21
+ return ZCircusBy.all(
22
+ grid.driver,
23
+ ZBoxComponentModel,
24
+ ".ZRomulatorSystemsPage-tile",
25
+ );
38
26
  }
39
27
  }
@@ -3,7 +3,10 @@ import { ZCircusBy } from "@zthun/cirque";
3
3
  import { ZCircusSetupRenderer } from "@zthun/cirque-du-react";
4
4
  import { ZTestRouter } from "@zthun/fashion-boutique";
5
5
  import { ZDataSourceStatic } from "@zthun/helpful-query";
6
- import { ZRomulatorSystemBuilder } from "@zthun/romulator-client";
6
+ import {
7
+ ZRomulatorSystemBuilder,
8
+ ZRomulatorSystemId,
9
+ } from "@zthun/romulator-client";
7
10
  import type { MemoryHistory } from "history";
8
11
  import { createMemoryHistory } from "history";
9
12
  import type { Mocked } from "vitest";
@@ -15,8 +18,12 @@ import type { IZRomulatorSystemsService } from "./systems-service.mjs";
15
18
  import { ZRomulatorSystemsServiceContext } from "./systems-service.mjs";
16
19
 
17
20
  describe("ZRomulatorSystemsPage", () => {
18
- const nes = new ZRomulatorSystemBuilder().id("nes").build();
19
- const snes = new ZRomulatorSystemBuilder().id("snes").build();
21
+ const nes = new ZRomulatorSystemBuilder()
22
+ .id(ZRomulatorSystemId.Nintendo)
23
+ .build();
24
+ const snes = new ZRomulatorSystemBuilder()
25
+ .id(ZRomulatorSystemId.SuperNintendo)
26
+ .build();
20
27
  const systems = [nes, snes];
21
28
 
22
29
  let _systemsService: Mocked<IZRomulatorSystemsService>;
@@ -60,22 +67,22 @@ describe("ZRomulatorSystemsPage", () => {
60
67
  const expected = systems.map((s) => s.id);
61
68
 
62
69
  // Act.
63
- const cards = await target.systems();
64
- const actual = await Promise.all(cards.map((s) => s.id()));
65
-
70
+ const tiles = await target.systems();
71
+ const ids = tiles.map((s) => s.driver.attribute("data-name"));
72
+ const actual = await Promise.all(ids);
66
73
  // Assert.
67
74
  expect(actual).toEqual(expected);
68
75
  });
69
76
 
70
- it("should navigate me to the system page when I click on the navigate button", async () => {
77
+ it("should navigate me to the system page when I click on one", async () => {
71
78
  // Arrange.
72
79
  const target = await createTestTarget();
73
80
 
74
81
  // Act.
75
- const more = await target.more(nes.id);
76
- await more.click();
82
+ const system = await target.system(nes.id);
83
+ await system?.click();
77
84
 
78
85
  // Assert.
79
- expect(_history.location.pathname).toEqual(`/systems/${nes.id}`);
86
+ expect(_history.location.pathname).toEqual(`/${nes.id}`);
80
87
  });
81
88
  });
@@ -1,48 +1,108 @@
1
1
  import {
2
+ useCss,
2
3
  useFashionTheme,
3
4
  useNavigate,
4
- ZButton,
5
+ ZBox,
6
+ ZBreadcrumbsLocation,
7
+ ZCard,
8
+ ZContentTitle,
5
9
  ZGridView,
10
+ ZIconFontAwesome,
11
+ ZImageSource,
12
+ ZStack,
6
13
  } from "@zthun/fashion-boutique";
7
14
  import { ZSizeFixed, ZSizeVaried } from "@zthun/fashion-tailor";
8
- import { ZRomulatorSystemAvatarCard } from "./system-avatar-card.js";
15
+ import { css, cssJoinDefined, ZOrientation } from "@zthun/helpful-fn";
16
+ import { ZDataRequestBuilder, ZSortBuilder } from "@zthun/helpful-query";
17
+ import type { IZRomulatorSystem } from "@zthun/romulator-client";
18
+ import { useState } from "react";
9
19
  import { useSystemsService } from "./systems-service.mjs";
10
20
 
21
+ const DefaultSystemSortOrder = new ZSortBuilder()
22
+ .ascending("generation")
23
+ .ascending("name")
24
+ .build();
25
+
26
+ const DefaultSystemRequest = new ZDataRequestBuilder()
27
+ .sort(DefaultSystemSortOrder)
28
+ .build();
29
+
11
30
  export function ZRomulatorSystemsPage() {
12
- const { secondary } = useFashionTheme();
31
+ const { body } = useFashionTheme();
13
32
  const navigate = useNavigate();
14
33
  const source = useSystemsService();
34
+ const [request, setRequest] = useState(DefaultSystemRequest);
15
35
 
16
- return (
17
- <ZGridView
18
- className="ZRomulatorSystemsPage-root"
19
- GridProps={{
20
- columns: {
21
- xl: "1fr 1fr 1fr 1fr",
22
- lg: "1fr 1fr 1fr",
23
- md: "1fr 1fr",
24
- sm: "1fr",
25
- },
26
- gap: ZSizeFixed.Medium,
27
- }}
28
- dataSource={source}
29
- renderItem={(s) => (
30
- <ZRomulatorSystemAvatarCard
31
- key={s.id}
32
- system={s}
33
- CardProps={{
34
- footer: (
35
- <ZButton
36
- fashion={secondary}
37
- label="More"
38
- name="more"
36
+ const tile = useCss(css`
37
+ & {
38
+ height: 100%;
39
+ }
40
+ `);
41
+
42
+ const renderTile = (system: IZRomulatorSystem) => {
43
+ const wheel = `/systems/wheel/${system.id}.png`;
44
+ return (
45
+ <ZBox
46
+ className="ZRomulatorSystemsPage-tile"
47
+ fashion={body}
48
+ interactive
49
+ key={system.id}
50
+ cursor="pointer"
51
+ padding={ZSizeFixed.Small}
52
+ data-name={system.id}
53
+ onClick={() => navigate(system.id)}
54
+ >
55
+ <ZStack
56
+ className={cssJoinDefined(tile)}
57
+ gap={ZSizeFixed.Medium}
58
+ orientation={ZOrientation.Horizontal}
59
+ justify={{ content: "center" }}
60
+ align={{ items: "center" }}
61
+ >
62
+ <ZContentTitle
63
+ avatar={
64
+ <ZImageSource
65
+ src={wheel}
66
+ height={ZSizeVaried.Full}
39
67
  width={ZSizeVaried.Full}
40
- onClick={() => navigate(`/systems/${s.id}`)}
41
68
  />
42
- ),
69
+ }
70
+ />
71
+ </ZStack>
72
+ </ZBox>
73
+ );
74
+ };
75
+
76
+ return (
77
+ <ZStack gap={ZSizeFixed.Medium}>
78
+ <ZBreadcrumbsLocation />
79
+ <ZCard
80
+ width={ZSizeVaried.Full}
81
+ TitleProps={{
82
+ avatar: (
83
+ <ZIconFontAwesome name="puzzle-piece" width={ZSizeFixed.Medium} />
84
+ ),
85
+ heading: "Systems",
86
+ subHeading: "Your games organized by system",
87
+ }}
88
+ >
89
+ <ZGridView
90
+ className="ZRomulatorSystemsPage-root"
91
+ GridProps={{
92
+ columns: {
93
+ xl: "1fr 1fr 1fr 1fr",
94
+ lg: "1fr 1fr 1fr",
95
+ md: "1fr 1fr",
96
+ sm: "1fr",
97
+ },
98
+ gap: ZSizeFixed.Medium,
43
99
  }}
100
+ value={request}
101
+ onValueChange={setRequest}
102
+ dataSource={source}
103
+ renderItem={renderTile}
44
104
  />
45
- )}
46
- />
105
+ </ZCard>
106
+ </ZStack>
47
107
  );
48
108
  }
@@ -3,7 +3,10 @@ import type { IZCircusReactHook } from "@zthun/cirque-du-react";
3
3
  import { ZCircusSetupHook } from "@zthun/cirque-du-react";
4
4
  import { ZDataRequestBuilder, ZPageBuilder } from "@zthun/helpful-query";
5
5
  import type { IZRomulatorSystem } from "@zthun/romulator-client";
6
- import { ZRomulatorSystemBuilder } from "@zthun/romulator-client";
6
+ import {
7
+ ZRomulatorSystemBuilder,
8
+ ZRomulatorSystemId,
9
+ } from "@zthun/romulator-client";
7
10
  import {
8
11
  ZHttpMethod,
9
12
  ZHttpResultBuilder,
@@ -26,8 +29,12 @@ describe("SystemsService", () => {
26
29
  let _http: ZHttpServiceMock;
27
30
  let _env: Mocked<IZRomulatorEnvironmentService>;
28
31
 
29
- const nes = new ZRomulatorSystemBuilder().id("nes").build();
30
- const snes = new ZRomulatorSystemBuilder().id("snes").build();
32
+ const nes = new ZRomulatorSystemBuilder()
33
+ .id(ZRomulatorSystemId.Nintendo)
34
+ .build();
35
+ const snes = new ZRomulatorSystemBuilder()
36
+ .id(ZRomulatorSystemId.SuperNintendo)
37
+ .build();
31
38
  const systems = [nes, snes];
32
39
 
33
40
  beforeEach(async () => {
Binary file
Binary file
Binary file
Binary file