GameCreationForm.jsx 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. import ms from "pretty-ms";
  2. import { useCallback, useState } from "react";
  3. import { createGame } from "../../../domain/apiMethods";
  4. import { RANDOM_STREET_VIEW, URBAN } from "../../../domain/genMethods";
  5. import {
  6. FROZEN,
  7. NORMAL,
  8. TIME_BANK,
  9. RACE,
  10. COUNTRY_RACE,
  11. } from "../../../domain/ruleSets";
  12. import useCountryLookup from "../../../hooks/useCountryLookup";
  13. import Loading from "../Loading";
  14. import { Dropdown, DropdownGroup, Item, CountryDropdown } from "./Dropdown";
  15. import ErrorModal from "./ErrorModal";
  16. import styles from "./GameCreationForm.module.css";
  17. const DEFAULTS = {
  18. timer: 300,
  19. rounds: 5,
  20. countryLock: null,
  21. genMethod: RANDOM_STREET_VIEW,
  22. ruleSet: NORMAL,
  23. };
  24. const PRESETS = {
  25. URBAN_AMERICA: {
  26. ...DEFAULTS,
  27. genMethod: URBAN,
  28. countryLock: "us",
  29. },
  30. URBAN_GLOBAL: {
  31. ...DEFAULTS,
  32. genMethod: URBAN,
  33. },
  34. FAST_FROZEN: {
  35. ...DEFAULTS,
  36. timer: 30,
  37. rounds: 3,
  38. genMethod: RANDOM_STREET_VIEW,
  39. ruleSet: FROZEN,
  40. },
  41. };
  42. const GameCreationForm = ({ afterCreate }) => {
  43. const [loading, setLoading] = useState(false);
  44. const [creationError, setCreationError] = useState(false);
  45. const [timer, setTimer] = useState(DEFAULTS.timer);
  46. const [rounds, setRounds] = useState(DEFAULTS.rounds);
  47. const [countryLock, setCountryLock] = useState(DEFAULTS.countryLock);
  48. const [genMethod, setGenMethod] = useState(DEFAULTS.genMethod);
  49. const [ruleSet, setRuleSet] = useState(DEFAULTS.ruleSet);
  50. const countryLookup = useCountryLookup(genMethod);
  51. const setPreset = useCallback(
  52. ({
  53. timer: newTimer,
  54. rounds: newRounds,
  55. countryLock: newCountryLock,
  56. genMethod: newGenMethod,
  57. ruleSet: newRuleSet,
  58. }) => {
  59. setTimer(newTimer);
  60. setRounds(newRounds);
  61. setCountryLock(newCountryLock);
  62. setGenMethod(newGenMethod);
  63. setRuleSet(newRuleSet);
  64. },
  65. []
  66. );
  67. if (loading || countryLookup === null) {
  68. return <Loading />;
  69. }
  70. const onCreateGame = async () => {
  71. setLoading(true);
  72. let gameId;
  73. try {
  74. gameId = await createGame(timer, rounds, countryLock, genMethod, ruleSet);
  75. } catch (e) {
  76. setCreationError(true);
  77. setLoading(false);
  78. return;
  79. }
  80. if (afterCreate) {
  81. afterCreate(gameId);
  82. }
  83. };
  84. return (
  85. <div className={styles.form}>
  86. <ErrorModal
  87. open={creationError}
  88. onClose={() => setCreationError(false)}
  89. />
  90. <button className={styles.start} onClick={onCreateGame} type="button">
  91. New Game
  92. </button>
  93. <div className={styles.dropdowns}>
  94. <DropdownGroup>
  95. <Dropdown selected={DEFAULTS} onSelect={setPreset} open="presets">
  96. <Item value={DEFAULTS} display="⭐">
  97. Default
  98. </Item>
  99. <Item value={PRESETS.URBAN_AMERICA} display="⭐">
  100. Urban America
  101. </Item>
  102. <Item value={PRESETS.URBAN_GLOBAL} display="⭐">
  103. Urban Global
  104. </Item>
  105. <Item value={PRESETS.FAST_FROZEN} display="⭐">
  106. Fast Frozen
  107. </Item>
  108. </Dropdown>
  109. <Dropdown selected={timer} onSelect={setTimer} open="timer">
  110. <Item value={30} display={ms(30 * 1000)}>
  111. 30 Seconds
  112. </Item>
  113. <Item value={120} display={ms(2 * 60 * 1000)}>
  114. 2 Minutes
  115. </Item>
  116. <Item value={300} display={ms(5 * 60 * 1000)}>
  117. 5 Minutes
  118. </Item>
  119. <Item value={3600} display={ms(60 * 60 * 1000)}>
  120. 1 Hour
  121. </Item>
  122. </Dropdown>
  123. <Dropdown selected={rounds} onSelect={setRounds} open="rounds">
  124. <Item value={1}>1 Round</Item>
  125. <Item value={3}>3 Rounds</Item>
  126. <Item value={5}>5 Rounds</Item>
  127. <Item value={10}>10 Rounds</Item>
  128. </Dropdown>
  129. <Dropdown selected={genMethod} onSelect={setGenMethod} open="gen">
  130. <Item value={RANDOM_STREET_VIEW} display="🎲">
  131. Random Street View
  132. </Item>
  133. <Item value={URBAN} display="🏙️">
  134. Urban Centers
  135. </Item>
  136. </Dropdown>
  137. <CountryDropdown
  138. countryLookup={countryLookup}
  139. selected={countryLock}
  140. onSelect={setCountryLock}
  141. open="country"
  142. />
  143. <Dropdown selected={ruleSet} onSelect={setRuleSet} open="rule">
  144. <Item value={NORMAL} display="⏰">
  145. Normal
  146. </Item>
  147. <Item value={TIME_BANK} display="🏦">
  148. Time Bank
  149. </Item>
  150. <Item value={FROZEN} display="❄️">
  151. Frozen
  152. </Item>
  153. <Item value={RACE} display="🏃">
  154. Race
  155. </Item>
  156. <Item value={COUNTRY_RACE} display="🗾">
  157. Country Race
  158. </Item>
  159. </Dropdown>
  160. </DropdownGroup>
  161. </div>
  162. </div>
  163. );
  164. };
  165. export default GameCreationForm;