app.js 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906
  1. (() => {
  2. // application/scripts/height_equaler.js
  3. var height_equaler = class {
  4. #to;
  5. #from;
  6. constructor(from, to) {
  7. this.#from = from;
  8. this.#to = to;
  9. this.#set_styles();
  10. new ResizeObserver(() => {
  11. this.#update();
  12. }).observe(from);
  13. setTimeout(() => {
  14. this.#update();
  15. }, 100);
  16. }
  17. get height() {
  18. return this.#from.offsetHeight;
  19. }
  20. #set_styles() {
  21. this.#to.style.height = "0px";
  22. this.#to.style.transition = "height 0.5s";
  23. }
  24. #update() {
  25. this.#to.style.height = this.height + "px";
  26. }
  27. };
  28. // application/scripts/product.js
  29. var product = class _product {
  30. name;
  31. description;
  32. author;
  33. image;
  34. stock_count;
  35. barcode;
  36. thumbnail;
  37. on_stock;
  38. constructor(target) {
  39. this.name = null;
  40. this.description = null;
  41. this.author = null;
  42. this.image = null;
  43. this.stock_count = null;
  44. this.barcode = null;
  45. this.thumbnail = null;
  46. this.on_stock = null;
  47. if ("name" in target) this.name = target["name"];
  48. if ("description" in target) this.description = target["description"];
  49. if ("author" in target) this.author = target["author"];
  50. if ("image" in target) this.image = target["image"];
  51. if ("stock_count" in target) this.stock_count = target["stock_count"];
  52. if ("barcode" in target) this.barcode = target["barcode"];
  53. if ("thumbnail" in target) this.thumbnail = target["thumbnail"];
  54. if ("on_stock" in target) this.on_stock = target["on_stock"];
  55. }
  56. get dump() {
  57. const dumped = {
  58. "name": this.name,
  59. "description": this.description,
  60. "author": this.author,
  61. "image": this.image,
  62. "stock_count": this.stock_count,
  63. "barcode": this.barcode,
  64. "thumbnail": this.thumbnail
  65. };
  66. if (this.on_stock !== null) {
  67. dumped["on_stock"] = this.on_stock;
  68. }
  69. return dumped;
  70. }
  71. get ready() {
  72. if (this.name === null || this.description === null) return false;
  73. if (this.author === null || this.image === null) return false;
  74. if (this.stock_count === null || this.barcode === null) return false;
  75. if (this.thumbnail === null) return false;
  76. return true;
  77. }
  78. copy() {
  79. return new _product(this.dump);
  80. }
  81. };
  82. // application/scripts/products_loader.js
  83. var products_loader = class _products_loader {
  84. static async all() {
  85. const request2 = await fetch("/products/");
  86. const response = await request2.json();
  87. return _products_loader.#response_to_collection(response);
  88. }
  89. static #response_to_collection(response) {
  90. const result = new Array();
  91. if (response.result !== "success") {
  92. return result;
  93. }
  94. response.collection.forEach((serialized) => {
  95. result.push(new product(serialized));
  96. });
  97. return result;
  98. }
  99. static async search_name(name) {
  100. return await _products_loader.#search(
  101. "/product/search/name",
  102. name
  103. );
  104. }
  105. static async search_author(author) {
  106. return await _products_loader.#search(
  107. "/product/search/author",
  108. author
  109. );
  110. }
  111. static async #search(path, parameter) {
  112. const coded = encodeURI(parameter);
  113. const request2 = await fetch(path + "/" + coded);
  114. const response = await request2.json();
  115. return _products_loader.#response_to_collection(response);
  116. }
  117. };
  118. // application/scripts/fullscreen.js
  119. var fullscreen = class {
  120. #node;
  121. constructor() {
  122. this.#node = null;
  123. }
  124. get visible() {
  125. return this.#node !== null;
  126. }
  127. _build_node() {
  128. throw new TypeError("This is virtual method!");
  129. }
  130. get #opacity() {
  131. if (!this.visible) {
  132. throw new TypeError("Can not change opacity of not existed.");
  133. }
  134. return Number(this.#node.style.opacity);
  135. }
  136. set #opacity(target) {
  137. if (!this.visible) {
  138. throw new TypeError("Can not change opacity of not existed.");
  139. }
  140. this.#node.style.opacity = String(target);
  141. }
  142. get_query(selector) {
  143. if (!this.visible) {
  144. throw new TypeError("Can not get item from not visible.");
  145. }
  146. return this.#node.querySelector(selector);
  147. }
  148. #prepare() {
  149. const container = document.createElement("div");
  150. container.classList.add("fullscreen-viewer");
  151. container.style.transition = "opacity 0.5s";
  152. container.appendChild(this._build_node());
  153. return container;
  154. }
  155. hide() {
  156. if (!this.visible) {
  157. return;
  158. }
  159. this.#opacity = 0;
  160. setTimeout(() => {
  161. if (!this.visible) {
  162. return;
  163. }
  164. this.#node.remove();
  165. this.#node = null;
  166. }, 500);
  167. }
  168. show() {
  169. if (this.visible) {
  170. return;
  171. }
  172. this.#node = this.#prepare();
  173. this.#opacity = 0;
  174. document.querySelector("body").appendChild(this.#node);
  175. setTimeout(() => {
  176. this.#opacity = 1;
  177. }, 100);
  178. }
  179. };
  180. // application/scripts/product_fullscreen.js
  181. var product_fullscreen = class extends fullscreen {
  182. #target;
  183. constructor(target) {
  184. super();
  185. this.#target = target;
  186. }
  187. get target() {
  188. return this.#target;
  189. }
  190. _build_node() {
  191. const container = document.createElement("div");
  192. container.classList.add("product-fullscreen-viewer");
  193. const image = document.createElement("div");
  194. image.style.backgroundImage = 'url("' + this.target.image + '")';
  195. image.classList.add("image");
  196. container.appendChild(image);
  197. const title = document.createElement("div");
  198. title.classList.add("title");
  199. container.appendChild(title);
  200. const title_content = document.createElement("h1");
  201. title_content.innerText = this.target.name;
  202. title.appendChild(title_content);
  203. const bottom = document.createElement("div");
  204. bottom.classList.add("bottom-side");
  205. container.appendChild(bottom);
  206. const bottom_header = document.createElement("div");
  207. bottom_header.classList.add("bottom-header");
  208. bottom.appendChild(bottom_header);
  209. const barcode_icon = document.createElement("span");
  210. barcode_icon.classList.add("material-icons");
  211. barcode_icon.innerText = "qr_code_scanner";
  212. const barcode_content = document.createElement("span");
  213. barcode_content.innerText = this.target.barcode;
  214. barcode_content.classList.add("numbers");
  215. const barcode = document.createElement("p");
  216. barcode.appendChild(barcode_icon);
  217. barcode.appendChild(barcode_content);
  218. bottom_header.appendChild(barcode);
  219. const author_icon = document.createElement("span");
  220. author_icon.classList.add("material-icons");
  221. author_icon.innerText = "attribution";
  222. const author_content = document.createElement("span");
  223. author_content.innerText = this.target.author;
  224. const author = document.createElement("p");
  225. author.appendChild(author_icon);
  226. author.appendChild(author_content);
  227. bottom_header.appendChild(author);
  228. const description = document.createElement("div");
  229. description.classList.add("description");
  230. bottom.appendChild(description);
  231. const description_content = document.createElement("p");
  232. description_content.innerText = this.target.description;
  233. description.appendChild(description_content);
  234. const close_button = document.createElement("button");
  235. close_button.classList.add("material-icons");
  236. close_button.classList.add("close");
  237. close_button.innerText = "close";
  238. container.appendChild(close_button);
  239. close_button.addEventListener("click", () => {
  240. this.hide();
  241. });
  242. return container;
  243. }
  244. };
  245. // application/scripts/user.js
  246. var user = class {
  247. #nick;
  248. #apikey;
  249. constructor(nick, apikey) {
  250. this.#nick = nick;
  251. this.#apikey = apikey;
  252. }
  253. get nick() {
  254. return this.#nick;
  255. }
  256. get apikey() {
  257. return this.#apikey;
  258. }
  259. };
  260. // application/scripts/login_manager.js
  261. var login_manager = class {
  262. get apikey() {
  263. return localStorage.getItem("apikey");
  264. }
  265. get logged_in() {
  266. return localStorage.getItem("apikey") !== null;
  267. }
  268. #create_request(data) {
  269. return {
  270. method: "POST",
  271. body: JSON.stringify(data),
  272. headers: {
  273. "Content-Type": "application/json"
  274. }
  275. };
  276. }
  277. async get_user() {
  278. if (!this.logged_in) {
  279. return null;
  280. }
  281. const request_data = this.#create_request({
  282. apikey: this.apikey
  283. });
  284. const request2 = await fetch("/user", request_data);
  285. const response = await request2.json();
  286. if (response.result !== "success") {
  287. return null;
  288. }
  289. return new user(
  290. response.nick,
  291. response.apikey
  292. );
  293. }
  294. async login(nick, password) {
  295. const request_data = this.#create_request({
  296. nick,
  297. password
  298. });
  299. const request2 = await fetch("/user/login", request_data);
  300. const response = await request2.json();
  301. if (response.result !== "success") {
  302. return false;
  303. }
  304. localStorage.setItem("apikey", response.apikey);
  305. return true;
  306. }
  307. logout() {
  308. localStorage.removeItem("apikey");
  309. }
  310. };
  311. // application/scripts/confirm_action.js
  312. var confirm_action = class {
  313. #node;
  314. #action;
  315. constructor() {
  316. this.#node = null;
  317. this.#action = true;
  318. }
  319. get _description() {
  320. throw new TypeError("It must be overwriten.");
  321. }
  322. get _title() {
  323. return "You must confirm it.";
  324. }
  325. _action() {
  326. throw new TypeError("It must be overwriten.");
  327. }
  328. get _info() {
  329. return false;
  330. }
  331. show() {
  332. if (this.#node !== null) {
  333. return;
  334. }
  335. this.#action = true;
  336. this.#node = this.#create_window();
  337. document.querySelector("body").appendChild(this.#node);
  338. setTimeout(() => {
  339. this.#node.style.opacity = "1";
  340. }, 100);
  341. }
  342. hide() {
  343. if (this.#node === null) {
  344. return;
  345. }
  346. this.#action = false;
  347. this.#node.style.opacity = "0";
  348. setTimeout(() => {
  349. if (this.#node === null) {
  350. return;
  351. }
  352. this.#node.remove();
  353. this.#node = null;
  354. }, 500);
  355. }
  356. #create_window() {
  357. const container = document.createElement("div");
  358. container.classList.add("confirm-window");
  359. container.style.transition = "opacity 0.5s";
  360. container.style.opacity = "0";
  361. const center = document.createElement("div");
  362. center.classList.add("center");
  363. container.appendChild(center);
  364. const title = document.createElement("div");
  365. title.classList.add("title");
  366. center.appendChild(title);
  367. const title_text = document.createElement("h3");
  368. title_text.innerText = this._title;
  369. title.appendChild(title_text);
  370. const description = document.createElement("div");
  371. description.classList.add("description");
  372. center.appendChild(description);
  373. const description_text = document.createElement("p");
  374. description_text.innerText = this._description;
  375. description.appendChild(description_text);
  376. const buttons = document.createElement("div");
  377. buttons.classList.add("buttons");
  378. center.appendChild(buttons);
  379. const cancel_button = document.createElement("button");
  380. cancel_button.classList.add("cancel");
  381. cancel_button.classList.add("material-icons");
  382. cancel_button.innerText = "clear";
  383. buttons.appendChild(cancel_button);
  384. cancel_button.addEventListener("click", () => {
  385. this.hide();
  386. });
  387. if (!this._info) {
  388. const confirm_button = document.createElement("button");
  389. confirm_button.classList.add("confirm");
  390. confirm_button.classList.add("material-icons");
  391. confirm_button.innerText = "send";
  392. buttons.appendChild(confirm_button);
  393. confirm_button.addEventListener("click", () => {
  394. if (this.#action === false) {
  395. return;
  396. }
  397. this._action();
  398. this.hide();
  399. });
  400. }
  401. return container;
  402. }
  403. };
  404. // application/scripts/request.js
  405. var request = class {
  406. get settings() {
  407. return {
  408. "method": this.method,
  409. "headers": this.headers,
  410. "body": this.body
  411. };
  412. }
  413. get _apikey() {
  414. const manager = new login_manager();
  415. if (manager.logged_in) {
  416. return manager.apikey;
  417. }
  418. throw new Error("User must be logged in.");
  419. }
  420. get method() {
  421. throw new TypeError("It must be overwrite.");
  422. }
  423. get url() {
  424. throw new TypeError("It must be overwrite.");
  425. }
  426. get headers() {
  427. if (this.method === "GET") {
  428. return {};
  429. }
  430. return {
  431. "Content-Type": "application/json"
  432. };
  433. }
  434. get body() {
  435. if (this.data === null) {
  436. return "";
  437. }
  438. return JSON.stringify(this.data);
  439. }
  440. get _response() {
  441. throw new TypeError("It must be overwrite.");
  442. }
  443. async connect() {
  444. const request2 = await fetch(this.url, this.settings);
  445. if (!request2.ok) {
  446. throw new Error('Fail when requested: "' + this.url + '".');
  447. }
  448. const response = await request2.json();
  449. if (!("result" in response)) {
  450. throw new Error("Bad response, not contain result.");
  451. }
  452. return new this._response(response);
  453. }
  454. get data() {
  455. throw new TypeError("This must be overwrite.");
  456. }
  457. };
  458. // application/scripts/bool_response.js
  459. var bool_response = class {
  460. #result;
  461. #cause;
  462. constructor(target) {
  463. this.#result = target.result === "success";
  464. this.#cause = null;
  465. if (!this.result) {
  466. this.#cause = target.cause;
  467. }
  468. }
  469. get cause() {
  470. return this.#cause;
  471. }
  472. get result() {
  473. return this.#result;
  474. }
  475. };
  476. // application/scripts/delete_request.js
  477. var delete_request = class extends request {
  478. #product;
  479. constructor(product2) {
  480. super();
  481. this.#product = product2;
  482. }
  483. get _response() {
  484. return bool_response;
  485. }
  486. get data() {
  487. return {
  488. "apikey": this._apikey
  489. };
  490. }
  491. get url() {
  492. return "/product/barcode/" + this.#product.barcode;
  493. }
  494. get method() {
  495. return "DELETE";
  496. }
  497. };
  498. // application/scripts/product_containers.js
  499. var product_containers = class {
  500. #content;
  501. #where;
  502. #inserted;
  503. constructor(where) {
  504. this.#where = where;
  505. this.#content = new Array();
  506. this.#inserted = new Array();
  507. }
  508. add_list(target) {
  509. target.forEach((count) => {
  510. this.add(count);
  511. });
  512. return this;
  513. }
  514. add(target) {
  515. const current = new product_container(target);
  516. this.#content.push(current);
  517. return this;
  518. }
  519. clean() {
  520. this.#content = new Array();
  521. return this;
  522. }
  523. update() {
  524. this.#hide();
  525. setTimeout(() => {
  526. this.#content.forEach((count) => {
  527. this.#inserted.push(count);
  528. count.add(this.#where);
  529. });
  530. }, 500);
  531. return this;
  532. }
  533. #hide() {
  534. this.#inserted.forEach((count) => {
  535. if (!this.#content.includes(count)) {
  536. count.drop();
  537. }
  538. });
  539. this.#inserted = new Array();
  540. return this;
  541. }
  542. };
  543. // application/scripts/searcher.js
  544. var searcher = class _searcher {
  545. #input;
  546. #category;
  547. #manager;
  548. #result;
  549. static #instances;
  550. static #add(instance) {
  551. if (typeof _searcher.#instances !== "object") {
  552. _searcher.#instances = new Array();
  553. }
  554. _searcher.#instances.push(instance);
  555. }
  556. static reload() {
  557. if (typeof _searcher.#instances !== "object") {
  558. return;
  559. }
  560. _searcher.#instances.forEach((instance) => {
  561. instance.update();
  562. });
  563. }
  564. constructor(search_form, manager, result) {
  565. this.#input = search_form.querySelector('input[type="text"]');
  566. this.#category = search_form.querySelector("select");
  567. this.#manager = manager;
  568. this.#result = result;
  569. this.#selector_complete();
  570. search_form.addEventListener("submit", (target) => {
  571. target.preventDefault();
  572. this.update();
  573. });
  574. _searcher.#add(this);
  575. }
  576. get categories() {
  577. return {
  578. "name": "Name",
  579. "author": "Author"
  580. };
  581. }
  582. #selector_complete() {
  583. const category = this.#category;
  584. const categories = this.categories;
  585. Object.keys(categories).forEach((name) => {
  586. const option = document.createElement("option");
  587. option.value = name;
  588. option.innerText = categories[name];
  589. category.appendChild(option);
  590. });
  591. }
  592. get #loader() {
  593. return {
  594. "name": products_loader.search_name,
  595. "author": products_loader.search_author
  596. }[this.category];
  597. }
  598. get category() {
  599. return this.#category.value;
  600. }
  601. get phrase() {
  602. return this.#input.value.trim();
  603. }
  604. get #result_title() {
  605. return this.#result.innerText;
  606. }
  607. set #result_title(target) {
  608. this.#result.innerText = target;
  609. }
  610. async update() {
  611. if (this.phrase.length === 0) {
  612. this.show_all();
  613. return;
  614. }
  615. this.#insert(await this.#loader(this.phrase));
  616. }
  617. #insert(list) {
  618. if (list.length === 0) {
  619. this.#result_title = "Not found anything.";
  620. } else {
  621. this.#result_title = "Browse our products!";
  622. }
  623. this.#manager.clean().add_list(list).update();
  624. }
  625. async show_all() {
  626. this.#insert(await products_loader.all());
  627. }
  628. };
  629. // application/scripts/delete_product_window.js
  630. var delete_product_window = class extends confirm_action {
  631. #target;
  632. constructor(target) {
  633. super();
  634. this.#target = target;
  635. }
  636. get _title() {
  637. return "Do you want remove it?";
  638. }
  639. get _description() {
  640. let content = "You try to remove " + this.#target.name + ". ";
  641. content += "You can not restore it, when confirm.";
  642. return content;
  643. }
  644. async _action() {
  645. new delete_request(this.#target).connect();
  646. searcher.reload();
  647. }
  648. };
  649. // application/scripts/formscreen.js
  650. var formscreen = class extends fullscreen {
  651. #form;
  652. #result;
  653. constructor() {
  654. super();
  655. this.#form = null;
  656. this.#result = null;
  657. }
  658. get _name() {
  659. throw new TypeError("This is virtual getter!");
  660. }
  661. _process() {
  662. this._error = "This is abstract, and must be overwriten.";
  663. }
  664. _build_form() {
  665. throw new TypeError("This is virtual method!");
  666. }
  667. _get_input(name) {
  668. return this.get_query('input[name="' + name + '"]');
  669. }
  670. get _has_submit() {
  671. return true;
  672. }
  673. _build_node() {
  674. const center = document.createElement("div");
  675. center.classList.add("center");
  676. const title = document.createElement("div");
  677. title.classList.add("title");
  678. center.appendChild(title);
  679. const title_content = document.createElement("h3");
  680. title_content.innerText = this._name;
  681. title.appendChild(title_content);
  682. const form = document.createElement("form");
  683. center.appendChild(form);
  684. form.addEventListener("click", () => {
  685. this._clear_results();
  686. });
  687. this.#form = document.createElement("div");
  688. this.#form.classList.add("content");
  689. form.appendChild(this.#form);
  690. this.#result = document.createElement("div");
  691. this.#result.classList.add("result");
  692. form.appendChild(this.#result);
  693. const bottom = document.createElement("div");
  694. bottom.classList.add("bottom");
  695. form.appendChild(bottom);
  696. const close_button = document.createElement("button");
  697. close_button.classList.add("close");
  698. close_button.classList.add("material-icons");
  699. close_button.innerText = "close";
  700. close_button.type = "button";
  701. bottom.appendChild(close_button);
  702. if (this._has_submit) {
  703. const send_button = document.createElement("button");
  704. send_button.classList.add("send");
  705. send_button.classList.add("material-icons");
  706. send_button.innerText = "send";
  707. send_button.type = "submit";
  708. bottom.appendChild(send_button);
  709. }
  710. close_button.addEventListener("click", () => {
  711. this.hide();
  712. });
  713. form.addEventListener("submit", (target) => {
  714. target.preventDefault();
  715. this._process();
  716. });
  717. this._refresh();
  718. return center;
  719. }
  720. _refresh() {
  721. while (this.#form.lastChild) {
  722. this.#form.lastChild.remove();
  723. }
  724. this._build_form();
  725. }
  726. _create_input(name, label_text, placeholder, worker = null) {
  727. const container = document.createElement("div");
  728. container.classList.add("input-container");
  729. container.classList.add("input-" + name);
  730. const label = document.createElement("label");
  731. label.htmlFor = name;
  732. label.innerText = label_text;
  733. container.appendChild(label);
  734. const input = document.createElement("input");
  735. input.type = "text";
  736. input.placeholder = placeholder;
  737. input.name = name;
  738. input.id = name;
  739. container.appendChild(input);
  740. if (worker !== null) {
  741. worker(input);
  742. }
  743. if (!this.#form) {
  744. throw new Error("Screen is not visible yet!");
  745. }
  746. this._append_child(container);
  747. return () => {
  748. return input.value;
  749. };
  750. }
  751. _append_child(target) {
  752. this.#form.appendChild(target);
  753. }
  754. _clear_results() {
  755. if (!this.#result) {
  756. return;
  757. }
  758. while (this.#result.lastChild) {
  759. this.#result.lastChild.remove();
  760. }
  761. }
  762. set _info(target) {
  763. this._clear_results();
  764. const info = document.createElement("p");
  765. info.classList.add("info");
  766. info.innerText = target;
  767. if (this.#result) {
  768. this.#result.appendChild(info);
  769. }
  770. }
  771. set _error(target) {
  772. this._clear_results();
  773. const info = document.createElement("p");
  774. info.classList.add("error");
  775. info.innerText = target;
  776. if (this.#result) {
  777. this.#result.appendChild(info);
  778. }
  779. }
  780. set _success(target) {
  781. this._clear_results();
  782. const info = document.createElement("p");
  783. info.classList.add("success");
  784. info.innerText = target;
  785. if (this.#result) {
  786. this.#result.appendChild(info);
  787. }
  788. }
  789. };
  790. // application/scripts/product_base.js
  791. var product_base = class {
  792. name;
  793. description;
  794. author;
  795. barcode;
  796. stock_count;
  797. constructor(target = null) {
  798. this.name = this._extract(target, "name");
  799. this.description = this._extract(target, "description");
  800. this.author = this._extract(target, "author");
  801. this.barcode = this._extract(target, "barcode");
  802. this.stock_count = this._extract(target, "stock_count");
  803. if (this.stock_count !== null) {
  804. this.stock_count = Number(this.stock_count);
  805. }
  806. }
  807. get dump() {
  808. return {
  809. "name": this.name,
  810. "description": this.description,
  811. "author": this.author,
  812. "barcode": this.barcode,
  813. "stock_count": this.stock_count
  814. };
  815. }
  816. _extract(dict, name) {
  817. if (dict === null) {
  818. return null;
  819. }
  820. if (name in dict) {
  821. return dict[name];
  822. }
  823. return null;
  824. }
  825. get avairable() {
  826. return this.stock_count > 0;
  827. }
  828. };
  829. // application/scripts/edit_request.js
  830. var edit_request = class extends request {
  831. #target;
  832. #updated;
  833. constructor(target, updated) {
  834. super();
  835. this.#target = target;
  836. this.#updated = updated;
  837. }
  838. get _response() {
  839. return bool_response;
  840. }
  841. get data() {
  842. return Object.assign(this.#updated.dump, {
  843. "apikey": this._apikey
  844. });
  845. }
  846. get method() {
  847. return "POST";
  848. }
  849. get url() {
  850. return "/product/update/barcode/" + this.#target.barcode;
  851. }
  852. };
  853. // application/scripts/edit_image_request.js
  854. var edit_image_request = class extends request {
  855. #image;
  856. #target;
  857. constructor(target, image) {
  858. super();
  859. this.#target = target;
  860. this.#image = image;
  861. }
  862. get _response() {
  863. return bool_response;
  864. }
  865. get data() {
  866. return {
  867. "image": this.#image,
  868. "apikey": this._apikey
  869. };
  870. }
  871. get method() {
  872. return "POST";
  873. }
  874. get url() {
  875. return "/product/update/image/barcode/" + this.#target.barcode;
  876. }
  877. };
  878. // application/scripts/product_editor.js
  879. var product_editor = class extends formscreen {
  880. #target;
  881. #name;
  882. #description;
  883. #author;
  884. #barcode;
  885. #stock_count;
  886. #image;
  887. constructor(target) {
  888. super();
  889. this.#target = target;
  890. }
  891. get target() {
  892. return this.#target;
  893. }
  894. get _name() {
  895. return "Product editor";
  896. }
  897. _build_form() {
  898. this.#name = this._create_input(
  899. "name",
  900. "Name:",
  901. "Sample...",
  902. (input) => {
  903. input.value = this.#target.name;
  904. }
  905. );
  906. this.#description = this._create_input(
  907. "description",
  908. "Description:",
  909. "This is sample product...",
  910. (input) => {
  911. input.value = this.#target.description;
  912. }
  913. );
  914. this.#author = this._create_input(
  915. "author",
  916. "Author:",
  917. "Jack Black",
  918. (input) => {
  919. input.value = this.#target.author;
  920. }
  921. );
  922. this.#barcode = this._create_input(
  923. "barcode",
  924. "Barcode (EAN):",
  925. "123456789012...",
  926. (input) => {
  927. input.type = "number";
  928. input.value = this.#target.barcode;
  929. }
  930. );
  931. this.#stock_count = this._create_input(
  932. "stock_count",
  933. "Stock count:",
  934. "10...",
  935. (input) => {
  936. input.type = "number";
  937. input.value = this.#target.stock_count;
  938. }
  939. );
  940. this._create_input(
  941. "image",
  942. "Change product image:",
  943. "",
  944. (input) => {
  945. this.#image = input;
  946. input.type = "file";
  947. input.accept = "image/*";
  948. }
  949. );
  950. }
  951. async #code_image() {
  952. if (this.#image.files.length === 0) {
  953. return null;
  954. }
  955. const file = this.#image.files.item(0);
  956. const buffer = await file.arrayBuffer();
  957. const list = new Uint8Array(buffer);
  958. let content = new String();
  959. list.forEach((code) => {
  960. content += String.fromCharCode(code);
  961. });
  962. return btoa(content);
  963. }
  964. async #submit() {
  965. const copy = this.#target.copy();
  966. copy.name = this.#name();
  967. copy.description = this.#description();
  968. copy.author = this.#author();
  969. copy.barcode = this.#barcode();
  970. copy.stock_count = this.#stock_count();
  971. const request2 = new edit_request(this.#target, copy);
  972. const response = await request2.connect();
  973. if (!response.result) {
  974. throw new Error(response.cause);
  975. }
  976. this.#target = copy;
  977. }
  978. async #image_submit() {
  979. const image = await this.#code_image();
  980. if (image === null) {
  981. return;
  982. }
  983. const request2 = new edit_image_request(this.#target, image);
  984. const response = await request2.connect();
  985. if (!response.result) {
  986. throw new Error(response.cause);
  987. }
  988. }
  989. async _process() {
  990. try {
  991. this._info = "Uploading...";
  992. await this.#submit();
  993. this._info = "Processing image...";
  994. await this.#image_submit();
  995. this._success = "Updated success!";
  996. searcher.reload();
  997. setTimeout(() => {
  998. this.hide();
  999. }, 500);
  1000. } catch (error) {
  1001. this._error = new String(error);
  1002. }
  1003. }
  1004. };
  1005. // application/scripts/rents_screen.js
  1006. var rents_screen = class extends formscreen {
  1007. #target;
  1008. #email;
  1009. #phone;
  1010. get _email() {
  1011. return this.#email();
  1012. }
  1013. get _phone() {
  1014. return this.#phone();
  1015. }
  1016. constructor(target) {
  1017. super();
  1018. this.#target = target;
  1019. }
  1020. get _target() {
  1021. return this.#target;
  1022. }
  1023. _build_form() {
  1024. this.#email = this._create_input(
  1025. "email",
  1026. "E-mail:",
  1027. "[email protected]",
  1028. (input) => {
  1029. input.type = "email";
  1030. }
  1031. );
  1032. this.#phone = this._create_input(
  1033. "phone",
  1034. "Phone number:",
  1035. "+1 123-456-789",
  1036. (input) => {
  1037. input.type = "tel";
  1038. const add_prefix = () => {
  1039. if (input.value.length === 0) {
  1040. input.value = "+48 ";
  1041. }
  1042. };
  1043. input.addEventListener("click", add_prefix);
  1044. input.addEventListener("focus", add_prefix);
  1045. }
  1046. );
  1047. }
  1048. };
  1049. // application/scripts/reservation.js
  1050. var reservation = class _reservation {
  1051. email;
  1052. phone_number;
  1053. product_barcode;
  1054. constructor(target = null) {
  1055. this.email = null;
  1056. this.phone_number = null;
  1057. this.product_barcode = null;
  1058. if (target === null) {
  1059. return;
  1060. }
  1061. if ("email" in target) {
  1062. this.email = target["email"];
  1063. }
  1064. if ("target_barcode" in target) {
  1065. this.product_barcode = target["target_barcode"];
  1066. }
  1067. if ("phone_number" in target) {
  1068. this.phone_number = target["phone_number"];
  1069. }
  1070. }
  1071. get dump() {
  1072. const dumped = {
  1073. "target_barcode": this.product_barcode
  1074. };
  1075. if (this.email !== null) {
  1076. dumped["email"] = this.email;
  1077. }
  1078. if (this.phone_number !== null) {
  1079. dumped["phone_number"] = this.phone_number;
  1080. }
  1081. return dumped;
  1082. }
  1083. get ready() {
  1084. if (this.product_barcode === null) return false;
  1085. if (this.email === null && this.phone_number === null) return false;
  1086. return true;
  1087. }
  1088. copy() {
  1089. return new _reservation(this.dump);
  1090. }
  1091. };
  1092. // application/scripts/product_rent_request.js
  1093. var product_rent_request = class extends request {
  1094. #reservation;
  1095. constructor(reservation2) {
  1096. super();
  1097. this.#reservation = reservation2;
  1098. }
  1099. get data() {
  1100. return Object.assign(this.#reservation.dump, {
  1101. "apikey": this._apikey
  1102. });
  1103. }
  1104. get _response() {
  1105. return bool_response;
  1106. }
  1107. get method() {
  1108. return "POST";
  1109. }
  1110. get url() {
  1111. return "/rent/product/barcode/" + this.#reservation.product_barcode;
  1112. }
  1113. };
  1114. // application/scripts/reservation_factory.js
  1115. var reservation_factory = class {
  1116. #target;
  1117. constructor() {
  1118. this.#target = new reservation();
  1119. }
  1120. phone_number(target) {
  1121. target = target.trim().replaceAll("-", "");
  1122. if (target.length === 0) {
  1123. target = null;
  1124. }
  1125. this.#target.phone_number = target;
  1126. return this;
  1127. }
  1128. email(target) {
  1129. target = target.trim();
  1130. if (target.length === 0) {
  1131. target = null;
  1132. }
  1133. this.#target.email = target;
  1134. return this;
  1135. }
  1136. product(target) {
  1137. this.#target.product_barcode = target.barcode;
  1138. return this;
  1139. }
  1140. result() {
  1141. if (this.#target.ready) {
  1142. return this.#target;
  1143. }
  1144. throw new Error("Target reservation is not ready yet.");
  1145. }
  1146. };
  1147. // application/scripts/product_rent.js
  1148. var product_rent = class extends rents_screen {
  1149. get _name() {
  1150. return "Product rent";
  1151. }
  1152. async _process() {
  1153. try {
  1154. this._info = "Processing...";
  1155. const target = new reservation_factory().email(this._email).phone_number(this._phone).product(this._target).result();
  1156. const request2 = new product_rent_request(target);
  1157. const response = await request2.connect();
  1158. if (!response.result) {
  1159. throw new Error(response.cause);
  1160. }
  1161. this._success = "New rent added.";
  1162. searcher.reload();
  1163. setTimeout(() => {
  1164. this.hide();
  1165. }, 500);
  1166. } catch (error) {
  1167. this._error = String(error);
  1168. }
  1169. }
  1170. };
  1171. // application/scripts/product_give_back_request.js
  1172. var product_give_back_request = class extends request {
  1173. #reservation;
  1174. constructor(reservation2) {
  1175. super();
  1176. this.#reservation = reservation2;
  1177. }
  1178. get data() {
  1179. return Object.assign(this.#reservation.dump, {
  1180. "apikey": this._apikey
  1181. });
  1182. }
  1183. get _response() {
  1184. return bool_response;
  1185. }
  1186. get method() {
  1187. return "POST";
  1188. }
  1189. get url() {
  1190. return "/give_back/product/barcode/" + this.#reservation.product_barcode;
  1191. }
  1192. };
  1193. // application/scripts/product_give_back.js
  1194. var product_give_back = class extends rents_screen {
  1195. get _name() {
  1196. return "Product give back";
  1197. }
  1198. async _process() {
  1199. try {
  1200. this._info = "Processing...";
  1201. const target = new reservation_factory().email(this._email).phone_number(this._phone).product(this._target).result();
  1202. const request2 = new product_give_back_request(target);
  1203. const response = await request2.connect();
  1204. if (!response.result) {
  1205. throw new Error(response.cause);
  1206. }
  1207. this._success = "Success!";
  1208. searcher.reload();
  1209. setTimeout(() => {
  1210. this.hide();
  1211. }, 500);
  1212. } catch (error) {
  1213. this._error = String(error);
  1214. }
  1215. }
  1216. };
  1217. // application/scripts/reservations_response.js
  1218. var reservations_response = class extends bool_response {
  1219. #collection;
  1220. constructor(target) {
  1221. super(target);
  1222. if (!this.result) {
  1223. return;
  1224. }
  1225. this.#collection = new Array();
  1226. target["reservations"].forEach((count) => {
  1227. this.#collection.push(new reservation(count));
  1228. });
  1229. }
  1230. get collection() {
  1231. if (!this.result) {
  1232. throw new Error(this.cause);
  1233. }
  1234. return this.#collection;
  1235. }
  1236. };
  1237. // application/scripts/product_reservations_request.js
  1238. var product_reservations_request = class extends request {
  1239. #target;
  1240. constructor(target) {
  1241. super();
  1242. this.#target = target;
  1243. }
  1244. get _response() {
  1245. return reservations_response;
  1246. }
  1247. get data() {
  1248. return {
  1249. "apikey": this._apikey
  1250. };
  1251. }
  1252. get method() {
  1253. return "POST";
  1254. }
  1255. get url() {
  1256. return "/reservations/product/barcode/" + this.#target.barcode;
  1257. }
  1258. };
  1259. // application/scripts/product_all_rents.js
  1260. var product_all_rents = class extends formscreen {
  1261. #target;
  1262. constructor(target) {
  1263. super();
  1264. this.#target = target;
  1265. }
  1266. get _name() {
  1267. return "All rents";
  1268. }
  1269. get _has_submit() {
  1270. return false;
  1271. }
  1272. #create_single(target) {
  1273. const container = document.createElement("div");
  1274. container.classList.add("reservation-info");
  1275. if (target.phone_number !== null) {
  1276. const phone_icon = document.createElement("span");
  1277. phone_icon.classList.add("material-icons");
  1278. phone_icon.innerText = "phone";
  1279. const phone_number = document.createElement("span");
  1280. phone_number.classList.add("numbers");
  1281. phone_number.innerText = target.phone_number;
  1282. const phone_number_container = document.createElement("p");
  1283. phone_number_container.appendChild(phone_icon);
  1284. phone_number_container.appendChild(phone_number);
  1285. container.appendChild(phone_number_container);
  1286. }
  1287. if (target.email !== null) {
  1288. const email_icon = document.createElement("span");
  1289. email_icon.classList.add("material-icons");
  1290. email_icon.innerText = "mail";
  1291. const email = document.createElement("span");
  1292. email.innerText = target.email;
  1293. const email_container = document.createElement("p");
  1294. email_container.appendChild(email_icon);
  1295. email_container.appendChild(email);
  1296. container.appendChild(email_container);
  1297. }
  1298. return container;
  1299. }
  1300. #create_single_button(target) {
  1301. const button = document.createElement("button");
  1302. button.classList.add("material-icons");
  1303. button.classList.add("give-back-button");
  1304. button.innerText = "save_alt";
  1305. button.addEventListener("click", async () => {
  1306. try {
  1307. this._info = "Processing...";
  1308. const request2 = new product_give_back_request(target);
  1309. const response = await request2.connect();
  1310. if (!response.result) {
  1311. throw new Error(response.cause);
  1312. }
  1313. this._refresh();
  1314. searcher.reload();
  1315. } catch (error) {
  1316. this._error = String(error);
  1317. }
  1318. });
  1319. return button;
  1320. }
  1321. _process() {
  1322. return;
  1323. }
  1324. async _build_form() {
  1325. try {
  1326. this._info = "Loading...";
  1327. const request2 = new product_reservations_request(this.#target);
  1328. const response = await request2.connect();
  1329. const list = document.createElement("div");
  1330. list.classList.add("reservations-list");
  1331. let empty = true;
  1332. response.collection.forEach((count) => {
  1333. const item = document.createElement("div");
  1334. item.classList.add("reservation");
  1335. const left = this.#create_single(count);
  1336. const right = this.#create_single_button(count);
  1337. empty = false;
  1338. item.appendChild(left);
  1339. item.appendChild(right);
  1340. list.appendChild(item);
  1341. });
  1342. this._append_child(list);
  1343. if (empty) {
  1344. this._success = "Not found any reservations.";
  1345. } else {
  1346. this._clear_results();
  1347. }
  1348. } catch (error) {
  1349. this._error = String(error);
  1350. }
  1351. }
  1352. };
  1353. // application/scripts/product_not_avairable.js
  1354. var product_not_avairable = class extends confirm_action {
  1355. get _title() {
  1356. return "Error";
  1357. }
  1358. get _description() {
  1359. return "This product is not avairable. Anybody can not rent it.";
  1360. }
  1361. get _info() {
  1362. return true;
  1363. }
  1364. };
  1365. // application/scripts/product_container.js
  1366. var product_container = class {
  1367. #target;
  1368. #node;
  1369. #login;
  1370. constructor(target) {
  1371. this.#target = new product(target.dump);
  1372. this.#node = null;
  1373. this.#login = new login_manager().logged_in;
  1374. }
  1375. get #header() {
  1376. const header = document.createElement("div");
  1377. header.classList.add("header");
  1378. const title = document.createElement("h3");
  1379. title.innerText = this.#target.name;
  1380. header.appendChild(title);
  1381. if (this.#login) {
  1382. header.appendChild(this.#manage);
  1383. }
  1384. return header;
  1385. }
  1386. get #manage() {
  1387. const manage = document.createElement("div");
  1388. manage.classList.add("manage");
  1389. const all_rents_button = document.createElement("button");
  1390. all_rents_button.classList.add("material-icons");
  1391. all_rents_button.classList.add("all-rents-button");
  1392. all_rents_button.innerText = "list";
  1393. manage.appendChild(all_rents_button);
  1394. const rent_button = document.createElement("button");
  1395. rent_button.classList.add("material-icons");
  1396. rent_button.classList.add("rent-button");
  1397. rent_button.innerText = "backpack";
  1398. manage.appendChild(rent_button);
  1399. const give_back_button = document.createElement("button");
  1400. give_back_button.classList.add("material-icons");
  1401. give_back_button.classList.add("give-back-button");
  1402. give_back_button.innerText = "save_alt";
  1403. manage.appendChild(give_back_button);
  1404. const edit_button = document.createElement("button");
  1405. edit_button.classList.add("material-icons");
  1406. edit_button.classList.add("edit-button");
  1407. edit_button.innerText = "edit";
  1408. manage.appendChild(edit_button);
  1409. const delete_button = document.createElement("button");
  1410. delete_button.classList.add("material-icons");
  1411. delete_button.classList.add("delete-button");
  1412. delete_button.innerText = "remove_circle_outline";
  1413. manage.appendChild(delete_button);
  1414. all_rents_button.addEventListener("click", () => {
  1415. new product_all_rents(this.#target).show();
  1416. });
  1417. rent_button.addEventListener("click", () => {
  1418. if (this.#target.on_stock > 0) {
  1419. new product_rent(this.#target).show();
  1420. } else {
  1421. new product_not_avairable().show();
  1422. }
  1423. });
  1424. give_back_button.addEventListener("click", () => {
  1425. new product_give_back(this.#target).show();
  1426. });
  1427. edit_button.addEventListener("click", () => {
  1428. new product_editor(this.#target).show();
  1429. });
  1430. delete_button.addEventListener("click", () => {
  1431. new delete_product_window(this.#target).show();
  1432. });
  1433. return manage;
  1434. }
  1435. get #description() {
  1436. const container = document.createElement("div");
  1437. container.classList.add("description");
  1438. const description = document.createElement("p");
  1439. description.innerText = this.#target.description;
  1440. description.classList.add("content");
  1441. const author_container = document.createElement("div");
  1442. author_container.classList.add("author");
  1443. const author = document.createElement("span");
  1444. author.innerText = this.#target.author;
  1445. const author_icon = document.createElement("span");
  1446. author_icon.classList.add("material-icons");
  1447. author_icon.innerText = "attribution";
  1448. author_container.appendChild(author_icon);
  1449. author_container.appendChild(author);
  1450. const stock_count = document.createElement("p");
  1451. stock_count.classList.add("stock-count");
  1452. stock_count.classList.add("material-icons");
  1453. if (this.#target.on_stock > 0) {
  1454. stock_count.innerText = "check_circle";
  1455. stock_count.classList.add("avairable");
  1456. } else {
  1457. stock_count.innerText = "cancel";
  1458. stock_count.classList.add("unavairable");
  1459. }
  1460. const barcode_container = document.createElement("p");
  1461. barcode_container.classList.add("barcode");
  1462. const barcode = document.createElement("span");
  1463. barcode.innerText = this.#target.barcode;
  1464. barcode.classList.add("numbers");
  1465. const barcode_icon = document.createElement("span");
  1466. barcode_icon.classList.add("material-icons");
  1467. barcode_icon.innerText = "qr_code_scanner";
  1468. barcode_container.appendChild(barcode_icon);
  1469. barcode_container.appendChild(barcode);
  1470. container.appendChild(description);
  1471. container.appendChild(author_container);
  1472. container.appendChild(barcode_container);
  1473. container.appendChild(stock_count);
  1474. return container;
  1475. }
  1476. get #cache_bypass() {
  1477. return "?cache=" + new String(Math.floor(Math.random() * 100));
  1478. }
  1479. get #image() {
  1480. const image = document.createElement("img");
  1481. image.classList.add("image");
  1482. image.src = this.#target.thumbnail + this.#cache_bypass;
  1483. image.alt = this.#target.name;
  1484. image.addEventListener("click", () => {
  1485. new product_fullscreen(this.#target).show();
  1486. });
  1487. return image;
  1488. }
  1489. get node() {
  1490. if (this.#node !== null) {
  1491. return this.#node;
  1492. }
  1493. const bottom_container = document.createElement("div");
  1494. bottom_container.classList.add("bottom-container");
  1495. bottom_container.appendChild(this.#description);
  1496. bottom_container.appendChild(this.#image);
  1497. const container = document.createElement("div");
  1498. container.classList.add("product");
  1499. container.appendChild(this.#header);
  1500. container.appendChild(bottom_container);
  1501. return this.#node = container;
  1502. }
  1503. add(target) {
  1504. const node = this.node;
  1505. node.style.opacity = "0";
  1506. node.style.transition = "opacity 0.5s";
  1507. target.appendChild(node);
  1508. setTimeout(() => {
  1509. node.style.opacity = "1";
  1510. }, 50);
  1511. }
  1512. drop() {
  1513. const container = this.#node;
  1514. if (container === null) {
  1515. throw new TypeError("It is not showed yet.");
  1516. }
  1517. container.style.opacity = "1";
  1518. container.style.transition = "opacity 0.5s";
  1519. setTimeout(() => {
  1520. container.style.opacity = "0";
  1521. }, 50);
  1522. setTimeout(() => {
  1523. this.#node = null;
  1524. container.remove();
  1525. }, 550);
  1526. }
  1527. };
  1528. // application/scripts/login_prompt.js
  1529. var login_prompt = class extends formscreen {
  1530. #nick;
  1531. #password;
  1532. constructor(target) {
  1533. super();
  1534. target.addEventListener("click", () => {
  1535. this.show();
  1536. });
  1537. }
  1538. get _name() {
  1539. return "Login";
  1540. }
  1541. async _process() {
  1542. try {
  1543. this._info = "Processing...";
  1544. await this.#login();
  1545. this._success = "Logged in!";
  1546. setTimeout(() => {
  1547. location.reload();
  1548. }, 250);
  1549. } catch (error) {
  1550. this._error = new String(error);
  1551. }
  1552. }
  1553. async #login() {
  1554. const manager = new login_manager();
  1555. const result = await manager.login(
  1556. this.#nick(),
  1557. this.#password()
  1558. );
  1559. if (result) {
  1560. return;
  1561. }
  1562. throw new Error("Can not login. Check nick and password.");
  1563. }
  1564. _build_form() {
  1565. this.#nick = this._create_input(
  1566. "nick",
  1567. "Nick:",
  1568. "Sample..."
  1569. );
  1570. this.#password = this._create_input(
  1571. "password",
  1572. "Password:",
  1573. "ABCDEFGH",
  1574. (input) => {
  1575. input.type = "password";
  1576. }
  1577. );
  1578. }
  1579. };
  1580. // application/scripts/create_request.js
  1581. var create_request = class extends request {
  1582. #image;
  1583. #product;
  1584. constructor(product2, image) {
  1585. super();
  1586. this.#image = image;
  1587. this.#product = product2;
  1588. }
  1589. get _response() {
  1590. return bool_response;
  1591. }
  1592. get data() {
  1593. return Object.assign(this.#product.dump, {
  1594. "image": this.#image,
  1595. "apikey": this._apikey
  1596. });
  1597. }
  1598. get method() {
  1599. return "POST";
  1600. }
  1601. get url() {
  1602. return "/product/create";
  1603. }
  1604. };
  1605. // application/scripts/product_adder.js
  1606. var product_adder = class extends formscreen {
  1607. #name;
  1608. #description;
  1609. #author;
  1610. #barcode;
  1611. #stock_count;
  1612. #image;
  1613. get _name() {
  1614. return "Add product";
  1615. }
  1616. _build_form() {
  1617. this.#name = this._create_input(
  1618. "name",
  1619. "Name:",
  1620. "Sample..."
  1621. );
  1622. this.#description = this._create_input(
  1623. "description",
  1624. "Description:",
  1625. "This is sample product..."
  1626. );
  1627. this.#author = this._create_input(
  1628. "author",
  1629. "Author:",
  1630. "Jack Black"
  1631. );
  1632. this.#barcode = this._create_input(
  1633. "barcode",
  1634. "Barcode (EAN):",
  1635. "123456789012...",
  1636. (input) => {
  1637. input.type = "number";
  1638. }
  1639. );
  1640. this.#stock_count = this._create_input(
  1641. "stock_count",
  1642. "Stock count:",
  1643. "10...",
  1644. (input) => {
  1645. input.type = "number";
  1646. }
  1647. );
  1648. this._create_input(
  1649. "image",
  1650. "Product image:",
  1651. "",
  1652. (input) => {
  1653. this.#image = input;
  1654. input.type = "file";
  1655. input.accept = "image/*";
  1656. }
  1657. );
  1658. }
  1659. async #code_image() {
  1660. if (this.#image.files.length === 0) {
  1661. throw new Error("Upload image for product.");
  1662. }
  1663. const file = this.#image.files.item(0);
  1664. const buffer = await file.arrayBuffer();
  1665. const list = new Uint8Array(buffer);
  1666. let content = new String();
  1667. list.forEach((code) => {
  1668. content += String.fromCharCode(code);
  1669. });
  1670. return btoa(content);
  1671. }
  1672. async #submit() {
  1673. const product2 = new product_base();
  1674. product2.name = this.#name();
  1675. product2.description = this.#description();
  1676. product2.author = this.#author();
  1677. product2.stock_count = this.#stock_count();
  1678. product2.barcode = this.#barcode();
  1679. const image = await this.#code_image();
  1680. const request2 = new create_request(product2, image);
  1681. const response = await request2.connect();
  1682. if (!response.result) {
  1683. throw new Error(response.cause);
  1684. }
  1685. }
  1686. async _process() {
  1687. try {
  1688. this._info = "Uploading...";
  1689. await this.#submit();
  1690. this._success = "Created success!";
  1691. searcher.reload();
  1692. setTimeout(() => {
  1693. this.hide();
  1694. }, 500);
  1695. } catch (error) {
  1696. this._error = new String(error);
  1697. }
  1698. }
  1699. };
  1700. // application/scripts/login_bar.js
  1701. var login_bar = class {
  1702. #manager;
  1703. constructor(target) {
  1704. this.#manager = new login_manager();
  1705. if (!this.#manager.logged_in) {
  1706. this.#not_logged(target);
  1707. return;
  1708. }
  1709. this.#logged(target);
  1710. }
  1711. #not_login_propertly() {
  1712. this.#manager.logout();
  1713. location.reload();
  1714. }
  1715. async #logged(target) {
  1716. const user2 = await this.#manager.get_user();
  1717. if (user2 === null) {
  1718. this.#not_login_propertly();
  1719. }
  1720. const info_icon = document.createElement("span");
  1721. info_icon.classList.add("icon");
  1722. info_icon.classList.add("material-icons");
  1723. info_icon.innerText = "account_circle";
  1724. const info_content = document.createElement("span");
  1725. info_content.innerText = user2.nick;
  1726. const info = document.createElement("p");
  1727. info.classList.add("login-info");
  1728. info.appendChild(info_icon);
  1729. info.appendChild(info_content);
  1730. target.appendChild(info);
  1731. const logout_button = document.createElement("button");
  1732. logout_button.innerText = "logout";
  1733. logout_button.classList.add("logout-button");
  1734. logout_button.classList.add("material-icons");
  1735. target.appendChild(logout_button);
  1736. const add_product_button = document.createElement("button");
  1737. add_product_button.innerText = "add";
  1738. add_product_button.classList.add("add-product-button");
  1739. add_product_button.classList.add("material-icons");
  1740. target.appendChild(add_product_button);
  1741. add_product_button.addEventListener("click", () => {
  1742. new product_adder().show();
  1743. });
  1744. logout_button.addEventListener("click", () => {
  1745. this.#manager.logout();
  1746. location.reload();
  1747. });
  1748. }
  1749. #not_logged(target) {
  1750. const login_button = document.createElement("button");
  1751. login_button.innerText = "account_circle";
  1752. login_button.classList.add("login-button");
  1753. login_button.classList.add("material-icons");
  1754. target.appendChild(login_button);
  1755. new login_prompt(login_button);
  1756. }
  1757. };
  1758. // application/scripts/scroll_up.js
  1759. var scroll_up = class {
  1760. #button;
  1761. constructor(button) {
  1762. this.#button = button;
  1763. this.#update();
  1764. document.addEventListener("scroll", () => {
  1765. this.#update();
  1766. });
  1767. this.#button.addEventListener("click", () => {
  1768. this.scroll();
  1769. });
  1770. }
  1771. scroll() {
  1772. this.#position = 0;
  1773. }
  1774. get #position() {
  1775. return document.scrollingElement.scrollTop;
  1776. }
  1777. set #position(target) {
  1778. document.scrollingElement.scrollTop = target;
  1779. }
  1780. get #visible() {
  1781. return Number(this.#button.style.opacity) === 1;
  1782. }
  1783. set #visible(target) {
  1784. this.#button.style.opacity = target ? "1" : "0";
  1785. }
  1786. get #margin() {
  1787. return 20;
  1788. }
  1789. #update() {
  1790. this.#visible = this.#position > this.#margin;
  1791. }
  1792. };
  1793. // application/scripts/color_theme.js
  1794. var color_theme = class {
  1795. #button;
  1796. #themes;
  1797. get themes() {
  1798. return Object.keys(this.#themes);
  1799. }
  1800. theme_name(target) {
  1801. return this.#themes[target];
  1802. }
  1803. constructor(button, themes = null) {
  1804. this.#button = button;
  1805. this.#themes = themes;
  1806. if (this.#themes === null) {
  1807. this.#themes = {
  1808. "dark-theme": "Dark",
  1809. "white-theme": "White"
  1810. };
  1811. }
  1812. this.#load();
  1813. this.#button.addEventListener("click", () => {
  1814. this.change();
  1815. });
  1816. }
  1817. get current() {
  1818. if (localStorage.hasOwnProperty("theme")) {
  1819. return localStorage.getItem("theme");
  1820. }
  1821. return this.themes[this.themes.length - 1];
  1822. }
  1823. #load() {
  1824. this.#show(this.current);
  1825. }
  1826. #save(target) {
  1827. localStorage.setItem("theme", target);
  1828. }
  1829. #show(target) {
  1830. const themes = this.themes;
  1831. const body = document.querySelector("body");
  1832. body.classList.forEach((count) => {
  1833. if (themes.indexOf(count) !== -1) {
  1834. body.classList.remove(count);
  1835. }
  1836. });
  1837. body.classList.add(target);
  1838. }
  1839. change() {
  1840. const themes = this.themes;
  1841. const current = this.current;
  1842. let position = themes.indexOf(current) + 1;
  1843. if (position === themes.length) {
  1844. position = 0;
  1845. }
  1846. const updated = themes[position];
  1847. this.#save(updated);
  1848. this.#show(updated);
  1849. }
  1850. };
  1851. // application/scripts/core.js
  1852. document.addEventListener("DOMContentLoaded", async () => {
  1853. const top_bar_spacing = new height_equaler(
  1854. document.querySelector(".top-bar"),
  1855. document.querySelector(".top-bar-spacing")
  1856. );
  1857. const container = document.querySelector(".products");
  1858. const search_bar = document.querySelector("form.search");
  1859. const search_title = document.querySelector(".search-title");
  1860. const login_space = document.querySelector(".top-bar .right");
  1861. const scroll_up_button = document.querySelector(".scroll-up-button");
  1862. const reverse_colors = document.querySelector(".reverse-colors");
  1863. const manager = new product_containers(container);
  1864. new login_bar(login_space);
  1865. new scroll_up(scroll_up_button);
  1866. new color_theme(reverse_colors);
  1867. new searcher(search_bar, manager, search_title).show_all();
  1868. });
  1869. })();