app.js 69 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476
  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. try {
  56. this.stock_count = Number(this.stock_count);
  57. } catch {
  58. this.stock_count = 0;
  59. }
  60. try {
  61. this.on_stock = Number(this.on_stock);
  62. } catch {
  63. this.on_stock = 0;
  64. }
  65. }
  66. get dump() {
  67. const dumped = {
  68. "name": new String(this.name),
  69. "description": new String(this.description),
  70. "author": new String(this.author),
  71. "image": new String(this.image),
  72. "barcode": new String(this.barcode),
  73. "thumbnail": new String(this.thumbnail),
  74. "stock_count": new String(this.stock_count)
  75. };
  76. if (this.on_stock !== null) {
  77. dumped["on_stock"] = new String(this.on_stock);
  78. }
  79. return dumped;
  80. }
  81. get ready() {
  82. if (this.name === null || this.description === null) return false;
  83. if (this.author === null || this.image === null) return false;
  84. if (this.stock_count === null || this.barcode === null) return false;
  85. if (this.thumbnail === null) return false;
  86. return true;
  87. }
  88. copy() {
  89. return new _product(this.dump);
  90. }
  91. };
  92. // application/scripts/products_loader.js
  93. var products_loader = class _products_loader {
  94. static async all() {
  95. const request2 = await fetch("/products/");
  96. const response = await request2.json();
  97. return _products_loader.#response_to_collection(response);
  98. }
  99. static #response_to_collection(response) {
  100. const result = new Array();
  101. if (response.result !== "success") {
  102. return result;
  103. }
  104. response.collection.forEach((serialized) => {
  105. result.push(new product(serialized));
  106. });
  107. return result;
  108. }
  109. static async search_name(name) {
  110. return await _products_loader.#search(
  111. "/product/search/name",
  112. name
  113. );
  114. }
  115. static async search_author(author) {
  116. return await _products_loader.#search(
  117. "/product/search/author",
  118. author
  119. );
  120. }
  121. static async #search(path, parameter) {
  122. const coded = encodeURI(parameter);
  123. const request2 = await fetch(path + "/" + coded);
  124. const response = await request2.json();
  125. return _products_loader.#response_to_collection(response);
  126. }
  127. };
  128. // application/scripts/fullscreen.js
  129. var fullscreen = class {
  130. #node;
  131. constructor() {
  132. this.#node = null;
  133. }
  134. get visible() {
  135. return this.#node !== null;
  136. }
  137. _build_node() {
  138. throw new TypeError("This is virtual method!");
  139. }
  140. get #opacity() {
  141. if (!this.visible) {
  142. throw new TypeError("Can not change opacity of not existed.");
  143. }
  144. return Number(this.#node.style.opacity);
  145. }
  146. set #opacity(target) {
  147. if (!this.visible) {
  148. throw new TypeError("Can not change opacity of not existed.");
  149. }
  150. this.#node.style.opacity = String(target);
  151. }
  152. get_query(selector) {
  153. if (!this.visible) {
  154. throw new TypeError("Can not get item from not visible.");
  155. }
  156. return this.#node.querySelector(selector);
  157. }
  158. #prepare() {
  159. const container = document.createElement("div");
  160. container.classList.add("fullscreen-viewer");
  161. container.style.transition = "opacity 0.5s";
  162. container.appendChild(this._build_node());
  163. return container;
  164. }
  165. hide() {
  166. if (!this.visible) {
  167. return;
  168. }
  169. this.#opacity = 0;
  170. setTimeout(() => {
  171. if (!this.visible) {
  172. return;
  173. }
  174. this.#node.remove();
  175. this.#node = null;
  176. }, 500);
  177. }
  178. show() {
  179. if (this.visible) {
  180. return;
  181. }
  182. this.#node = this.#prepare();
  183. this.#opacity = 0;
  184. document.querySelector("body").appendChild(this.#node);
  185. setTimeout(() => {
  186. this.#opacity = 1;
  187. }, 100);
  188. }
  189. };
  190. // application/scripts/product_fullscreen.js
  191. var product_fullscreen = class extends fullscreen {
  192. #target;
  193. constructor(target) {
  194. super();
  195. this.#target = target;
  196. }
  197. get target() {
  198. return this.#target;
  199. }
  200. _build_node() {
  201. const container = document.createElement("div");
  202. container.classList.add("product-fullscreen-viewer");
  203. const image = document.createElement("div");
  204. image.style.backgroundImage = 'url("' + this.target.image + '")';
  205. image.classList.add("image");
  206. container.appendChild(image);
  207. const title = document.createElement("div");
  208. title.classList.add("title");
  209. container.appendChild(title);
  210. const title_content = document.createElement("h1");
  211. title_content.innerText = this.target.name;
  212. title.appendChild(title_content);
  213. const bottom = document.createElement("div");
  214. bottom.classList.add("bottom-side");
  215. container.appendChild(bottom);
  216. const bottom_header = document.createElement("div");
  217. bottom_header.classList.add("bottom-header");
  218. bottom.appendChild(bottom_header);
  219. const barcode_icon = document.createElement("span");
  220. barcode_icon.classList.add("material-icons");
  221. barcode_icon.innerText = "qr_code_scanner";
  222. const barcode_content = document.createElement("span");
  223. barcode_content.innerText = this.target.barcode;
  224. barcode_content.classList.add("numbers");
  225. const barcode = document.createElement("p");
  226. barcode.appendChild(barcode_icon);
  227. barcode.appendChild(barcode_content);
  228. bottom_header.appendChild(barcode);
  229. const author_icon = document.createElement("span");
  230. author_icon.classList.add("material-icons");
  231. author_icon.innerText = "attribution";
  232. const author_content = document.createElement("span");
  233. author_content.innerText = this.target.author;
  234. const author = document.createElement("p");
  235. author.appendChild(author_icon);
  236. author.appendChild(author_content);
  237. bottom_header.appendChild(author);
  238. const description = document.createElement("div");
  239. description.classList.add("description");
  240. bottom.appendChild(description);
  241. const description_content = document.createElement("p");
  242. description_content.innerText = this.target.description;
  243. description.appendChild(description_content);
  244. const close_button = document.createElement("button");
  245. close_button.classList.add("material-icons");
  246. close_button.classList.add("close");
  247. close_button.innerText = "close";
  248. container.appendChild(close_button);
  249. close_button.addEventListener("click", () => {
  250. this.hide();
  251. });
  252. return container;
  253. }
  254. };
  255. // application/scripts/user.js
  256. var user = class {
  257. #nick;
  258. #apikey;
  259. constructor(nick, apikey) {
  260. this.#nick = nick;
  261. this.#apikey = apikey;
  262. }
  263. get nick() {
  264. return this.#nick;
  265. }
  266. get apikey() {
  267. return this.#apikey;
  268. }
  269. };
  270. // application/scripts/login_manager.js
  271. var login_manager = class {
  272. get apikey() {
  273. return localStorage.getItem("apikey");
  274. }
  275. get logged_in() {
  276. return localStorage.getItem("apikey") !== null;
  277. }
  278. #create_request(data) {
  279. return {
  280. method: "POST",
  281. body: JSON.stringify(data),
  282. headers: {
  283. "Content-Type": "application/json"
  284. }
  285. };
  286. }
  287. async get_user() {
  288. if (!this.logged_in) {
  289. return null;
  290. }
  291. const request_data = this.#create_request({
  292. apikey: this.apikey
  293. });
  294. const request2 = await fetch("/user", request_data);
  295. const response = await request2.json();
  296. if (response.result !== "success") {
  297. return null;
  298. }
  299. return new user(
  300. response.nick,
  301. response.apikey
  302. );
  303. }
  304. async login(nick, password) {
  305. const request_data = this.#create_request({
  306. nick,
  307. password
  308. });
  309. const request2 = await fetch("/user/login", request_data);
  310. const response = await request2.json();
  311. if (response.result !== "success") {
  312. return false;
  313. }
  314. localStorage.setItem("apikey", response.apikey);
  315. return true;
  316. }
  317. logout() {
  318. localStorage.removeItem("apikey");
  319. }
  320. };
  321. // application/scripts/confirm_action.js
  322. var confirm_action = class {
  323. #node;
  324. #action;
  325. constructor() {
  326. this.#node = null;
  327. this.#action = true;
  328. }
  329. get _description() {
  330. throw new TypeError("It must be overwriten.");
  331. }
  332. get _title() {
  333. return "You must confirm it.";
  334. }
  335. _action() {
  336. throw new TypeError("It must be overwriten.");
  337. }
  338. get _info() {
  339. return false;
  340. }
  341. show() {
  342. if (this.#node !== null) {
  343. return;
  344. }
  345. this.#action = true;
  346. this.#node = this.#create_window();
  347. document.querySelector("body").appendChild(this.#node);
  348. setTimeout(() => {
  349. this.#node.style.opacity = "1";
  350. }, 100);
  351. }
  352. hide() {
  353. if (this.#node === null) {
  354. return;
  355. }
  356. this.#action = false;
  357. this.#node.style.opacity = "0";
  358. setTimeout(() => {
  359. if (this.#node === null) {
  360. return;
  361. }
  362. this.#node.remove();
  363. this.#node = null;
  364. }, 500);
  365. }
  366. #create_window() {
  367. const container = document.createElement("div");
  368. container.classList.add("confirm-window");
  369. container.style.transition = "opacity 0.5s";
  370. container.style.opacity = "0";
  371. const center = document.createElement("div");
  372. center.classList.add("center");
  373. container.appendChild(center);
  374. const title = document.createElement("div");
  375. title.classList.add("title");
  376. center.appendChild(title);
  377. const title_text = document.createElement("h3");
  378. title_text.innerText = this._title;
  379. title.appendChild(title_text);
  380. const description = document.createElement("div");
  381. description.classList.add("description");
  382. center.appendChild(description);
  383. const description_text = document.createElement("p");
  384. description_text.innerText = this._description;
  385. description.appendChild(description_text);
  386. const buttons = document.createElement("div");
  387. buttons.classList.add("buttons");
  388. center.appendChild(buttons);
  389. const cancel_button = document.createElement("button");
  390. cancel_button.classList.add("cancel");
  391. cancel_button.classList.add("material-icons");
  392. cancel_button.innerText = "clear";
  393. buttons.appendChild(cancel_button);
  394. cancel_button.addEventListener("click", () => {
  395. this.hide();
  396. });
  397. if (!this._info) {
  398. const confirm_button = document.createElement("button");
  399. confirm_button.classList.add("confirm");
  400. confirm_button.classList.add("material-icons");
  401. confirm_button.innerText = "send";
  402. buttons.appendChild(confirm_button);
  403. confirm_button.addEventListener("click", () => {
  404. if (this.#action === false) {
  405. return;
  406. }
  407. this._action();
  408. this.hide();
  409. });
  410. }
  411. return container;
  412. }
  413. };
  414. // application/scripts/request.js
  415. var request = class {
  416. get settings() {
  417. const settings = {
  418. "method": this.method,
  419. "headers": this.headers
  420. };
  421. if (this.method === "GET" || this.method === "HEAD") {
  422. return settings;
  423. }
  424. if (this.body === null) {
  425. return settings;
  426. }
  427. settings.body = this.body;
  428. return settings;
  429. }
  430. get _apikey() {
  431. const manager = new login_manager();
  432. if (manager.logged_in) {
  433. return manager.apikey;
  434. }
  435. throw new Error("User must be logged in.");
  436. }
  437. get method() {
  438. throw new TypeError("It must be overwrite.");
  439. }
  440. get url() {
  441. throw new TypeError("It must be overwrite.");
  442. }
  443. get headers() {
  444. if (this.method === "GET" || this.method === "HEAD") {
  445. return {};
  446. }
  447. if (typeof this.data === "string") {
  448. return {
  449. "Content-Type": "text/plain"
  450. };
  451. }
  452. return {
  453. "Content-Type": "application/json"
  454. };
  455. }
  456. get body() {
  457. if (this.data === null) {
  458. return null;
  459. }
  460. if (typeof this.data === "string") {
  461. return this.data;
  462. }
  463. return JSON.stringify(this.data);
  464. }
  465. get _response() {
  466. throw new TypeError("It must be overwrite.");
  467. }
  468. async connect() {
  469. const request2 = await fetch(this.url, this.settings);
  470. if (!request2.ok) {
  471. throw new Error('Fail when requested: "' + this.url + '".');
  472. }
  473. const response = await request2.json();
  474. if (!("result" in response)) {
  475. throw new Error("Bad response, not contain result.");
  476. }
  477. return new this._response(response);
  478. }
  479. get data() {
  480. throw new TypeError("This must be overwrite.");
  481. }
  482. };
  483. // application/scripts/bool_response.js
  484. var bool_response = class {
  485. #result;
  486. #cause;
  487. constructor(target) {
  488. this.#result = target.result === "success";
  489. this.#cause = null;
  490. if (!this.result) {
  491. this.#cause = target.cause;
  492. }
  493. }
  494. get cause() {
  495. return this.#cause;
  496. }
  497. get result() {
  498. return this.#result;
  499. }
  500. };
  501. // application/scripts/delete_request.js
  502. var delete_request = class extends request {
  503. #product;
  504. constructor(product2) {
  505. super();
  506. this.#product = product2;
  507. }
  508. get _response() {
  509. return bool_response;
  510. }
  511. get data() {
  512. return {
  513. "apikey": this._apikey
  514. };
  515. }
  516. get url() {
  517. return "/product/barcode/" + this.#product.barcode;
  518. }
  519. get method() {
  520. return "DELETE";
  521. }
  522. };
  523. // application/scripts/product_containers.js
  524. var product_containers = class {
  525. #content;
  526. #where;
  527. #inserted;
  528. constructor(where) {
  529. this.#where = where;
  530. this.#content = new Array();
  531. this.#inserted = new Array();
  532. }
  533. add_list(target) {
  534. target.forEach((count) => {
  535. this.add(count);
  536. });
  537. return this;
  538. }
  539. add(target) {
  540. const current = new product_container(target);
  541. this.#content.push(current);
  542. return this;
  543. }
  544. clean() {
  545. this.#content = new Array();
  546. return this;
  547. }
  548. update() {
  549. this.#hide();
  550. setTimeout(() => {
  551. this.#content.forEach((count) => {
  552. this.#inserted.push(count);
  553. count.add(this.#where);
  554. });
  555. }, 500);
  556. return this;
  557. }
  558. #hide() {
  559. this.#inserted.forEach((count) => {
  560. if (!this.#content.includes(count)) {
  561. count.drop();
  562. }
  563. });
  564. this.#inserted = new Array();
  565. return this;
  566. }
  567. };
  568. // application/scripts/searcher.js
  569. var searcher = class _searcher {
  570. #input;
  571. #category;
  572. #manager;
  573. #result;
  574. static #instances;
  575. static #add(instance) {
  576. if (typeof _searcher.#instances !== "object") {
  577. _searcher.#instances = new Array();
  578. }
  579. _searcher.#instances.push(instance);
  580. }
  581. static reload() {
  582. if (typeof _searcher.#instances !== "object") {
  583. return;
  584. }
  585. _searcher.#instances.forEach((instance) => {
  586. instance.update();
  587. });
  588. }
  589. constructor(search_form, manager, result) {
  590. this.#input = search_form.querySelector('input[type="text"]');
  591. this.#category = search_form.querySelector("select");
  592. this.#manager = manager;
  593. this.#result = result;
  594. this.#selector_complete();
  595. search_form.addEventListener("submit", (target) => {
  596. target.preventDefault();
  597. this.update();
  598. });
  599. _searcher.#add(this);
  600. }
  601. get categories() {
  602. return {
  603. "name": "Name",
  604. "author": "Author"
  605. };
  606. }
  607. #selector_complete() {
  608. const category = this.#category;
  609. const categories = this.categories;
  610. Object.keys(categories).forEach((name) => {
  611. const option = document.createElement("option");
  612. option.value = name;
  613. option.innerText = categories[name];
  614. category.appendChild(option);
  615. });
  616. }
  617. get #loader() {
  618. return {
  619. "name": products_loader.search_name,
  620. "author": products_loader.search_author
  621. }[this.category];
  622. }
  623. get category() {
  624. return this.#category.value;
  625. }
  626. get phrase() {
  627. return this.#input.value.trim();
  628. }
  629. get #result_title() {
  630. return this.#result.innerText;
  631. }
  632. set #result_title(target) {
  633. this.#result.innerText = target;
  634. }
  635. async update() {
  636. if (this.phrase.length === 0) {
  637. this.show_all();
  638. return;
  639. }
  640. this.#insert(await this.#loader(this.phrase));
  641. }
  642. #insert(list) {
  643. if (list.length === 0) {
  644. this.#result_title = "Not found anything.";
  645. } else {
  646. this.#result_title = "Browse our products!";
  647. }
  648. this.#manager.clean().add_list(list).update();
  649. }
  650. async show_all() {
  651. this.#insert(await products_loader.all());
  652. }
  653. };
  654. // application/scripts/delete_product_window.js
  655. var delete_product_window = class extends confirm_action {
  656. #target;
  657. constructor(target) {
  658. super();
  659. this.#target = target;
  660. }
  661. get _title() {
  662. return "Do you want remove it?";
  663. }
  664. get _description() {
  665. let content = "You try to remove " + this.#target.name + ". ";
  666. content += "You can not restore it, when confirm.";
  667. return content;
  668. }
  669. async _action() {
  670. new delete_request(this.#target).connect();
  671. searcher.reload();
  672. }
  673. };
  674. // application/scripts/formscreen.js
  675. var formscreen = class extends fullscreen {
  676. #form;
  677. #result;
  678. constructor() {
  679. super();
  680. this.#form = null;
  681. this.#result = null;
  682. }
  683. get _name() {
  684. throw new TypeError("This is virtual getter!");
  685. }
  686. _process() {
  687. this._error = "This is abstract, and must be overwriten.";
  688. }
  689. _build_form() {
  690. throw new TypeError("This is virtual method!");
  691. }
  692. _get_input(name) {
  693. return this.get_query('input[name="' + name + '"]');
  694. }
  695. get _has_submit() {
  696. return true;
  697. }
  698. _build_node() {
  699. const center = document.createElement("div");
  700. center.classList.add("center");
  701. const title = document.createElement("div");
  702. title.classList.add("title");
  703. center.appendChild(title);
  704. const title_content = document.createElement("h3");
  705. title_content.innerText = this._name;
  706. title.appendChild(title_content);
  707. const form = document.createElement("form");
  708. center.appendChild(form);
  709. form.addEventListener("change", () => {
  710. this._clear_results();
  711. });
  712. this.#form = document.createElement("div");
  713. this.#form.classList.add("content");
  714. form.appendChild(this.#form);
  715. this.#result = document.createElement("div");
  716. this.#result.classList.add("result");
  717. form.appendChild(this.#result);
  718. const bottom = document.createElement("div");
  719. bottom.classList.add("bottom");
  720. form.appendChild(bottom);
  721. const close_button = document.createElement("button");
  722. close_button.classList.add("close");
  723. close_button.classList.add("material-icons");
  724. close_button.innerText = "close";
  725. close_button.type = "button";
  726. bottom.appendChild(close_button);
  727. if (this._has_submit) {
  728. const send_button = document.createElement("button");
  729. send_button.classList.add("send");
  730. send_button.classList.add("material-icons");
  731. send_button.innerText = "send";
  732. send_button.type = "submit";
  733. bottom.appendChild(send_button);
  734. }
  735. close_button.addEventListener("click", () => {
  736. this.hide();
  737. });
  738. form.addEventListener("submit", (target) => {
  739. target.preventDefault();
  740. this._process();
  741. });
  742. this._refresh();
  743. return center;
  744. }
  745. _refresh() {
  746. while (this.#form.lastChild) {
  747. this.#form.lastChild.remove();
  748. }
  749. this._build_form();
  750. }
  751. _create_input(name, label_text, placeholder, worker = null) {
  752. const container = document.createElement("div");
  753. container.classList.add("input-container");
  754. container.classList.add("input-" + name);
  755. const label = document.createElement("label");
  756. label.htmlFor = name;
  757. label.innerText = label_text;
  758. container.appendChild(label);
  759. const input = document.createElement("input");
  760. input.type = "text";
  761. input.placeholder = placeholder;
  762. input.name = name;
  763. input.id = name;
  764. container.appendChild(input);
  765. if (worker !== null) {
  766. worker(input);
  767. }
  768. if (!this.#form) {
  769. throw new Error("Screen is not visible yet!");
  770. }
  771. this._append_child(container);
  772. return (target = null) => {
  773. if (target !== null) {
  774. input.value = target;
  775. }
  776. return input.value;
  777. };
  778. }
  779. _append_child(target) {
  780. this.#form.appendChild(target);
  781. }
  782. _clear_results() {
  783. if (!this.#result) {
  784. return;
  785. }
  786. while (this.#result.lastChild) {
  787. this.#result.lastChild.remove();
  788. }
  789. }
  790. set _info(target) {
  791. this._clear_results();
  792. const info = document.createElement("p");
  793. info.classList.add("info");
  794. info.innerText = target;
  795. if (this.#result) {
  796. this.#result.appendChild(info);
  797. }
  798. }
  799. set _error(target) {
  800. this._clear_results();
  801. const info = document.createElement("p");
  802. info.classList.add("error");
  803. info.innerText = target;
  804. if (this.#result) {
  805. this.#result.appendChild(info);
  806. }
  807. }
  808. set _success(target) {
  809. this._clear_results();
  810. const info = document.createElement("p");
  811. info.classList.add("success");
  812. info.innerText = target;
  813. if (this.#result) {
  814. this.#result.appendChild(info);
  815. }
  816. }
  817. };
  818. // application/scripts/product_base.js
  819. var product_base = class {
  820. name;
  821. description;
  822. author;
  823. barcode;
  824. stock_count;
  825. constructor(target = null) {
  826. this.name = this._extract(target, "name");
  827. this.description = this._extract(target, "description");
  828. this.author = this._extract(target, "author");
  829. this.barcode = this._extract(target, "barcode");
  830. this.stock_count = this._extract(target, "stock_count");
  831. if (this.stock_count !== null) {
  832. try {
  833. this.stock_count = Number(this.stock_count);
  834. } catch {
  835. this.stock_count = 0;
  836. }
  837. }
  838. }
  839. get dump() {
  840. return {
  841. "name": new String(this.name),
  842. "description": new String(this.description),
  843. "author": new String(this.author),
  844. "barcode": new String(this.barcode),
  845. "stock_count": new String(this.stock_count)
  846. };
  847. }
  848. _extract(dict, name) {
  849. if (dict === null) {
  850. return null;
  851. }
  852. if (name in dict) {
  853. return dict[name];
  854. }
  855. return null;
  856. }
  857. get avairable() {
  858. return this.stock_count > 0;
  859. }
  860. };
  861. // application/scripts/edit_request.js
  862. var edit_request = class extends request {
  863. #target;
  864. #updated;
  865. constructor(target, updated) {
  866. super();
  867. this.#target = target;
  868. this.#updated = updated;
  869. }
  870. get _response() {
  871. return bool_response;
  872. }
  873. get data() {
  874. return Object.assign(this.#updated.dump, {
  875. "apikey": this._apikey
  876. });
  877. }
  878. get method() {
  879. return "POST";
  880. }
  881. get url() {
  882. return "/product/update/barcode/" + this.#target.barcode;
  883. }
  884. };
  885. // application/scripts/edit_image_request.js
  886. var edit_image_request = class extends request {
  887. #image;
  888. #target;
  889. constructor(target, image) {
  890. super();
  891. this.#target = target;
  892. this.#image = image;
  893. }
  894. get _response() {
  895. return bool_response;
  896. }
  897. get data() {
  898. return {
  899. "image": this.#image,
  900. "apikey": this._apikey
  901. };
  902. }
  903. get method() {
  904. return "POST";
  905. }
  906. get url() {
  907. return "/product/update/image/barcode/" + this.#target.barcode;
  908. }
  909. };
  910. // application/scripts/product_editor.js
  911. var product_editor = class extends formscreen {
  912. #target;
  913. #name;
  914. #description;
  915. #author;
  916. #barcode;
  917. #stock_count;
  918. #image;
  919. #loaded_image_type;
  920. #loaded_image;
  921. #image_preview;
  922. constructor(target) {
  923. super();
  924. this.#target = target;
  925. }
  926. get target() {
  927. return this.#target;
  928. }
  929. get _name() {
  930. return "Product editor";
  931. }
  932. _build_form() {
  933. this.#loaded_image = null;
  934. this.#loaded_image_type = null;
  935. this.#name = this._create_input(
  936. "name",
  937. "Name:",
  938. "Sample...",
  939. (input) => {
  940. input.value = this.#target.name;
  941. }
  942. );
  943. this.#description = this._create_input(
  944. "description",
  945. "Description:",
  946. "This is sample product...",
  947. (input) => {
  948. input.value = this.#target.description;
  949. }
  950. );
  951. this.#author = this._create_input(
  952. "author",
  953. "Author:",
  954. "Jack Black",
  955. (input) => {
  956. input.value = this.#target.author;
  957. }
  958. );
  959. this.#barcode = this._create_input(
  960. "barcode",
  961. "Barcode (EAN):",
  962. "123456789012...",
  963. (input) => {
  964. input.type = "number";
  965. input.value = this.#target.barcode;
  966. }
  967. );
  968. this.#stock_count = this._create_input(
  969. "stock_count",
  970. "Stock count:",
  971. "10...",
  972. (input) => {
  973. input.type = "number";
  974. input.value = this.#target.stock_count;
  975. }
  976. );
  977. this._create_input(
  978. "image",
  979. "Change product image:",
  980. "",
  981. (input) => {
  982. this.#image = input;
  983. input.type = "file";
  984. input.accept = "image/*";
  985. input.addEventListener("change", () => {
  986. this.#load_image_from_file();
  987. });
  988. }
  989. );
  990. this.#image_preview = document.createElement("img");
  991. this.#image_preview.style.opacity = "1";
  992. this.#image_preview.src = this.#target.image;
  993. this._append_child(this.#image_preview);
  994. }
  995. get #ready_image() {
  996. return this.#loaded_image;
  997. }
  998. #update_image_preview() {
  999. this.#image_preview.src = "data:" + this.#loaded_image_type + ";base64," + this.#loaded_image;
  1000. this.#image_preview.style.opacity = "1";
  1001. }
  1002. #reset_image() {
  1003. this.#loaded_image = null;
  1004. this.#loaded_image_type = null;
  1005. this.#image_preview.style.opacity = "0";
  1006. this.#image_preview.src = "";
  1007. }
  1008. async #load_image_from_file() {
  1009. if (this.#image.files.length === 0) {
  1010. this.#reset_image();
  1011. }
  1012. const file = this.#image.files.item(0);
  1013. const buffer = await file.arrayBuffer();
  1014. let as_string = new String();
  1015. new Uint8Array(buffer).forEach((letter) => {
  1016. as_string += String.fromCharCode(letter);
  1017. });
  1018. this.#loaded_image = btoa(as_string);
  1019. this.#loaded_image_type = file.type;
  1020. this.#update_image_preview();
  1021. }
  1022. async #submit() {
  1023. const copy = this.#target.copy();
  1024. copy.name = this.#name();
  1025. copy.description = this.#description();
  1026. copy.author = this.#author();
  1027. copy.barcode = this.#barcode();
  1028. copy.stock_count = this.#stock_count();
  1029. const request2 = new edit_request(this.#target, copy);
  1030. const response = await request2.connect();
  1031. if (!response.result) {
  1032. throw new Error(response.cause);
  1033. }
  1034. this.#target = copy;
  1035. }
  1036. async #image_submit() {
  1037. const image = await this.#ready_image;
  1038. if (image === null) {
  1039. return;
  1040. }
  1041. const request2 = new edit_image_request(this.#target, image);
  1042. const response = await request2.connect();
  1043. if (!response.result) {
  1044. throw new Error(response.cause);
  1045. }
  1046. }
  1047. async _process() {
  1048. try {
  1049. this._info = "Uploading...";
  1050. await this.#submit();
  1051. this._info = "Processing image...";
  1052. await this.#image_submit();
  1053. this._success = "Updated success!";
  1054. searcher.reload();
  1055. setTimeout(() => {
  1056. this.hide();
  1057. }, 500);
  1058. } catch (error) {
  1059. this._error = new String(error);
  1060. }
  1061. }
  1062. };
  1063. // application/scripts/rents_screen.js
  1064. var rents_screen = class extends formscreen {
  1065. #target;
  1066. #email;
  1067. #phone;
  1068. get _email() {
  1069. return this.#email();
  1070. }
  1071. get _phone() {
  1072. return this.#phone();
  1073. }
  1074. constructor(target) {
  1075. super();
  1076. this.#target = target;
  1077. }
  1078. get _target() {
  1079. return this.#target;
  1080. }
  1081. _build_form() {
  1082. this.#email = this._create_input(
  1083. "email",
  1084. "E-mail:",
  1085. "[email protected]",
  1086. (input) => {
  1087. input.type = "email";
  1088. }
  1089. );
  1090. this.#phone = this._create_input(
  1091. "phone",
  1092. "Phone number:",
  1093. "+1 123-456-789",
  1094. (input) => {
  1095. input.type = "tel";
  1096. const add_prefix = () => {
  1097. if (input.value.length === 0) {
  1098. input.value = "+48 ";
  1099. }
  1100. };
  1101. input.addEventListener("click", add_prefix);
  1102. input.addEventListener("focus", add_prefix);
  1103. }
  1104. );
  1105. }
  1106. };
  1107. // application/scripts/reservation.js
  1108. var reservation = class _reservation {
  1109. email;
  1110. phone_number;
  1111. product_barcode;
  1112. constructor(target = null) {
  1113. this.email = null;
  1114. this.phone_number = null;
  1115. this.product_barcode = null;
  1116. if (target === null) {
  1117. return;
  1118. }
  1119. if ("email" in target) {
  1120. this.email = target["email"];
  1121. }
  1122. if ("target_barcode" in target) {
  1123. this.product_barcode = target["target_barcode"];
  1124. }
  1125. if ("phone_number" in target) {
  1126. this.phone_number = target["phone_number"];
  1127. }
  1128. }
  1129. get dump() {
  1130. const dumped = {
  1131. "target_barcode": this.product_barcode
  1132. };
  1133. if (this.email !== null) {
  1134. dumped["email"] = this.email;
  1135. }
  1136. if (this.phone_number !== null) {
  1137. dumped["phone_number"] = this.phone_number;
  1138. }
  1139. return dumped;
  1140. }
  1141. get ready() {
  1142. if (this.product_barcode === null) return false;
  1143. if (this.email === null && this.phone_number === null) return false;
  1144. return true;
  1145. }
  1146. copy() {
  1147. return new _reservation(this.dump);
  1148. }
  1149. };
  1150. // application/scripts/product_rent_request.js
  1151. var product_rent_request = class extends request {
  1152. #reservation;
  1153. constructor(reservation2) {
  1154. super();
  1155. this.#reservation = reservation2;
  1156. }
  1157. get data() {
  1158. return Object.assign(this.#reservation.dump, {
  1159. "apikey": this._apikey
  1160. });
  1161. }
  1162. get _response() {
  1163. return bool_response;
  1164. }
  1165. get method() {
  1166. return "POST";
  1167. }
  1168. get url() {
  1169. return "/rent/product/barcode/" + this.#reservation.product_barcode;
  1170. }
  1171. };
  1172. // application/scripts/reservation_factory.js
  1173. var reservation_factory = class {
  1174. #target;
  1175. constructor() {
  1176. this.#target = new reservation();
  1177. }
  1178. phone_number(target) {
  1179. target = target.trim().replaceAll("-", "");
  1180. if (target.length === 0) {
  1181. target = null;
  1182. }
  1183. this.#target.phone_number = target;
  1184. return this;
  1185. }
  1186. email(target) {
  1187. target = target.trim();
  1188. if (target.length === 0) {
  1189. target = null;
  1190. }
  1191. this.#target.email = target;
  1192. return this;
  1193. }
  1194. product(target) {
  1195. this.#target.product_barcode = target.barcode;
  1196. return this;
  1197. }
  1198. result() {
  1199. if (this.#target.ready) {
  1200. return this.#target;
  1201. }
  1202. throw new Error("Target reservation is not ready yet.");
  1203. }
  1204. };
  1205. // application/scripts/product_rent.js
  1206. var product_rent = class extends rents_screen {
  1207. get _name() {
  1208. return "Product rent";
  1209. }
  1210. async _process() {
  1211. try {
  1212. this._info = "Processing...";
  1213. const target = new reservation_factory().email(this._email).phone_number(this._phone).product(this._target).result();
  1214. const request2 = new product_rent_request(target);
  1215. const response = await request2.connect();
  1216. if (!response.result) {
  1217. throw new Error(response.cause);
  1218. }
  1219. this._success = "New rent added.";
  1220. searcher.reload();
  1221. setTimeout(() => {
  1222. this.hide();
  1223. }, 500);
  1224. } catch (error) {
  1225. this._error = String(error);
  1226. }
  1227. }
  1228. };
  1229. // application/scripts/product_give_back_request.js
  1230. var product_give_back_request = class extends request {
  1231. #reservation;
  1232. constructor(reservation2) {
  1233. super();
  1234. this.#reservation = reservation2;
  1235. }
  1236. get data() {
  1237. return Object.assign(this.#reservation.dump, {
  1238. "apikey": this._apikey
  1239. });
  1240. }
  1241. get _response() {
  1242. return bool_response;
  1243. }
  1244. get method() {
  1245. return "POST";
  1246. }
  1247. get url() {
  1248. return "/give_back/product/barcode/" + this.#reservation.product_barcode;
  1249. }
  1250. };
  1251. // application/scripts/product_give_back.js
  1252. var product_give_back = class extends rents_screen {
  1253. get _name() {
  1254. return "Product give back";
  1255. }
  1256. async _process() {
  1257. try {
  1258. this._info = "Processing...";
  1259. const target = new reservation_factory().email(this._email).phone_number(this._phone).product(this._target).result();
  1260. const request2 = new product_give_back_request(target);
  1261. const response = await request2.connect();
  1262. if (!response.result) {
  1263. throw new Error(response.cause);
  1264. }
  1265. this._success = "Success!";
  1266. searcher.reload();
  1267. setTimeout(() => {
  1268. this.hide();
  1269. }, 500);
  1270. } catch (error) {
  1271. this._error = String(error);
  1272. }
  1273. }
  1274. };
  1275. // application/scripts/reservations_response.js
  1276. var reservations_response = class extends bool_response {
  1277. #collection;
  1278. constructor(target) {
  1279. super(target);
  1280. if (!this.result) {
  1281. return;
  1282. }
  1283. this.#collection = new Array();
  1284. target["reservations"].forEach((count) => {
  1285. this.#collection.push(new reservation(count));
  1286. });
  1287. }
  1288. get collection() {
  1289. if (!this.result) {
  1290. throw new Error(this.cause);
  1291. }
  1292. return this.#collection;
  1293. }
  1294. };
  1295. // application/scripts/product_reservations_request.js
  1296. var product_reservations_request = class extends request {
  1297. #target;
  1298. constructor(target) {
  1299. super();
  1300. this.#target = target;
  1301. }
  1302. get _response() {
  1303. return reservations_response;
  1304. }
  1305. get data() {
  1306. return {
  1307. "apikey": this._apikey
  1308. };
  1309. }
  1310. get method() {
  1311. return "POST";
  1312. }
  1313. get url() {
  1314. return "/reservations/product/barcode/" + this.#target.barcode;
  1315. }
  1316. };
  1317. // application/scripts/product_all_rents.js
  1318. var product_all_rents = class extends formscreen {
  1319. #target;
  1320. constructor(target) {
  1321. super();
  1322. this.#target = target;
  1323. }
  1324. get _name() {
  1325. return "All rents";
  1326. }
  1327. get _has_submit() {
  1328. return false;
  1329. }
  1330. #create_single(target) {
  1331. const container = document.createElement("div");
  1332. container.classList.add("reservation-info");
  1333. if (target.phone_number !== null) {
  1334. const phone_icon = document.createElement("span");
  1335. phone_icon.classList.add("material-icons");
  1336. phone_icon.innerText = "phone";
  1337. const phone_number = document.createElement("span");
  1338. phone_number.classList.add("numbers");
  1339. phone_number.innerText = target.phone_number;
  1340. const phone_number_container = document.createElement("p");
  1341. phone_number_container.appendChild(phone_icon);
  1342. phone_number_container.appendChild(phone_number);
  1343. container.appendChild(phone_number_container);
  1344. }
  1345. if (target.email !== null) {
  1346. const email_icon = document.createElement("span");
  1347. email_icon.classList.add("material-icons");
  1348. email_icon.innerText = "mail";
  1349. const email = document.createElement("span");
  1350. email.innerText = target.email;
  1351. const email_container = document.createElement("p");
  1352. email_container.appendChild(email_icon);
  1353. email_container.appendChild(email);
  1354. container.appendChild(email_container);
  1355. }
  1356. return container;
  1357. }
  1358. #create_single_button(target) {
  1359. const button = document.createElement("button");
  1360. button.classList.add("material-icons");
  1361. button.classList.add("give-back-button");
  1362. button.innerText = "save_alt";
  1363. button.addEventListener("click", async () => {
  1364. try {
  1365. this._info = "Processing...";
  1366. const request2 = new product_give_back_request(target);
  1367. const response = await request2.connect();
  1368. if (!response.result) {
  1369. throw new Error(response.cause);
  1370. }
  1371. this._refresh();
  1372. searcher.reload();
  1373. } catch (error) {
  1374. this._error = String(error);
  1375. }
  1376. });
  1377. return button;
  1378. }
  1379. _process() {
  1380. return;
  1381. }
  1382. async _build_form() {
  1383. try {
  1384. this._info = "Loading...";
  1385. const request2 = new product_reservations_request(this.#target);
  1386. const response = await request2.connect();
  1387. const list = document.createElement("div");
  1388. list.classList.add("reservations-list");
  1389. let empty = true;
  1390. response.collection.forEach((count) => {
  1391. const item = document.createElement("div");
  1392. item.classList.add("reservation");
  1393. const left = this.#create_single(count);
  1394. const right = this.#create_single_button(count);
  1395. empty = false;
  1396. item.appendChild(left);
  1397. item.appendChild(right);
  1398. list.appendChild(item);
  1399. });
  1400. this._append_child(list);
  1401. if (empty) {
  1402. this._success = "Not found any reservations.";
  1403. } else {
  1404. this._clear_results();
  1405. }
  1406. } catch (error) {
  1407. this._error = String(error);
  1408. }
  1409. }
  1410. };
  1411. // application/scripts/product_not_avairable.js
  1412. var product_not_avairable = class extends confirm_action {
  1413. get _title() {
  1414. return "Error";
  1415. }
  1416. get _description() {
  1417. return "This product is not avairable. Anybody can not rent it.";
  1418. }
  1419. get _info() {
  1420. return true;
  1421. }
  1422. };
  1423. // application/scripts/product_container.js
  1424. var product_container = class {
  1425. #target;
  1426. #node;
  1427. #login;
  1428. constructor(target) {
  1429. this.#target = new product(target.dump);
  1430. this.#node = null;
  1431. this.#login = new login_manager().logged_in;
  1432. }
  1433. get #header() {
  1434. const header = document.createElement("div");
  1435. header.classList.add("header");
  1436. const title = document.createElement("h3");
  1437. title.innerText = this.#target.name;
  1438. header.appendChild(title);
  1439. if (this.#login) {
  1440. header.appendChild(this.#manage);
  1441. }
  1442. return header;
  1443. }
  1444. get #manage() {
  1445. const manage = document.createElement("div");
  1446. manage.classList.add("manage");
  1447. const all_rents_button = document.createElement("button");
  1448. all_rents_button.classList.add("material-icons");
  1449. all_rents_button.classList.add("all-rents-button");
  1450. all_rents_button.innerText = "list";
  1451. manage.appendChild(all_rents_button);
  1452. const rent_button = document.createElement("button");
  1453. rent_button.classList.add("material-icons");
  1454. rent_button.classList.add("rent-button");
  1455. rent_button.innerText = "backpack";
  1456. manage.appendChild(rent_button);
  1457. const give_back_button = document.createElement("button");
  1458. give_back_button.classList.add("material-icons");
  1459. give_back_button.classList.add("give-back-button");
  1460. give_back_button.innerText = "save_alt";
  1461. manage.appendChild(give_back_button);
  1462. const edit_button = document.createElement("button");
  1463. edit_button.classList.add("material-icons");
  1464. edit_button.classList.add("edit-button");
  1465. edit_button.innerText = "edit";
  1466. manage.appendChild(edit_button);
  1467. const delete_button = document.createElement("button");
  1468. delete_button.classList.add("material-icons");
  1469. delete_button.classList.add("delete-button");
  1470. delete_button.innerText = "remove_circle_outline";
  1471. manage.appendChild(delete_button);
  1472. all_rents_button.addEventListener("click", () => {
  1473. new product_all_rents(this.#target).show();
  1474. });
  1475. rent_button.addEventListener("click", () => {
  1476. if (this.#target.on_stock > 0) {
  1477. new product_rent(this.#target).show();
  1478. } else {
  1479. new product_not_avairable().show();
  1480. }
  1481. });
  1482. give_back_button.addEventListener("click", () => {
  1483. new product_give_back(this.#target).show();
  1484. });
  1485. edit_button.addEventListener("click", () => {
  1486. new product_editor(this.#target).show();
  1487. });
  1488. delete_button.addEventListener("click", () => {
  1489. new delete_product_window(this.#target).show();
  1490. });
  1491. return manage;
  1492. }
  1493. get #description() {
  1494. const container = document.createElement("div");
  1495. container.classList.add("description");
  1496. const description = document.createElement("p");
  1497. description.innerText = this.#target.description;
  1498. description.classList.add("content");
  1499. const author_container = document.createElement("div");
  1500. author_container.classList.add("author");
  1501. const author = document.createElement("span");
  1502. author.innerText = this.#target.author;
  1503. const author_icon = document.createElement("span");
  1504. author_icon.classList.add("material-icons");
  1505. author_icon.innerText = "attribution";
  1506. author_container.appendChild(author_icon);
  1507. author_container.appendChild(author);
  1508. const stock_count = document.createElement("p");
  1509. stock_count.classList.add("stock-count");
  1510. stock_count.classList.add("material-icons");
  1511. if (this.#target.on_stock > 0) {
  1512. stock_count.innerText = "check_circle";
  1513. stock_count.classList.add("avairable");
  1514. } else {
  1515. stock_count.innerText = "cancel";
  1516. stock_count.classList.add("unavairable");
  1517. }
  1518. const barcode_container = document.createElement("p");
  1519. barcode_container.classList.add("barcode");
  1520. const barcode = document.createElement("span");
  1521. barcode.innerText = this.#target.barcode;
  1522. barcode.classList.add("numbers");
  1523. const barcode_icon = document.createElement("span");
  1524. barcode_icon.classList.add("material-icons");
  1525. barcode_icon.innerText = "qr_code_scanner";
  1526. barcode_container.appendChild(barcode_icon);
  1527. barcode_container.appendChild(barcode);
  1528. container.appendChild(description);
  1529. container.appendChild(author_container);
  1530. container.appendChild(barcode_container);
  1531. container.appendChild(stock_count);
  1532. return container;
  1533. }
  1534. get #cache_bypass() {
  1535. return "?cache=" + new String(Math.floor(Math.random() * 100));
  1536. }
  1537. get #image() {
  1538. const image = document.createElement("img");
  1539. image.classList.add("image");
  1540. image.src = this.#target.thumbnail + this.#cache_bypass;
  1541. image.alt = this.#target.name;
  1542. image.loading = "lazy";
  1543. image.addEventListener("click", () => {
  1544. new product_fullscreen(this.#target).show();
  1545. });
  1546. return image;
  1547. }
  1548. get node() {
  1549. if (this.#node !== null) {
  1550. return this.#node;
  1551. }
  1552. const bottom_container = document.createElement("div");
  1553. bottom_container.classList.add("bottom-container");
  1554. bottom_container.appendChild(this.#description);
  1555. bottom_container.appendChild(this.#image);
  1556. const container = document.createElement("div");
  1557. container.classList.add("product");
  1558. container.appendChild(this.#header);
  1559. container.appendChild(bottom_container);
  1560. return this.#node = container;
  1561. }
  1562. add(target) {
  1563. const node = this.node;
  1564. node.style.opacity = "0";
  1565. node.style.transition = "opacity 0.5s";
  1566. target.appendChild(node);
  1567. setTimeout(() => {
  1568. node.style.opacity = "1";
  1569. }, 50);
  1570. }
  1571. drop() {
  1572. const container = this.#node;
  1573. if (container === null) {
  1574. throw new TypeError("It is not showed yet.");
  1575. }
  1576. container.style.opacity = "1";
  1577. container.style.transition = "opacity 0.5s";
  1578. setTimeout(() => {
  1579. container.style.opacity = "0";
  1580. }, 50);
  1581. setTimeout(() => {
  1582. this.#node = null;
  1583. container.remove();
  1584. }, 550);
  1585. }
  1586. };
  1587. // application/scripts/login_prompt.js
  1588. var login_prompt = class extends formscreen {
  1589. #nick;
  1590. #password;
  1591. constructor(target) {
  1592. super();
  1593. target.addEventListener("click", () => {
  1594. this.show();
  1595. });
  1596. }
  1597. get _name() {
  1598. return "Login";
  1599. }
  1600. async _process() {
  1601. try {
  1602. this._info = "Processing...";
  1603. await this.#login();
  1604. this._success = "Logged in!";
  1605. setTimeout(() => {
  1606. location.reload();
  1607. }, 250);
  1608. } catch (error) {
  1609. this._error = new String(error);
  1610. }
  1611. }
  1612. async #login() {
  1613. const manager = new login_manager();
  1614. const result = await manager.login(
  1615. this.#nick(),
  1616. this.#password()
  1617. );
  1618. if (result) {
  1619. return;
  1620. }
  1621. throw new Error("Can not login. Check nick and password.");
  1622. }
  1623. _build_form() {
  1624. this.#nick = this._create_input(
  1625. "nick",
  1626. "Nick:",
  1627. "Sample..."
  1628. );
  1629. this.#password = this._create_input(
  1630. "password",
  1631. "Password:",
  1632. "ABCDEFGH",
  1633. (input) => {
  1634. input.type = "password";
  1635. }
  1636. );
  1637. }
  1638. };
  1639. // application/scripts/create_request.js
  1640. var create_request = class extends request {
  1641. #image;
  1642. #product;
  1643. constructor(product2, image) {
  1644. super();
  1645. this.#image = image;
  1646. this.#product = product2;
  1647. }
  1648. get _response() {
  1649. return bool_response;
  1650. }
  1651. get data() {
  1652. return Object.assign(this.#product.dump, {
  1653. "image": this.#image,
  1654. "apikey": this._apikey
  1655. });
  1656. }
  1657. get method() {
  1658. return "POST";
  1659. }
  1660. get url() {
  1661. return "/product/create";
  1662. }
  1663. };
  1664. // application/scripts/autocomplete_response.js
  1665. var autocomplete_response = class extends bool_response {
  1666. #found;
  1667. constructor(target) {
  1668. super(target);
  1669. this.#found = null;
  1670. if (this.result) {
  1671. this.#found = target["found"];
  1672. }
  1673. }
  1674. get found() {
  1675. if (this.#found === null) {
  1676. throw new Error("Server response is not complete.");
  1677. }
  1678. return this.#found;
  1679. }
  1680. };
  1681. // application/scripts/autocomplete_request.js
  1682. var autocomplete_request = class extends request {
  1683. #barcode;
  1684. constructor(barcode) {
  1685. super();
  1686. this.#barcode = barcode;
  1687. }
  1688. get _response() {
  1689. return autocomplete_response;
  1690. }
  1691. get data() {
  1692. return {
  1693. "apikey": this._apikey
  1694. };
  1695. }
  1696. get method() {
  1697. return "POST";
  1698. }
  1699. get url() {
  1700. return "/complete/barcode/" + this.#barcode;
  1701. }
  1702. };
  1703. // application/scripts/product_adder.js
  1704. var product_adder = class extends formscreen {
  1705. #name;
  1706. #description;
  1707. #author;
  1708. #barcode;
  1709. #stock_count;
  1710. #image;
  1711. #loaded_image_type;
  1712. #loaded_image;
  1713. #image_preview;
  1714. get _name() {
  1715. return "Add product";
  1716. }
  1717. async #autocomplete() {
  1718. const barcode = this.#barcode();
  1719. if (barcode.length === 0) {
  1720. this._info = "Fill barcode first.";
  1721. return;
  1722. }
  1723. this._info = "Searching in the web...";
  1724. try {
  1725. const request2 = new autocomplete_request(barcode);
  1726. const response = await request2.connect();
  1727. if (!response.result) {
  1728. throw new Error(response.cause);
  1729. }
  1730. const product2 = response.found;
  1731. this.#name(product2.title);
  1732. this.#description(product2.description);
  1733. this.#author(product2.author);
  1734. this.#barcode(product2.barcode);
  1735. this.#loaded_image = product2.image;
  1736. this.#loaded_image_type = product2.image_type;
  1737. this.#update_image_preview();
  1738. this._info = "Ready. Check results.";
  1739. } catch (error) {
  1740. this._error = new String(error);
  1741. }
  1742. }
  1743. #update_image_preview() {
  1744. this.#image_preview.src = "data:" + this.#loaded_image_type + ";base64," + this.#loaded_image;
  1745. this.#image_preview.style.opacity = "1";
  1746. }
  1747. get #autocomplete_button() {
  1748. const button = document.createElement("div");
  1749. button.classList.add("autocomplete-button");
  1750. button.classList.add("button");
  1751. const icon = document.createElement("span");
  1752. icon.classList.add("material-icons");
  1753. icon.innerText = "auto_fix_normal";
  1754. button.appendChild(icon);
  1755. const text = document.createElement("span");
  1756. text.classList.add("text");
  1757. text.innerText = "Autocomplete";
  1758. button.appendChild(text);
  1759. return button;
  1760. }
  1761. _build_form() {
  1762. this.#loaded_image = null;
  1763. this.#loaded_image_type = null;
  1764. this.#name = this._create_input(
  1765. "name",
  1766. "Name:",
  1767. "Sample..."
  1768. );
  1769. this.#description = this._create_input(
  1770. "description",
  1771. "Description:",
  1772. "This is sample product..."
  1773. );
  1774. this.#author = this._create_input(
  1775. "author",
  1776. "Author:",
  1777. "Jack Black"
  1778. );
  1779. this.#barcode = this._create_input(
  1780. "barcode",
  1781. "Barcode (EAN):",
  1782. "123456789012...",
  1783. (input) => {
  1784. input.type = "number";
  1785. }
  1786. );
  1787. this.#stock_count = this._create_input(
  1788. "stock_count",
  1789. "Stock count:",
  1790. "10...",
  1791. (input) => {
  1792. input.type = "number";
  1793. }
  1794. );
  1795. this._create_input(
  1796. "image",
  1797. "Product image:",
  1798. "",
  1799. (input) => {
  1800. this.#image = input;
  1801. input.type = "file";
  1802. input.accept = "image/*";
  1803. input.addEventListener("change", () => {
  1804. this.#load_image_from_file();
  1805. });
  1806. }
  1807. );
  1808. this.#image_preview = document.createElement("img");
  1809. this.#image_preview.style.opacity = "0";
  1810. this._append_child(this.#image_preview);
  1811. const autocomplete = this.#autocomplete_button;
  1812. this._append_child(autocomplete);
  1813. autocomplete.addEventListener("click", () => {
  1814. this.#autocomplete();
  1815. });
  1816. }
  1817. #reset_image() {
  1818. this.#loaded_image = null;
  1819. this.#loaded_image_type = null;
  1820. this.#image_preview.style.opacity = "0";
  1821. this.#image_preview.src = "";
  1822. }
  1823. async #load_image_from_file() {
  1824. if (this.#image.files.length === 0) {
  1825. this.#reset_image();
  1826. }
  1827. const file = this.#image.files.item(0);
  1828. const buffer = await file.arrayBuffer();
  1829. let as_string = new String();
  1830. new Uint8Array(buffer).forEach((letter) => {
  1831. as_string += String.fromCharCode(letter);
  1832. });
  1833. this.#loaded_image = btoa(as_string);
  1834. this.#loaded_image_type = file.type;
  1835. this.#update_image_preview();
  1836. }
  1837. get #ready_image() {
  1838. if (this.#loaded_image === null) {
  1839. throw new Error("Loady any image first.");
  1840. }
  1841. return this.#loaded_image;
  1842. }
  1843. async #submit() {
  1844. const product2 = new product_base();
  1845. product2.name = this.#name();
  1846. product2.description = this.#description();
  1847. product2.author = this.#author();
  1848. product2.stock_count = this.#stock_count();
  1849. product2.barcode = this.#barcode();
  1850. const request2 = new create_request(product2, this.#ready_image);
  1851. const response = await request2.connect();
  1852. if (!response.result) {
  1853. throw new Error(response.cause);
  1854. }
  1855. }
  1856. async _process() {
  1857. try {
  1858. this._info = "Uploading...";
  1859. await this.#submit();
  1860. this._success = "Created success!";
  1861. searcher.reload();
  1862. setTimeout(() => {
  1863. this.hide();
  1864. }, 500);
  1865. } catch (error) {
  1866. this._error = new String(error);
  1867. }
  1868. }
  1869. };
  1870. // application/scripts/import_process_fail.js
  1871. var import_process_fail = class {
  1872. #product;
  1873. #error;
  1874. constructor(product2, error) {
  1875. this.#product = product2;
  1876. this.#error = error;
  1877. }
  1878. get error() {
  1879. return this.#error;
  1880. }
  1881. get product() {
  1882. return this.#product;
  1883. }
  1884. };
  1885. // application/scripts/database.js
  1886. var database = class {
  1887. #content;
  1888. #processed;
  1889. #on_skip;
  1890. constructor(content) {
  1891. this.#content = content;
  1892. this.#processed = /* @__PURE__ */ new Map();
  1893. this.#on_skip = null;
  1894. }
  1895. #append(target) {
  1896. if (this.#processed.has(target.barcode)) {
  1897. this.#processed.get(target.barcode).stock_count += 1;
  1898. return;
  1899. }
  1900. this.#processed.set(target.barcode, target);
  1901. }
  1902. #validate(target) {
  1903. if (!("id" in target)) {
  1904. throw new Error("One of item has no ID.");
  1905. }
  1906. if (!("title" in target)) {
  1907. throw new Error("Product " + target.barcode + " has no title.");
  1908. }
  1909. if (!("author" in target)) {
  1910. throw new Error("Product " + target.barcode + " has no author.");
  1911. }
  1912. }
  1913. #convert(target) {
  1914. this.#validate(target);
  1915. const product2 = new product_base();
  1916. product2.name = target.title;
  1917. product2.description = "";
  1918. product2.author = target.author;
  1919. product2.stock_count = 1;
  1920. product2.barcode = target.id;
  1921. return product2;
  1922. }
  1923. on_skip(target) {
  1924. this.#on_skip = target;
  1925. return this;
  1926. }
  1927. process() {
  1928. this.#processed.clear();
  1929. if (!(this.#content instanceof Array)) {
  1930. throw new Error("Database woud be array of objects.");
  1931. }
  1932. this.#content.forEach((count) => {
  1933. try {
  1934. const product2 = this.#convert(count);
  1935. this.#append(product2);
  1936. } catch (error) {
  1937. if (this.#on_skip === null) {
  1938. return;
  1939. }
  1940. try {
  1941. this.#on_skip(new import_process_fail(count, error));
  1942. } catch (fail) {
  1943. console.log(fail);
  1944. }
  1945. }
  1946. });
  1947. return this;
  1948. }
  1949. results() {
  1950. return Array.from(this.#processed.values());
  1951. }
  1952. };
  1953. // application/scripts/product_response.js
  1954. var product_response = class extends bool_response {
  1955. #product;
  1956. constructor(target) {
  1957. super(target);
  1958. this.#product = null;
  1959. if (this.result) {
  1960. if (!("product" in target)) {
  1961. throw new Error("Incomplete response with good status.");
  1962. }
  1963. this.#product = new product(target.product);
  1964. }
  1965. }
  1966. get product() {
  1967. return this.#product;
  1968. }
  1969. };
  1970. // application/scripts/product_get_request.js
  1971. var product_get_request = class extends request {
  1972. #barcode;
  1973. constructor(barcode) {
  1974. super();
  1975. this.#barcode = barcode;
  1976. }
  1977. get _response() {
  1978. return product_response;
  1979. }
  1980. get data() {
  1981. return null;
  1982. }
  1983. get method() {
  1984. return "GET";
  1985. }
  1986. get url() {
  1987. return "/product/get/barcode/" + new String(this.#barcode);
  1988. }
  1989. };
  1990. // application/scripts/import_loop.js
  1991. var import_loop = class {
  1992. #content;
  1993. #on_autocomplete;
  1994. #on_create;
  1995. #on_single_fail;
  1996. #on_skip;
  1997. #on_single_success;
  1998. #finally;
  1999. on_autocomplete(target) {
  2000. this.#on_autocomplete = target;
  2001. return this;
  2002. }
  2003. on_create(target) {
  2004. this.#on_create = target;
  2005. return this;
  2006. }
  2007. on_single_fail(target) {
  2008. this.#on_single_fail = target;
  2009. return this;
  2010. }
  2011. on_skip(target) {
  2012. this.#on_skip = target;
  2013. return this;
  2014. }
  2015. on_single_success(target) {
  2016. this.#on_single_success = target;
  2017. return this;
  2018. }
  2019. finally(target) {
  2020. this.#finally = target;
  2021. return this;
  2022. }
  2023. constructor(dataset) {
  2024. this.#content = dataset;
  2025. this.#on_autocomplete = null;
  2026. this.#on_create = null;
  2027. this.#on_single_fail = null;
  2028. this.#on_skip = null;
  2029. this.#on_single_success = null;
  2030. this.#finally = null;
  2031. }
  2032. async #autocomplete(target) {
  2033. if (this.#on_autocomplete !== null) {
  2034. try {
  2035. this.#on_autocomplete(target);
  2036. } catch (error) {
  2037. console.log(error);
  2038. }
  2039. }
  2040. const request2 = new autocomplete_request(target.barcode);
  2041. const response = await request2.connect();
  2042. if (!response.result) {
  2043. throw new Error(response.cause);
  2044. }
  2045. const found = response.found;
  2046. target.description = found.description;
  2047. if (found.image.length === 0) {
  2048. throw new Error("Image for " + target.barcode + " not found.");
  2049. }
  2050. return new create_request(target, found.image);
  2051. }
  2052. async process() {
  2053. for (const count of this.#content) {
  2054. try {
  2055. await this.#create(count);
  2056. } catch (error) {
  2057. if (this.#on_single_fail !== null) {
  2058. try {
  2059. const fail = new import_process_fail(count, error);
  2060. this.#on_single_fail(fail);
  2061. } catch (error2) {
  2062. console.log(error2);
  2063. }
  2064. }
  2065. }
  2066. }
  2067. if (this.#finally !== null) {
  2068. try {
  2069. this.#finally();
  2070. } catch (error) {
  2071. console.log(error);
  2072. }
  2073. }
  2074. return this;
  2075. }
  2076. async #exists(target) {
  2077. const request2 = new product_get_request(target.barcode);
  2078. const response = await request2.connect();
  2079. return response.product !== null;
  2080. }
  2081. async #create(target) {
  2082. if (await this.#exists(target)) {
  2083. try {
  2084. const result = new import_process_fail(target, null);
  2085. this.#on_skip(result);
  2086. } catch (error) {
  2087. console.log(error);
  2088. }
  2089. return;
  2090. }
  2091. const request2 = await this.#autocomplete(target);
  2092. if (this.on_create !== null) {
  2093. try {
  2094. this.#on_create(target);
  2095. } catch (error) {
  2096. console.log(error);
  2097. }
  2098. }
  2099. const response = await request2.connect();
  2100. if (!response.result) {
  2101. throw new Error(response.cause);
  2102. }
  2103. if (this.#on_single_success !== null) {
  2104. try {
  2105. this.#on_single_success(target);
  2106. } catch (error) {
  2107. console.log(error);
  2108. }
  2109. }
  2110. }
  2111. };
  2112. // application/scripts/import_log.js
  2113. var import_log = class {
  2114. #log;
  2115. constructor() {
  2116. this.#log = new Array();
  2117. }
  2118. #append(target) {
  2119. this.#log.push(target);
  2120. }
  2121. #error_dump(error) {
  2122. return "Error: " + new String(error) + ".";
  2123. }
  2124. #product_dump(product2) {
  2125. return 'Product: barcode: "' + product2.barcode + '", title: "' + product2.title + '".';
  2126. }
  2127. fail(target) {
  2128. this.#append(
  2129. "Fail when processing item. " + this.#product_dump(target.product) + " " + this.#error_dump(target.error)
  2130. );
  2131. }
  2132. skip(target) {
  2133. this.#append(
  2134. "Skipping not ready item. " + this.#product_dump(target.product) + " " + this.#error_dump(target.error)
  2135. );
  2136. }
  2137. get length() {
  2138. return this.#log.length;
  2139. }
  2140. content() {
  2141. return this.#log.join("\n");
  2142. }
  2143. };
  2144. // application/scripts/downloader.js
  2145. var downloader = class {
  2146. #name;
  2147. #content;
  2148. #type;
  2149. #encode;
  2150. constructor() {
  2151. this.#name = "download.json";
  2152. this.#content = "";
  2153. this.#type = "text/plain";
  2154. this.#encode = "utf-8";
  2155. }
  2156. name(target) {
  2157. this.#name = target;
  2158. return this;
  2159. }
  2160. content(target) {
  2161. this.#content = target;
  2162. return this;
  2163. }
  2164. type(target) {
  2165. this.#type = target;
  2166. return this;
  2167. }
  2168. encode(target) {
  2169. this.#encode = target;
  2170. return this;
  2171. }
  2172. get #href() {
  2173. return "data:" + this.#type + ";charset=" + this.#encode + "," + encodeURIComponent(this.#content);
  2174. }
  2175. get #link() {
  2176. const link = document.createElement("a");
  2177. link.style.display = "none";
  2178. link.href = this.#href;
  2179. link.download = this.#name;
  2180. return link;
  2181. }
  2182. process() {
  2183. const link = this.#link;
  2184. const body = document.querySelector("body");
  2185. body.appendChild(link);
  2186. link.click();
  2187. body.removeChild(link);
  2188. return this;
  2189. }
  2190. };
  2191. // application/scripts/import_products.js
  2192. var import_products = class extends formscreen {
  2193. #file;
  2194. #content;
  2195. get _name() {
  2196. return "Import products JSON";
  2197. }
  2198. _build_form() {
  2199. this._create_input("file", "Database:", "", (input) => {
  2200. this.#file = input;
  2201. input.type = "file";
  2202. input.accept = "application/json";
  2203. });
  2204. }
  2205. async #load_file() {
  2206. if (this.#file.files.length === 0) {
  2207. throw new Error("Select JSON products database first.");
  2208. }
  2209. const file = this.#file.files.item(0);
  2210. const text = await file.text();
  2211. return JSON.parse(text);
  2212. }
  2213. async _process() {
  2214. try {
  2215. this._info = "Loading file...";
  2216. this.#content = await this.#load_file();
  2217. this._info = "Parsing file to dataset...";
  2218. const result = new import_log();
  2219. const dataset = new database(this.#content).on_skip((fail) => {
  2220. this._info = "Skipping " + fail.product.barcode + "...";
  2221. result.skip(fail);
  2222. }).process().results();
  2223. const loop = new import_loop(dataset).on_autocomplete((target) => {
  2224. this._info = "Searching for " + target.barcode + "...";
  2225. }).on_create((target) => {
  2226. this._info = "Creating " + target.barcode + "...";
  2227. }).on_single_fail((target) => {
  2228. this._info = "Can not add " + target.product.barcode + "...";
  2229. result.fail(target);
  2230. }).on_skip((target) => {
  2231. this._info = "Skipping " + target.product.barcode + "...";
  2232. result.skip(target);
  2233. }).on_single_success((target) => {
  2234. this._info = "Created " + target.barcode + " success.";
  2235. }).finally(() => {
  2236. searcher.reload();
  2237. const log = new downloader().content(result.content()).type("text/plain").encode("utf-8").name("import-json.log").process();
  2238. if (result.length === 0) {
  2239. this._success = "All items imported.";
  2240. setTimeout(() => {
  2241. this.hide();
  2242. });
  2243. } else {
  2244. this._success = "Not all items imported...";
  2245. }
  2246. }).process();
  2247. } catch (error) {
  2248. this._error = new String(error);
  2249. }
  2250. }
  2251. };
  2252. // application/scripts/login_bar.js
  2253. var login_bar = class {
  2254. #manager;
  2255. constructor(target) {
  2256. this.#manager = new login_manager();
  2257. if (!this.#manager.logged_in) {
  2258. this.#not_logged(target);
  2259. return;
  2260. }
  2261. this.#logged(target);
  2262. }
  2263. #not_login_propertly() {
  2264. this.#manager.logout();
  2265. location.reload();
  2266. }
  2267. async #logged(target) {
  2268. const user2 = await this.#manager.get_user();
  2269. if (user2 === null) {
  2270. this.#not_login_propertly();
  2271. }
  2272. const info_icon = document.createElement("span");
  2273. info_icon.classList.add("icon");
  2274. info_icon.classList.add("material-icons");
  2275. info_icon.innerText = "account_circle";
  2276. const info_content = document.createElement("span");
  2277. info_content.innerText = user2.nick;
  2278. const info = document.createElement("p");
  2279. info.classList.add("login-info");
  2280. info.appendChild(info_icon);
  2281. info.appendChild(info_content);
  2282. target.appendChild(info);
  2283. const logout_button = document.createElement("button");
  2284. logout_button.innerText = "logout";
  2285. logout_button.classList.add("logout-button");
  2286. logout_button.classList.add("material-icons");
  2287. target.appendChild(logout_button);
  2288. const add_product_button = document.createElement("button");
  2289. add_product_button.innerText = "add";
  2290. add_product_button.classList.add("add-product-button");
  2291. add_product_button.classList.add("material-icons");
  2292. target.appendChild(add_product_button);
  2293. const import_products_button = document.createElement("button");
  2294. import_products_button.innerText = "dataset_linked";
  2295. import_products_button.classList.add("material-icons");
  2296. import_products_button.classList.add("import-products-button");
  2297. target.appendChild(import_products_button);
  2298. add_product_button.addEventListener("click", () => {
  2299. new product_adder().show();
  2300. });
  2301. import_products_button.addEventListener("click", () => {
  2302. new import_products().show();
  2303. });
  2304. logout_button.addEventListener("click", () => {
  2305. this.#manager.logout();
  2306. location.reload();
  2307. });
  2308. }
  2309. #not_logged(target) {
  2310. const login_button = document.createElement("button");
  2311. login_button.innerText = "account_circle";
  2312. login_button.classList.add("login-button");
  2313. login_button.classList.add("material-icons");
  2314. target.appendChild(login_button);
  2315. new login_prompt(login_button);
  2316. }
  2317. };
  2318. // application/scripts/scroll_up.js
  2319. var scroll_up = class {
  2320. #button;
  2321. constructor(button) {
  2322. this.#button = button;
  2323. this.#update();
  2324. document.addEventListener("scroll", () => {
  2325. this.#update();
  2326. });
  2327. this.#button.addEventListener("click", () => {
  2328. this.scroll();
  2329. });
  2330. }
  2331. scroll() {
  2332. this.#position = 0;
  2333. }
  2334. get #position() {
  2335. return document.scrollingElement.scrollTop;
  2336. }
  2337. set #position(target) {
  2338. document.scrollingElement.scrollTop = target;
  2339. }
  2340. get #visible() {
  2341. return Number(this.#button.style.opacity) === 1;
  2342. }
  2343. set #visible(target) {
  2344. this.#button.style.opacity = target ? "1" : "0";
  2345. }
  2346. get #margin() {
  2347. return 20;
  2348. }
  2349. #update() {
  2350. this.#visible = this.#position > this.#margin;
  2351. }
  2352. };
  2353. // application/scripts/color_theme.js
  2354. var color_theme = class {
  2355. #button;
  2356. #themes;
  2357. get themes() {
  2358. return Object.keys(this.#themes);
  2359. }
  2360. theme_name(target) {
  2361. return this.#themes[target];
  2362. }
  2363. constructor(button, themes = null) {
  2364. this.#button = button;
  2365. this.#themes = themes;
  2366. if (this.#themes === null) {
  2367. this.#themes = {
  2368. "dark-theme": "Dark",
  2369. "white-theme": "White"
  2370. };
  2371. }
  2372. this.#load();
  2373. this.#button.addEventListener("click", () => {
  2374. this.change();
  2375. });
  2376. }
  2377. get current() {
  2378. if (localStorage.hasOwnProperty("theme")) {
  2379. return localStorage.getItem("theme");
  2380. }
  2381. return this.themes[this.themes.length - 1];
  2382. }
  2383. #load() {
  2384. this.#show(this.current);
  2385. }
  2386. #save(target) {
  2387. localStorage.setItem("theme", target);
  2388. }
  2389. #show(target) {
  2390. const themes = this.themes;
  2391. const body = document.querySelector("body");
  2392. body.classList.forEach((count) => {
  2393. if (themes.indexOf(count) !== -1) {
  2394. body.classList.remove(count);
  2395. }
  2396. });
  2397. body.classList.add(target);
  2398. }
  2399. change() {
  2400. const themes = this.themes;
  2401. const current = this.current;
  2402. let position = themes.indexOf(current) + 1;
  2403. if (position === themes.length) {
  2404. position = 0;
  2405. }
  2406. const updated = themes[position];
  2407. this.#save(updated);
  2408. this.#show(updated);
  2409. }
  2410. };
  2411. // application/scripts/core.js
  2412. document.addEventListener("DOMContentLoaded", async () => {
  2413. const top_bar_spacing = new height_equaler(
  2414. document.querySelector(".top-bar"),
  2415. document.querySelector(".top-bar-spacing")
  2416. );
  2417. const container = document.querySelector(".products");
  2418. const search_bar = document.querySelector("form.search");
  2419. const search_title = document.querySelector(".search-title");
  2420. const login_space = document.querySelector(".top-bar .right");
  2421. const scroll_up_button = document.querySelector(".scroll-up-button");
  2422. const reverse_colors = document.querySelector(".reverse-colors");
  2423. const manager = new product_containers(container);
  2424. new login_bar(login_space);
  2425. new scroll_up(scroll_up_button);
  2426. new color_theme(reverse_colors);
  2427. new searcher(search_bar, manager, search_title).show_all();
  2428. });
  2429. })();