pixelia_view.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. const { div, h2, p, section, form, input, label, select, option, button, table, tr, td, hr, ul, li, a, br } = require("../server/node_modules/hyperaxe");
  2. const { template, i18n } = require('./main_views');
  3. exports.pixeliaView = (pixelArt, errorMessage) => {
  4. const title = i18n.pixeliaTitle;
  5. const description = i18n.pixeliaDescription;
  6. const gridWidth = 50;
  7. const gridHeight = 200;
  8. const grid = table(
  9. { class: "pixelia-grid" },
  10. ...Array.from({ length: gridHeight }, (_, rowIndex) =>
  11. tr(
  12. ...Array.from({ length: gridWidth }, (_, colIndex) => {
  13. const pixel = pixelArt.find(p => p.x === colIndex + 1 && p.y === rowIndex + 1);
  14. const colorClass = pixel ? `pixel-color-${pixel.color.slice(1)}` : 'pixel-empty';
  15. const cellId = `cell-${rowIndex + 1}-${colIndex + 1}`;
  16. return td(
  17. {
  18. id: cellId,
  19. title: pixel ? `By: ${pixel.author}` : "",
  20. class: `pixel-cell ${colorClass}`
  21. },
  22. ""
  23. );
  24. })
  25. )
  26. )
  27. );
  28. const contributors = pixelArt.length > 0 ? [...new Set(pixelArt.flatMap(p => p.contributors_inhabitants || []))] : [];
  29. return template(
  30. title,
  31. section(
  32. div({ class: "tags-header" },
  33. h2(title),
  34. p(description)
  35. )
  36. ),
  37. section(
  38. div({ class: "pixelia-form-wrap" },
  39. form({ method: "POST", action: "/pixelia/paint"},
  40. label({ for: "x" }, "X (1-50):"),
  41. input({ type: "number", id: "x", name: "x", min: 1, max: gridWidth, required: true }),
  42. br(),br(),
  43. label({ for: "y" }, "Y (1-200):"),
  44. input({ type: "number", id: "y", name: "y", min: 1, max: gridHeight, required: true }),
  45. br(),br(),
  46. label({ for: "color" }, i18n.colorLabel),
  47. select({ id: "color", name: "color", required: true },
  48. option({ value: "#000000", style: "background-color:#000000;" }, "Black"),
  49. option({ value: "#ffffff", style: "background-color:#ffffff;" }, "White"),
  50. option({ value: "#17f018", style: "background-color:#17f018;" }, "Green"),
  51. option({ value: "#ffbb00", style: "background-color:#ffbb00;" }, "Yellow"),
  52. option({ value: "#ff0000", style: "background-color:#ff0000;" }, "Red"),
  53. option({ value: "#0000ff", style: "background-color:#0000ff;" }, "Blue"),
  54. option({ value: "#ffff00", style: "background-color:#ffff00;" }, "Lime"),
  55. option({ value: "#00ff00", style: "background-color:#00ff00;" }, "Spring Green"),
  56. option({ value: "#00ffff", style: "background-color:#00ffff;" }, "Aqua"),
  57. option({ value: "#ff00ff", style: "background-color:#ff00ff;" }, "Fuchsia"),
  58. option({ value: "#a52a2a", style: "background-color:#a52a2a;" }, "Brown"),
  59. option({ value: "#800080", style: "background-color:#800080;" }, "Purple"),
  60. option({ value: "#808000", style: "background-color:#808000;" }, "Olive"),
  61. option({ value: "#00bfff", style: "background-color:#00bfff;" }, "Deep Sky Blue"),
  62. option({ value: "#d3d3d3", style: "background-color:#d3d3d3;" }, "Light Grey"),
  63. option({ value: "#ff6347", style: "background-color:#ff6347;" }, "Tomato")
  64. ),
  65. br(),br(),
  66. button({ type: "submit" }, i18n.paintButton)
  67. )
  68. ),
  69. errorMessage ? div({ class: "error-message" }, errorMessage) : null,
  70. div({ class: "total-pixels" },
  71. h2(`${i18n.totalPixels}: ${pixelArt.length}`)
  72. )
  73. ),
  74. hr(),
  75. section(
  76. div({ class: "main_content" },
  77. div({ class: "pixelia-grid-wrap" }, grid),
  78. pixelArt.length > 0 ?
  79. div({ class: "contributors" },
  80. h2(i18n.contributorsTitle),
  81. ul(
  82. ...contributors.map(author =>
  83. li(a({ class: 'user-link', href: `/author/${encodeURIComponent(author)}` }, author))
  84. )
  85. )
  86. ) : null
  87. )
  88. )
  89. );
  90. };