ps99-api 1.2.0 → 2.0.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.
Files changed (141) hide show
  1. package/.idea/runConfigurations/test.xml +11 -0
  2. package/.idea/runConfigurations/test_changing.xml +11 -0
  3. package/.idea/runConfigurations/test_snapshot.xml +11 -0
  4. package/.idea/runConfigurations/test_snapshot_changing.xml +12 -0
  5. package/.idea/webResources.xml +14 -0
  6. package/.releaserc +13 -0
  7. package/dist/index.d.ts +1 -0
  8. package/dist/index.js +1 -0
  9. package/dist/index.js.map +1 -1
  10. package/dist/ps99-api.d.ts +3 -3
  11. package/dist/ps99-api.js +2 -2
  12. package/dist/ps99-api.js.map +1 -1
  13. package/dist/responses/collection/achievement.d.ts +2 -9
  14. package/dist/responses/collection/boost.d.ts +2 -9
  15. package/dist/responses/collection/booth.d.ts +15 -22
  16. package/dist/responses/collection/box.d.ts +14 -21
  17. package/dist/responses/collection/buff.d.ts +2 -9
  18. package/dist/responses/collection/charm.d.ts +13 -20
  19. package/dist/responses/collection/collection-data.d.ts +9 -0
  20. package/dist/responses/collection/collection-data.js +3 -0
  21. package/dist/responses/collection/collection-data.js.map +1 -0
  22. package/dist/responses/collection/currency.d.ts +22 -29
  23. package/dist/responses/collection/egg.d.ts +25 -31
  24. package/dist/responses/collection/enchantment.d.ts +18 -25
  25. package/dist/responses/collection/fishing-rod.d.ts +9 -16
  26. package/dist/responses/collection/fruit.d.ts +15 -22
  27. package/dist/responses/collection/guild-battle.d.ts +6 -13
  28. package/dist/responses/collection/hoverboard.d.ts +27 -34
  29. package/dist/responses/collection/index.d.ts +7 -5
  30. package/dist/responses/collection/lootbox.d.ts +12 -19
  31. package/dist/responses/collection/mastery.d.ts +5 -12
  32. package/dist/responses/collection/merchant.d.ts +6 -13
  33. package/dist/responses/collection/misc-item.d.ts +10 -17
  34. package/dist/responses/collection/pet.d.ts +20 -27
  35. package/dist/responses/collection/potion.d.ts +17 -24
  36. package/dist/responses/collection/random-event.d.ts +9 -16
  37. package/dist/responses/collection/rank.d.ts +7 -22
  38. package/dist/responses/collection/rarity.d.ts +6 -13
  39. package/dist/responses/collection/rebirth.d.ts +4 -11
  40. package/dist/responses/collection/secret-room.d.ts +4 -41
  41. package/dist/responses/collection/seed.d.ts +47 -1
  42. package/dist/responses/collection/shovel.d.ts +4 -11
  43. package/dist/responses/collection/sprinkler.d.ts +14 -21
  44. package/dist/responses/collection/ultimate.d.ts +17 -23
  45. package/dist/responses/collection/upgrade.d.ts +26 -33
  46. package/dist/responses/collection/watering-can.d.ts +5 -12
  47. package/dist/responses/collection/world.d.ts +6 -13
  48. package/dist/responses/collection/zone-flag.d.ts +14 -21
  49. package/dist/responses/collection/zone.d.ts +25 -102
  50. package/dump-result.js +16 -3
  51. package/example-web/react2/package-lock.json +45 -8
  52. package/example-web/react2/package.json +4 -3
  53. package/example-web/react2/public/_redirects +1 -0
  54. package/example-web/react2/public/index.html +1 -1
  55. package/example-web/react2/public/service-worker.js +2 -1
  56. package/example-web/react2/src/App.tsx +26 -141
  57. package/example-web/react2/src/components/AchievementsComponent.tsx +34 -30
  58. package/example-web/react2/src/components/BoostsComponent.tsx +17 -31
  59. package/example-web/react2/src/components/BoothsComponent.tsx +25 -31
  60. package/example-web/react2/src/components/BoxesComponent.tsx +28 -31
  61. package/example-web/react2/src/components/BuffsComponent.tsx +19 -31
  62. package/example-web/react2/src/components/CharmsComponent.tsx +33 -38
  63. package/example-web/react2/src/components/CollectionConfigIndex.tsx +53 -0
  64. package/example-web/react2/src/components/CollectionsIndex.tsx +33 -0
  65. package/example-web/react2/src/components/CurrencyComponent.tsx +58 -31
  66. package/example-web/react2/src/components/DynamicCollectionConfigData.tsx +94 -0
  67. package/example-web/react2/src/components/EggsComponent.tsx +55 -32
  68. package/example-web/react2/src/components/EnchantsComponent.tsx +37 -40
  69. package/example-web/react2/src/components/FishingRodsComponent.tsx +35 -31
  70. package/example-web/react2/src/components/FruitsComponent.tsx +29 -37
  71. package/example-web/react2/src/components/GenericFetchComponent.tsx +53 -0
  72. package/example-web/react2/src/components/GuildBattlesComponent.tsx +70 -40
  73. package/example-web/react2/src/components/Header.tsx +27 -0
  74. package/example-web/react2/src/components/HomePage.tsx +14 -0
  75. package/example-web/react2/src/components/HoverboardsComponent.tsx +40 -31
  76. package/example-web/react2/src/components/ImageComponent.tsx +37 -19
  77. package/example-web/react2/src/components/LootboxesComponent.tsx +19 -31
  78. package/example-web/react2/src/components/MasteryComponent.tsx +48 -30
  79. package/example-web/react2/src/components/MerchantsComponent.tsx +39 -28
  80. package/example-web/react2/src/components/MiscItemsComponent.tsx +28 -46
  81. package/example-web/react2/src/components/PetsComponent.tsx +53 -34
  82. package/example-web/react2/src/components/PotionsComponent.tsx +42 -37
  83. package/example-web/react2/src/components/RandomEventsComponent.tsx +39 -32
  84. package/example-web/react2/src/components/RanksComponent.tsx +80 -29
  85. package/example-web/react2/src/components/RarityComponent.tsx +18 -27
  86. package/example-web/react2/src/components/RebirthsComponent.tsx +32 -29
  87. package/example-web/react2/src/components/SecretRoomsComponent.tsx +18 -28
  88. package/example-web/react2/src/components/SeedsComponent.tsx +66 -31
  89. package/example-web/react2/src/components/ShovelsComponent.tsx +22 -32
  90. package/example-web/react2/src/components/SprinklersComponent.tsx +23 -32
  91. package/example-web/react2/src/components/UltimatesComponent.tsx +29 -33
  92. package/example-web/react2/src/components/UpgradesComponent.tsx +68 -43
  93. package/example-web/react2/src/components/WateringCansComponent.tsx +25 -34
  94. package/example-web/react2/src/components/WorldsComponent.tsx +31 -29
  95. package/example-web/react2/src/components/ZoneFlagsComponent.tsx +27 -32
  96. package/example-web/react2/src/components/ZonesComponent.tsx +84 -29
  97. package/example-web/react2/src/index.tsx +4 -2
  98. package/example-web/react2/tsconfig.json +1 -1
  99. package/example-web/react2/webpack.config.js +2 -6
  100. package/package.json +5 -3
  101. package/src/__tests__/__snapshots__/ps99-api-changes.ts.snap +9852 -7851
  102. package/src/__tests__/__snapshots__/ps99-api-live.ts.snap +1313 -86
  103. package/src/__tests__/ps99-api-changes.ts +1 -1
  104. package/src/index.ts +1 -0
  105. package/src/ps99-api.ts +5 -5
  106. package/src/responses/collection/achievement.ts +12 -9
  107. package/src/responses/collection/boost.ts +9 -9
  108. package/src/responses/collection/booth.ts +17 -22
  109. package/src/responses/collection/box.ts +16 -21
  110. package/src/responses/collection/buff.ts +4 -9
  111. package/src/responses/collection/charm.ts +14 -20
  112. package/src/responses/collection/collection-data.ts +14 -0
  113. package/src/responses/collection/currency.ts +27 -29
  114. package/src/responses/collection/egg.ts +26 -31
  115. package/src/responses/collection/enchantment.ts +19 -25
  116. package/src/responses/collection/fishing-rod.ts +13 -16
  117. package/src/responses/collection/fruit.ts +16 -22
  118. package/src/responses/collection/guild-battle.ts +10 -13
  119. package/src/responses/collection/hoverboard.ts +31 -34
  120. package/src/responses/collection/index.ts +10 -6
  121. package/src/responses/collection/lootbox.ts +13 -19
  122. package/src/responses/collection/mastery.ts +6 -12
  123. package/src/responses/collection/merchant.ts +7 -13
  124. package/src/responses/collection/misc-item.ts +11 -17
  125. package/src/responses/collection/pet.ts +21 -27
  126. package/src/responses/collection/potion.ts +18 -24
  127. package/src/responses/collection/random-event.ts +13 -16
  128. package/src/responses/collection/rank.ts +8 -24
  129. package/src/responses/collection/rarity.ts +7 -13
  130. package/src/responses/collection/rebirth.ts +5 -11
  131. package/src/responses/collection/secret-room.ts +8 -44
  132. package/src/responses/collection/seed.ts +55 -0
  133. package/src/responses/collection/shovel.ts +5 -11
  134. package/src/responses/collection/sprinkler.ts +15 -21
  135. package/src/responses/collection/ultimate.ts +18 -23
  136. package/src/responses/collection/upgrade.ts +27 -33
  137. package/src/responses/collection/watering-can.ts +9 -12
  138. package/src/responses/collection/world.ts +7 -13
  139. package/src/responses/collection/zone-flag.ts +15 -21
  140. package/src/responses/collection/zone.ts +26 -119
  141. package/.release.rc +0 -8
@@ -1,45 +1,75 @@
1
- import React, { useEffect, useState } from "react";
2
- import { GuildBattleData, PetSimulator99API } from "ps99-api";
3
-
4
- const GuildBattlesComponent: React.FC = () => {
5
- const [guildBattles, setGuildBattles] = useState<GuildBattleData[]>([]);
6
-
7
- useEffect(() => {
8
- const fetchGuildBattles = async () => {
9
- const api = new PetSimulator99API();
10
- const response = await api.getCollection("GuildBattles");
11
- if (response.status === "ok") {
12
- setGuildBattles(response.data);
13
- }
14
- };
15
- fetchGuildBattles();
16
- }, []);
1
+ import React from "react";
2
+ import { CollectionConfigData } from "ps99-api";
3
+ import { GenericFetchComponent } from "./GenericFetchComponent";
17
4
 
5
+ const GuildBattlesComponent: React.FC<{
6
+ configData?: CollectionConfigData<"GuildBattles">;
7
+ }> = ({ configData }) => {
18
8
  return (
19
- <div>
20
- <h2>Guild Battles</h2>
21
- <ul>
22
- {guildBattles.map((battle, index) => (
23
- <li key={index}>
24
- <span>Title: {battle.configData.Title}</span>
25
- <span>
26
- Start Time:{" "}
27
- {new Date(battle.configData.StartTime).toLocaleString()}
28
- </span>
29
- <span>
30
- Finish Time:{" "}
31
- {new Date(battle.configData.FinishTime).toLocaleString()}
32
- </span>
33
- <span>
34
- Rewards:{" "}
35
- {battle.configData.Rewards.Gold.map(
36
- (reward) => reward._data.id,
37
- ).join(", ")}
38
- </span>
39
- </li>
40
- ))}
41
- </ul>
42
- </div>
9
+ <GenericFetchComponent<CollectionConfigData<"GuildBattles">>
10
+ collectionName="GuildBattles"
11
+ configData={configData}
12
+ render={(data) => (
13
+ <div>
14
+ <h2>{data.Title}</h2>
15
+ <p>Start Time: {new Date(data.StartTime * 1000).toLocaleString()}</p>
16
+ <p>
17
+ Finish Time: {new Date(data.FinishTime * 1000).toLocaleString()}
18
+ </p>
19
+ {data.HasGoals && <p>Has Goals: Yes</p>}
20
+ <h3>Placement Rewards:</h3>
21
+ <ul>
22
+ {data.PlacementRewards?.map((reward, index) => (
23
+ <li key={index}>
24
+ <p>Item ID: {reward.Item._data.id}</p>
25
+ {reward.Item._data.pt && <p>Points: {reward.Item._data.pt}</p>}
26
+ <p>Best: {reward.Best}</p>
27
+ <p>Worst: {reward.Worst}</p>
28
+ </li>
29
+ ))}
30
+ </ul>
31
+ <h3>Rewards:</h3>
32
+ <div>
33
+ <h4>Gold:</h4>
34
+ <ul>
35
+ {data.Rewards.Gold.map((reward, index) => (
36
+ <li key={index}>
37
+ <p>Item ID: {reward._data.id}</p>
38
+ </li>
39
+ ))}
40
+ </ul>
41
+ <h4>Silver:</h4>
42
+ <ul>
43
+ {data.Rewards.Silver.map((reward, index) => (
44
+ <li key={index}>
45
+ <p>Item ID: {reward._data.id}</p>
46
+ </li>
47
+ ))}
48
+ </ul>
49
+ <h4>Bronze:</h4>
50
+ <ul>
51
+ {data.Rewards.Bronze.map((reward, index) => (
52
+ <li key={index}>
53
+ <p>Item ID: {reward._data.id}</p>
54
+ </li>
55
+ ))}
56
+ </ul>
57
+ {data.Rewards.Good && (
58
+ <div>
59
+ <h4>Good:</h4>
60
+ <ul>
61
+ {data.Rewards.Good.map((reward, index) => (
62
+ <li key={index}>
63
+ <p>Item ID: {reward._data.id}</p>
64
+ </li>
65
+ ))}
66
+ </ul>
67
+ </div>
68
+ )}
69
+ </div>
70
+ </div>
71
+ )}
72
+ />
43
73
  );
44
74
  };
45
75
 
@@ -0,0 +1,27 @@
1
+ import React from "react";
2
+ import { useLocation, Link } from "react-router-dom";
3
+
4
+ const Header: React.FC = () => {
5
+ const location = useLocation();
6
+ const pathnames = location.pathname.split("/").filter((x) => x);
7
+
8
+ return (
9
+ <nav>
10
+ <ol>
11
+ <li>
12
+ <Link to="/">Home</Link>
13
+ </li>
14
+ {pathnames.map((value, index) => {
15
+ const to = `/${pathnames.slice(0, index + 1).join("/")}`;
16
+ return (
17
+ <li key={to}>
18
+ <Link to={to}>{decodeURIComponent(value)}</Link>
19
+ </li>
20
+ );
21
+ })}
22
+ </ol>
23
+ </nav>
24
+ );
25
+ };
26
+
27
+ export default Header;
@@ -0,0 +1,14 @@
1
+ import React from "react";
2
+ import { Link } from "react-router-dom";
3
+
4
+ const HomePage: React.FC = () => {
5
+ return (
6
+ <div>
7
+ <h1>Welcome to Pet Simulator 99 API</h1>
8
+ <p>Select a collection to get started:</p>
9
+ <Link to="/collections">View Collections</Link>
10
+ </div>
11
+ );
12
+ };
13
+
14
+ export default HomePage;
@@ -1,37 +1,46 @@
1
- import React, { useEffect, useState } from "react";
2
- import { HoverboardData, PetSimulator99API } from "ps99-api";
1
+ import React from "react";
2
+ import { CollectionConfigData } from "ps99-api";
3
+ import { GenericFetchComponent } from "./GenericFetchComponent";
3
4
  import ImageComponent from "./ImageComponent";
4
5
 
5
- const HoverboardsComponent: React.FC = () => {
6
- const [hoverboards, setHoverboards] = useState<HoverboardData[]>([]);
7
-
8
- useEffect(() => {
9
- const fetchHoverboards = async () => {
10
- const api = new PetSimulator99API();
11
- const response = await api.getCollection("Hoverboards");
12
- if (response.status === "ok") {
13
- setHoverboards(response.data);
14
- }
15
- };
16
- fetchHoverboards();
17
- }, []);
18
-
6
+ const HoverboardsComponent: React.FC<{
7
+ configData?: CollectionConfigData<"Hoverboards">;
8
+ }> = ({ configData }) => {
19
9
  return (
20
- <div>
21
- <h2>Hoverboards</h2>
22
- <ul>
23
- {hoverboards.map((hoverboard, index) => (
24
- <li key={index}>
25
- <ImageComponent
26
- src={hoverboard.configData.Icon}
27
- alt={hoverboard.configData.DisplayName}
28
- />
29
- <span>{hoverboard.configData.DisplayName}</span>
30
- <span>{hoverboard.configData.Desc}</span>
31
- </li>
32
- ))}
33
- </ul>
34
- </div>
10
+ <GenericFetchComponent<CollectionConfigData<"Hoverboards">>
11
+ collectionName="Hoverboards"
12
+ configData={configData}
13
+ render={(data) => (
14
+ <div>
15
+ <h2>{data.DisplayName}</h2>
16
+ <ImageComponent src={data.Icon} alt={data.DisplayName} />
17
+ <p>Description: {data.Desc}</p>
18
+ <p>Rarity: {data.Rarity.DisplayName}</p>
19
+ <p>Rarity Number: {data.Rarity.RarityNumber}</p>
20
+ {data.Tradable && <p>Tradable: Yes</p>}
21
+ {data.CanBeShiny && <p>Can Be Shiny: Yes</p>}
22
+ {data.HoverHeight && <p>Hover Height: {data.HoverHeight}</p>}
23
+ {data.RotationLimit && <p>Rotation Limit: {data.RotationLimit}</p>}
24
+ {data.ProductId && <p>Product ID: {data.ProductId}</p>}
25
+ {data.Animation && <p>Animation: {data.Animation}</p>}
26
+ {data.BobRate && <p>Bob Rate: {data.BobRate}</p>}
27
+ {data.PitchScale && <p>Pitch Scale: {data.PitchScale}</p>}
28
+ {data.MaxRoll && <p>Max Roll: {data.MaxRoll}</p>}
29
+ {data.DefaultJumpSpeedBoost && (
30
+ <p>Default Jump Speed Boost: {data.DefaultJumpSpeedBoost}</p>
31
+ )}
32
+ {data.IdleVolumeSpeedScale && (
33
+ <p>Idle Volume Speed Scale: {data.IdleVolumeSpeedScale}</p>
34
+ )}
35
+ {data.IdlePitchScale && (
36
+ <p>Idle Pitch Scale: {data.IdlePitchScale}</p>
37
+ )}
38
+ {data.BlockcastScale && <p>Blockcast Scale: {data.BlockcastScale}</p>}
39
+ {data.SkateMode && <p>Skate Mode: Yes</p>}
40
+ {data.IdleVolume && <p>Idle Volume: {data.IdleVolume}</p>}
41
+ </div>
42
+ )}
43
+ />
35
44
  );
36
45
  };
37
46
 
@@ -6,41 +6,59 @@ interface ImageProps {
6
6
  alt: string;
7
7
  }
8
8
 
9
- const imageCache = new Map<string, string>();
9
+ const MAX_CONCURRENT_REQUESTS = 5;
10
+ let currentRequests = 0;
11
+ const queue: (() => void)[] = [];
12
+
13
+ const processQueue = () => {
14
+ if (queue.length > 0 && currentRequests < MAX_CONCURRENT_REQUESTS) {
15
+ const nextRequest = queue.shift();
16
+ if (nextRequest) {
17
+ currentRequests++;
18
+ nextRequest();
19
+ }
20
+ }
21
+ };
10
22
 
11
23
  const ImageComponent: React.FC<ImageProps> = ({ src, alt }) => {
12
24
  const [imageUrl, setImageUrl] = useState<string | null>(null);
25
+ const [error, setError] = useState<string | null>(null);
13
26
 
14
27
  useEffect(() => {
15
28
  const fetchImage = async () => {
16
- if (imageCache.has(src)) {
17
- setImageUrl(imageCache.get(src)!);
18
- } else {
19
- try {
20
- const api = new PetSimulator99API();
21
- const response = await api.getImage(src);
22
- const imageBlob = new Blob([response], { type: "image/png" });
23
- const imageUrl = URL.createObjectURL(imageBlob);
24
- imageCache.set(src, imageUrl);
25
- setImageUrl(imageUrl);
26
- } catch (error) {
27
- console.error("Error fetching image:", error);
28
- }
29
+ try {
30
+ const api = new PetSimulator99API();
31
+ const imageBlob = await api.getImage(src);
32
+ const imageUrl = URL.createObjectURL(new Blob([imageBlob], { type: "image/png" }));
33
+ setImageUrl(imageUrl);
34
+ } catch (error) {
35
+ setError("Error fetching image");
36
+ console.error("Error fetching image:", error);
37
+ } finally {
38
+ currentRequests--;
39
+ processQueue();
29
40
  }
30
41
  };
31
42
 
32
- fetchImage();
43
+ const load = () => {
44
+ fetchImage();
45
+ };
46
+
47
+ queue.push(load);
48
+ processQueue();
33
49
 
34
50
  return () => {
35
51
  if (imageUrl) {
36
52
  URL.revokeObjectURL(imageUrl);
37
53
  }
38
54
  };
39
- }, [src]);
55
+ }, [src, imageUrl]);
56
+
57
+ if (error) {
58
+ return <div>{error}</div>;
59
+ }
40
60
 
41
- return (
42
- <div>{imageUrl ? <img src={imageUrl} alt={alt} /> : <p>Loading...</p>}</div>
43
- );
61
+ return <div>{imageUrl ? <img src={imageUrl} alt={alt} /> : <p>Loading...</p>}</div>;
44
62
  };
45
63
 
46
64
  export default ImageComponent;
@@ -1,37 +1,25 @@
1
- import React, { useEffect, useState } from "react";
2
- import { LootboxData, PetSimulator99API } from "ps99-api";
1
+ import React from "react";
2
+ import { CollectionConfigData } from "ps99-api";
3
+ import { GenericFetchComponent } from "./GenericFetchComponent";
3
4
  import ImageComponent from "./ImageComponent";
4
5
 
5
- const LootboxesComponent: React.FC = () => {
6
- const [lootboxes, setLootboxes] = useState<LootboxData[]>([]);
7
-
8
- useEffect(() => {
9
- const fetchLootboxes = async () => {
10
- const api = new PetSimulator99API();
11
- const response = await api.getCollection("Lootboxes");
12
- if (response.status === "ok") {
13
- setLootboxes(response.data);
14
- }
15
- };
16
- fetchLootboxes();
17
- }, []);
18
-
6
+ const LootboxesComponent: React.FC<{
7
+ configData?: CollectionConfigData<"Lootboxes">;
8
+ }> = ({ configData }) => {
19
9
  return (
20
- <div>
21
- <h2>Lootboxes</h2>
22
- <ul>
23
- {lootboxes.map((lootbox, index) => (
24
- <li key={index}>
25
- <ImageComponent
26
- src={lootbox.configData.Icon}
27
- alt={lootbox.configData.DisplayName}
28
- />
29
- <span>{lootbox.configData.DisplayName}</span>
30
- <span>{lootbox.configData.Desc}</span>
31
- </li>
32
- ))}
33
- </ul>
34
- </div>
10
+ <GenericFetchComponent<CollectionConfigData<"Lootboxes">>
11
+ collectionName="Lootboxes"
12
+ configData={configData}
13
+ render={(data) => (
14
+ <div>
15
+ <h2>{data.DisplayName}</h2>
16
+ <ImageComponent src={data.Icon} alt={data.DisplayName} />
17
+ <p>Description: {data.Desc}</p>
18
+ <p>Rarity: {data.Rarity.DisplayName}</p>
19
+ <p>Rarity Number: {data.Rarity.RarityNumber}</p>
20
+ </div>
21
+ )}
22
+ />
35
23
  );
36
24
  };
37
25
 
@@ -1,37 +1,55 @@
1
- import React, { useEffect, useState } from "react";
2
- import { MasteryData, PetSimulator99API } from "ps99-api";
1
+ import React from "react";
2
+ import { CollectionConfigData } from "ps99-api";
3
+ import { GenericFetchComponent } from "./GenericFetchComponent";
3
4
  import ImageComponent from "./ImageComponent";
4
5
 
5
- const MasteryComponent: React.FC = () => {
6
- const [mastery, setMastery] = useState<MasteryData[]>([]);
7
-
8
- useEffect(() => {
9
- const fetchMastery = async () => {
10
- const api = new PetSimulator99API();
11
- const response = await api.getCollection("Mastery");
12
- if (response.status === "ok") {
13
- setMastery(response.data);
14
- }
15
- };
16
- fetchMastery();
17
- }, []);
6
+ const MasteryComponent: React.FC<{
7
+ configData?: CollectionConfigData<"Mastery">;
8
+ }> = ({ configData }) => {
9
+ const renderPerks = (perks: any) => {
10
+ return Object.entries(perks).map(
11
+ ([perkType, perkDetails]: [string, any]) => (
12
+ <div key={perkType}>
13
+ <h3>{perkType}</h3>
14
+ {perkDetails.map((detail: any, index: number) => (
15
+ <div key={index}>
16
+ <p>Level: {detail.Level}</p>
17
+ <p>Title: {detail.Title}</p>
18
+ <p>Description: {detail.Text}</p>
19
+ {detail.Power && <p>Power: {detail.Power}</p>}
20
+ </div>
21
+ ))}
22
+ </div>
23
+ ),
24
+ );
25
+ };
18
26
 
19
27
  return (
20
- <div>
21
- <h2>Mastery</h2>
22
- <ul>
23
- {mastery.map((item, index) => (
24
- <li key={index}>
25
- <ImageComponent
26
- src={item.configData.Icon}
27
- alt={item.configData.Name}
28
- />
29
- <span>{item.configData.Name}</span>
30
- <span>{item.configData.Desc}</span>
31
- </li>
32
- ))}
33
- </ul>
34
- </div>
28
+ <GenericFetchComponent<CollectionConfigData<"Mastery">>
29
+ collectionName="Mastery"
30
+ configData={configData}
31
+ render={(data) => (
32
+ <div>
33
+ <h2>{data.Name}</h2>
34
+ <ImageComponent src={data.Icon} alt={data.Name} />
35
+ <p>Description: {data.Desc}</p>
36
+ {data.ToggleablePerks && (
37
+ <div>
38
+ <h3>Toggleable Perks</h3>
39
+ {Object.entries(data.ToggleablePerks).map(([perk, value]) => (
40
+ <p key={perk}>
41
+ {perk}: {value ? "Enabled" : "Disabled"}
42
+ </p>
43
+ ))}
44
+ </div>
45
+ )}
46
+ <div>
47
+ <h3>Perks</h3>
48
+ {renderPerks(data.Perks)}
49
+ </div>
50
+ </div>
51
+ )}
52
+ />
35
53
  );
36
54
  };
37
55
 
@@ -1,34 +1,45 @@
1
- import React, { useEffect, useState } from "react";
2
- import { MerchantData, PetSimulator99API } from "ps99-api";
1
+ import React from "react";
2
+ import { CollectionConfigData } from "ps99-api";
3
+ import { GenericFetchComponent } from "./GenericFetchComponent";
3
4
 
4
- const MerchantsComponent: React.FC = () => {
5
- const [merchants, setMerchants] = useState<MerchantData[]>([]);
6
-
7
- useEffect(() => {
8
- const fetchMerchants = async () => {
9
- const api = new PetSimulator99API();
10
- const response = await api.getCollection("Merchants");
11
- if (response.status === "ok") {
12
- setMerchants(response.data);
13
- }
14
- };
15
- fetchMerchants();
16
- }, []);
5
+ const MerchantComponent: React.FC<{
6
+ configData?: CollectionConfigData<"Merchants">;
7
+ }> = ({ configData }) => {
8
+ const renderStockRange = (stockRange: number[][] | undefined) => {
9
+ if (!stockRange) return null;
10
+ return stockRange.map((range, index) => (
11
+ <div key={index}>
12
+ <p>
13
+ Level {index + 1}: {range[0]} - {range[1]}
14
+ </p>
15
+ </div>
16
+ ));
17
+ };
17
18
 
18
19
  return (
19
- <div>
20
- <h2>Merchants</h2>
21
- <ul>
22
- {merchants.map((merchant, index) => (
23
- <li key={index}>
24
- <span>{merchant.configData.DisplayName}</span>
25
- <span>Price Multiplier: {merchant.configData.PriceMult}</span>
26
- <span>Refresh Rate: {merchant.configData.RefreshRate}</span>
27
- </li>
28
- ))}
29
- </ul>
30
- </div>
20
+ <GenericFetchComponent<CollectionConfigData<"Merchants">>
21
+ collectionName="Merchants"
22
+ configData={configData}
23
+ render={(data) => (
24
+ <div>
25
+ <h2>{data.DisplayName}</h2>
26
+ <p>Price Multiplier: {data.PriceMult}</p>
27
+ <p>Machine Name: {data.MachineName}</p>
28
+ <p>Refresh Rate: {data.RefreshRate} seconds</p>
29
+ {data.HideNotification && <p>Notification: Hidden</p>}
30
+ {data.HideRespect && <p>Respect: Hidden</p>}
31
+ {data.IsStatic && <p>Static Merchant</p>}
32
+ {renderStockRange(data.StockRangeByRespectLevel)}
33
+ {data.SlotRespectLevels && (
34
+ <div>
35
+ <h3>Slot Respect Levels</h3>
36
+ <p>{data.SlotRespectLevels.join(", ")}</p>
37
+ </div>
38
+ )}
39
+ </div>
40
+ )}
41
+ />
31
42
  );
32
43
  };
33
44
 
34
- export default MerchantsComponent;
45
+ export default MerchantComponent;
@@ -1,54 +1,36 @@
1
- import React, { useEffect, useState } from "react";
2
- import { MiscItemData, PetSimulator99API } from "ps99-api";
1
+ import React from "react";
2
+ import { CollectionConfigData } from "ps99-api";
3
+ import { GenericFetchComponent } from "./GenericFetchComponent";
3
4
  import ImageComponent from "./ImageComponent";
4
- import ErrorComponent from "./ErrorComponent";
5
-
6
- const MiscItemsComponent: React.FC = () => {
7
- const [miscItems, setMiscItems] = useState<MiscItemData[]>([]);
8
- const [error, setError] = useState<string | null>(null);
9
-
10
- useEffect(() => {
11
- const fetchMiscItems = async () => {
12
- const api = new PetSimulator99API();
13
- const response = await api.getCollection("MiscItems");
14
- if (response.status === "ok") {
15
- setMiscItems(response.data);
16
- } else {
17
- setError(response.error.message);
18
- }
19
- };
20
- fetchMiscItems();
21
- }, []);
22
-
23
- if (error) {
24
- return <ErrorComponent message={error} />;
25
- }
26
5
 
6
+ const MiscItemsComponent: React.FC<{
7
+ configData?: CollectionConfigData<"MiscItems">;
8
+ }> = ({ configData }) => {
27
9
  return (
28
- <div>
29
- <h2>Miscellaneous Items</h2>
30
- <ul>
31
- {miscItems.map((item, index) => (
32
- <li key={index}>
10
+ <GenericFetchComponent<CollectionConfigData<"MiscItems">>
11
+ collectionName="MiscItems"
12
+ configData={configData}
13
+ render={(data) => (
14
+ <div>
15
+ <h2>{data.DisplayName}</h2>
16
+ <p>Category: {data.Category}</p>
17
+ <ImageComponent src={data.Icon} alt={data.DisplayName} />
18
+ {data.AltIcon && (
33
19
  <ImageComponent
34
- src={item.configData.Icon}
35
- alt={item.configData.DisplayName}
20
+ src={data.AltIcon}
21
+ alt={`${data.DisplayName} (Alternate)`}
36
22
  />
37
- <span>{item.configData.DisplayName}</span>
38
- <span>Category: {item.configData.Category}</span>
39
- <span>Description: {item.configData.Desc}</span>
40
- <span>Rarity: {item.configData.Rarity.DisplayName}</span>
41
- {item.configData.Tradable && <span>Tradable</span>}
42
- {item.configData.AltIcon && (
43
- <ImageComponent
44
- src={item.configData.AltIcon}
45
- alt={`${item.configData.DisplayName} Alternate Icon`}
46
- />
47
- )}
48
- </li>
49
- ))}
50
- </ul>
51
- </div>
23
+ )}
24
+ <p>Description: {data.Desc}</p>
25
+ <p>
26
+ Rarity: {data.Rarity.DisplayName} (Rarity Number:{" "}
27
+ {data.Rarity.RarityNumber})
28
+ </p>
29
+ {data.Tradable && <p>Tradable: Yes</p>}
30
+ {!data.Tradable && <p>Tradable: No</p>}
31
+ </div>
32
+ )}
33
+ />
52
34
  );
53
35
  };
54
36