App (7).js 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. import React, { useState, useEffect } from "react";
  2. // import logo from "./logo.svg";
  3. import "./App.css";
  4. const Spoiler = ({ header = "+", open, children }) => {
  5. const [state, setState] = useState(open);
  6. return (
  7. <>
  8. <div onClick={() => setState(!state)}>{header}</div>
  9. {/* <div
  10. style={{
  11. visibility: state ? "visible" : "hidden",
  12. }}
  13. > */}
  14. {state && children}
  15. </>
  16. // </div>
  17. );
  18. };
  19. const RangeInput = (props) => {
  20. const [text, setText] = useState("RangeInput");
  21. return (
  22. <div>
  23. <label htmlFor="range">RangeInput:</label>
  24. <input
  25. id="range"
  26. type="text"
  27. value={text}
  28. style={{
  29. backgroundColor:
  30. text.length < props.min || text.length > props.max ? "#FAA" : "",
  31. }}
  32. onChange={(e) => setText(e.target.value)}
  33. />
  34. </div>
  35. );
  36. };
  37. const PasswordConfirm = (props) => {
  38. const [password, setPassword] = useState("Password");
  39. const [confirmPassword, setConfirnPassword] = useState("PasswordConfirm");
  40. return (
  41. <div>
  42. <label htmlFor="password">Password:</label>
  43. <input
  44. id="password"
  45. type="text"
  46. value={password}
  47. style={{
  48. backgroundColor:
  49. password.length < props.min ||
  50. password !== confirmPassword ||
  51. password.match(/[0-9]+/gi)
  52. ? "#FAA"
  53. : "",
  54. }}
  55. onChange={(e) => setPassword(e.target.value)}
  56. />
  57. <label htmlFor="confirm">ConfirmPassword:</label>
  58. <input
  59. id="confirm"
  60. type="text"
  61. value={confirmPassword}
  62. style={{
  63. backgroundColor:
  64. confirmPassword.length < props.min ||
  65. confirmPassword !== password ||
  66. confirmPassword.match(/[0-9]+/gi)
  67. ? "#FAA"
  68. : "",
  69. }}
  70. onChange={(e) => setConfirnPassword(e.target.value)}
  71. />
  72. </div>
  73. );
  74. };
  75. const LifeCycle = ({ onDelete }) => {
  76. const [counter, setCounter] = useState(0);
  77. useEffect(() => {
  78. let intervalID = setInterval(() => {
  79. setCounter((c) => c + 1);
  80. }, 1000);
  81. return () => clearInterval(intervalID);
  82. // console.log(intervalID + "intervalID bye-bye")
  83. }, []);
  84. return (
  85. <div>
  86. {counter}
  87. <button onClick={onDelete}>x</button>
  88. </div>
  89. );
  90. };
  91. const LifeStyles = () => {
  92. const [count, setCount] = useState(1);
  93. return (
  94. <>
  95. {[..." ".repeat(count)].map(() => (
  96. <LifeCycle onDelete={() => setCount(count - 1)} />
  97. ))}
  98. <button onClick={() => setCount(count + 1)}>+</button>
  99. </>
  100. );
  101. };
  102. const Timer = (props) => {
  103. const [time, setTime] = useState(props.sec);
  104. // console.log("props.sec: ", props.sec);
  105. const [pause, setPause] = useState(true);
  106. let seconds = time % 60;
  107. let minutes = Math.floor((time / 60) % 60);
  108. let hours = Math.floor(time / 3600);
  109. let interval;
  110. useEffect(() => {
  111. interval = setInterval(() => {
  112. if (!pause) {
  113. setTime((time) => time - 1);
  114. // console.log("interval: " + interval);
  115. }
  116. }, props.refresh);
  117. return () => clearInterval(interval);
  118. }, [pause]);
  119. return (
  120. <div>
  121. <span>
  122. Timer: {hours}:{minutes}:{Math.trunc(seconds)}
  123. </span>
  124. <button id="pause" onClick={() => setPause(!pause)}>
  125. {/* &#10074;&#10074; */}
  126. {pause ? "\u25BA" : "\u275A\u275A"}
  127. </button>
  128. </div>
  129. );
  130. };
  131. // const MyComponents = {
  132. // Timer: (props) => {
  133. // const [time, setTime] = useState(props.sec);
  134. // const [pause, setPause] = useState(false);
  135. // const [minute, setMinute] = useState(props.min);
  136. // const [hour, setHour] = useState(props.hours);
  137. // {
  138. // if (!pause) {
  139. // return (
  140. // <div>
  141. // <span>
  142. // Timer: {hour}:{minute}:{time}
  143. // </span>
  144. // <button id="pause" onClick={() => setPause(!pause)}>
  145. // &#9658;
  146. // </button>
  147. // </div>
  148. // );
  149. // }
  150. // }
  151. // {
  152. // setTimeout(function () {
  153. // if (minute < 0) {
  154. // setMinute(59);
  155. // setHour(hour - 1);
  156. // }
  157. // if (time === 0 || time === "00") {
  158. // setTime(60);
  159. // setMinute(minute - 1);
  160. // } else {
  161. // setTime(time - 1);
  162. // }
  163. // }, 1000);
  164. // }
  165. // return (
  166. // <div>
  167. // <span>
  168. // Timer: {hour}:{minute}:{time}
  169. // </span>
  170. // <button id="pause" onClick={() => setPause(!pause)}>
  171. // &#10074;&#10074;
  172. // </button>
  173. // </div>
  174. // );
  175. // },
  176. // };
  177. const TimerControl = (props) => {
  178. const [state, setState] = useState(false);
  179. const [hours, setHours] = useState(0);
  180. const [minutes, setMinutes] = useState(0);
  181. const [seconds, setSeconds] = useState(0);
  182. let sum = +hours * 3600 + +minutes * 60 + +seconds;
  183. {
  184. if (state) {
  185. return (
  186. <div className="timer-control">
  187. <input id="hour" type="text" placeholder="Enter Hours" />
  188. <input id="minute" type="text" placeholder="Enter Minutes" />
  189. <input id="second" type="text" placeholder="Enter Seconds" />
  190. <button onClick={() => setState(!state)}>Start</button>
  191. {/* <Timer sec={+seconds} min={+minutes} hours={+hours} /> */}
  192. {<Timer sec={sum} refresh={props.refresh} />}
  193. </div>
  194. );
  195. }
  196. }
  197. return (
  198. <div className="timer-control">
  199. <input
  200. id="hour"
  201. type="number"
  202. placeholder="Enter Hours"
  203. onChange={(e) => setHours(e.target.value)}
  204. />
  205. <input
  206. id="minute"
  207. type="number"
  208. placeholder="Enter Minutes"
  209. onChange={(e) => setMinutes(e.target.value)}
  210. />
  211. <input
  212. id="second"
  213. type="number"
  214. placeholder="Enter Seconds"
  215. onChange={(e) => setSeconds(e.target.value)}
  216. />
  217. <button onClick={() => setState(!state)}>Start</button>
  218. </div>
  219. );
  220. };
  221. const LCD = (props) => {
  222. for (let key in props) {
  223. console.log("props.key in LCD: " + key);
  224. }
  225. return (
  226. <>
  227. <h2>LCD</h2>
  228. <div className="digital-clock au-target">
  229. <div className="clock-time lcd lcd-frame">
  230. {<Timer sec={props.sec} refresh={props.refresh} />}
  231. {/* 22<b className="clock-separator-blink">:</b>19
  232. <b className="clock-separator-blink">:</b>17 */}
  233. </div>
  234. </div>
  235. </>
  236. );
  237. };
  238. const TimerContainer = ({ seconds, refresh, render: Render }) => {
  239. const [text, setText] = useState();
  240. const [t0, setT0] = useState(performance.now());
  241. // const [forget, setForget] = useState();
  242. // let interval;
  243. // useEffect(() => {
  244. // interval = setInterval(() => {
  245. // // if (!pause) {
  246. // setForget((forget) => !forget);
  247. // // }
  248. // }, refresh);
  249. // return () => clearInterval(interval);
  250. // }, [forget]);
  251. console.log(text);
  252. return (
  253. <>
  254. <h2>TimerContainer</h2>
  255. <Render
  256. sec={seconds - (performance.now() - t0)}
  257. refresh={refresh}
  258. value={text}
  259. onChange={(e) => {
  260. let value = e;
  261. if (e && e.target && "value" in e.target) {
  262. value = e.target.value;
  263. }
  264. setText(value);
  265. }}
  266. />
  267. </>
  268. );
  269. };
  270. const SecondsTimer = ({ sec: seconds }) => <h2>{seconds}</h2>;
  271. const App = () => (
  272. <div className="App">
  273. <Spoiler header={<h1>Заголовок</h1>} open>
  274. Контент 1
  275. <p>
  276. Lorem, ipsum dolor sit amet consectetur adipisicing elit. Nihil ducimus
  277. suscipit incidunt officia deleniti, aspernatur unde eius facilis
  278. tempora. Eligendi voluptatem deleniti quas dolore rerum! Explicabo
  279. obcaecati minus est? Cumque!
  280. </p>
  281. </Spoiler>
  282. <Spoiler>
  283. <h2>Контент 2</h2>
  284. <p>
  285. Lorem ipsum dolor sit amet consectetur adipisicing elit. Delectus
  286. debitis possimus officiis necessitatibus. Illo quibusdam aliquid
  287. temporibus impedit, aliquam dolor harum eius consequuntur laboriosam
  288. quam excepturi voluptatibus dolores consequatur sed.
  289. </p>
  290. </Spoiler>
  291. <RangeInput min={2} max={10} />
  292. <PasswordConfirm min={2} />
  293. <h2>Timer</h2>
  294. <TimerControl refresh={100} />
  295. <TimerContainer seconds={1800} refresh={100} render={Timer} />
  296. <TimerContainer seconds={1800} refresh={100} render={SecondsTimer} />
  297. <TimerContainer seconds={1800} refresh={100} render={"input"} />
  298. <TimerContainer
  299. seconds={1800}
  300. refresh={100}
  301. render={(props) => <input type="color" {...props} />}
  302. />
  303. {/* <LifeStyles /> */}
  304. {/* <Timer sec={60} min={59} hours={23} /> */}
  305. {/* <Timer TimerControl /> */}
  306. <TimerContainer seconds={1800} refresh={100} render={LCD} />
  307. {/* <LCD /> */}
  308. </div>
  309. );
  310. export default App;