cv_view.js 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. const { form, button, div, h2, p, section, textarea, label, input, br, img, a, select, option } = require("../server/node_modules/hyperaxe");
  2. const { template, i18n } = require('./main_views');
  3. const generateCVBox = (label, content, className) => {
  4. return div({ class: `cv-box ${className}` },
  5. h2(label),
  6. content
  7. );
  8. };
  9. const generateTags = (tags) => {
  10. return tags && tags.length
  11. ? div(
  12. tags.map(tag =>
  13. a({
  14. href: `/search?query=%23${encodeURIComponent(tag)}`,
  15. class: "tag-link",
  16. style: "margin-right:0.8em;margin-bottom:0.5em;"
  17. }, `#${tag}`)
  18. )
  19. )
  20. : null;
  21. };
  22. exports.createCVView = async (cv = {}, editMode = false) => {
  23. const title = editMode ? i18n.cvEditSectionTitle : i18n.cvCreateSectionTitle;
  24. return template(
  25. title,
  26. section(
  27. div({ class: "tags-header" },
  28. h2(title),
  29. p(i18n.cvDescription)
  30. ),
  31. div({ class: "cv-form" },
  32. form({
  33. method: "POST",
  34. action: editMode ? `/cv/update/${encodeURIComponent(cv.id)}` : "/cv/upload",
  35. enctype: "multipart/form-data"
  36. },
  37. generateCVBox(i18n.cvPersonal, [
  38. label(i18n.cvNameLabel), br(),
  39. input({ type: "text", name: "name", required: true, value: cv.name || "" }), br(),
  40. label(i18n.cvDescriptionLabel), br(),
  41. textarea({ name: "description", required: true }, cv.description || ""), br(),
  42. label(i18n.cvLanguagesLabel), br(),
  43. input({ type: "text", name: "languages", value: cv.languages || "" }), br(),
  44. label(i18n.cvPhotoLabel), br(),
  45. input({ type: "file", name: "image" }), br(), br(),
  46. label(i18n.cvPersonalExperiencesLabel), br(),
  47. textarea({ name: "personalExperiences", rows: 4 }, cv.personalExperiences || ""), br(),
  48. label(i18n.cvPersonalSkillsLabel), br(),
  49. input({ type: "text", name: "personalSkills", required: true, value: (cv.personalSkills || []).join(", ") }), br()
  50. ], "personal"),
  51. generateCVBox(i18n.cvOasis, [
  52. label(i18n.cvOasisExperiencesLabel), br(),
  53. textarea({ name: "oasisExperiences", rows: 4 }, cv.oasisExperiences || ""), br(),
  54. label(i18n.cvOasisSkillsLabel), br(),
  55. input({ type: "text", name: "oasisSkills", value: (cv.oasisSkills || []).join(", ") }), br()
  56. ], "oasis"),
  57. generateCVBox(i18n.cvEducational, [
  58. label(i18n.cvEducationExperiencesLabel), br(),
  59. textarea({ name: "educationExperiences", rows: 4 }, cv.educationExperiences || ""), br(),
  60. label(i18n.cvEducationalSkillsLabel), br(),
  61. input({ type: "text", name: "educationalSkills", value: (cv.educationalSkills || []).join(", ") }), br()
  62. ], "education"),
  63. generateCVBox(i18n.cvProfessional, [
  64. label(i18n.cvProfessionalExperiencesLabel), br(),
  65. textarea({ name: "professionalExperiences", rows: 4 }, cv.professionalExperiences || ""), br(),
  66. label(i18n.cvProfessionalSkillsLabel), br(),
  67. input({ type: "text", name: "professionalSkills", value: (cv.professionalSkills || []).join(", ") }), br()
  68. ], "professional"),
  69. generateCVBox(i18n.cvAvailability, [
  70. label(i18n.cvLocationLabel), br(),
  71. input({ type: "text", name: "location", required: true, value: cv.location || "UNKNOWN" }), br(),
  72. label(i18n.cvStatusLabel), br(),
  73. select({ name: "status", required: true },
  74. option({ value: "AVAILABLE", selected: cv.status === "AVAILABLE FOR COLLABORATION" }, "AVAILABLE FOR COLLABORATION"),
  75. option({ value: "UNAVAILABLE", selected: cv.status === "NOT CURRENTLY AVAILABLE" }, "NOT CURRENTLY AVAILABLE"),
  76. option({ value: "LOOKING FOR WORK", selected: !cv.status || cv.status === "LOOKING FOR WORK" }, "LOOKING FOR WORK")
  77. ), br(), br(),
  78. label(i18n.cvPreferencesLabel), br(),
  79. select({ name: "preferences", required: true },
  80. option({ value: "IN PERSON", selected: cv.preferences === "IN-PERSON ONLY" }, "IN-PERSON ONLY"),
  81. option({ value: "REMOTE WORKING", selected: !cv.preferences || cv.preferences === "REMOTE WORKING" }, "REMOTE-WORKING")
  82. ), br()
  83. ], "availability"),
  84. button({ type: "submit" }, editMode ? i18n.cvUpdateButton : i18n.cvCreateButton)
  85. )
  86. )
  87. )
  88. )
  89. };
  90. exports.cvView = async (cv) => {
  91. const title = i18n.cvTitle;
  92. if (!cv) {
  93. return template(
  94. title,
  95. section(
  96. div({ class: "tags-header" },
  97. h2(title),
  98. p(i18n.cvDescription)
  99. ),
  100. div({ class: "no-cv" },
  101. p(i18n.cvNoCV),
  102. form({ method: "GET", action: "/cv/create" },
  103. button({ type: "submit" }, i18n.cvCreateButton)
  104. )
  105. )
  106. )
  107. )
  108. }
  109. const hasPersonal = cv.contact || cv.name || cv.description || cv.photo || typeof cv.oasisContributor === "boolean" || (cv.personalSkills && cv.personalSkills.length);
  110. const hasPersonalExp = cv.personalExperiences;
  111. const hasOasis = cv.oasisExperiences || (cv.oasisSkills && cv.oasisSkills.length);
  112. const hasEducational = cv.educationExperiences || cv.languages || (cv.educationalSkills && cv.educationalSkills.length);
  113. const hasProfessional = cv.professionalExperiences || (cv.professionalSkills && cv.professionalSkills.length);
  114. const hasAvailability = cv.location || cv.status || cv.preferences;
  115. return template(
  116. title,
  117. section(
  118. div({ class: "tags-header" },
  119. h2(title),
  120. p(i18n.cvDescription)
  121. ),
  122. div({ class: "cv-section" },
  123. div({ class: "cv-item" }, ...[
  124. div({ class: "cv-actions" },
  125. form({ method: "GET", action: `/cv/edit/${encodeURIComponent(cv.id)}` },
  126. button({ type: "submit" }, i18n.cvEditButton)
  127. ),
  128. form({ method: "POST", action: `/cv/delete/${encodeURIComponent(cv.id)}` },
  129. button({ type: "submit" }, i18n.cvDeleteButton)
  130. )
  131. ),
  132. div({ class: "cv-meta" },
  133. p(`${i18n.cvCreatedAt}: ${new Date(cv.createdAt).toLocaleString()}`),
  134. cv.updatedAt ? p(`${i18n.cvUpdatedAt}: ${new Date(cv.updatedAt).toLocaleString()}`) : null
  135. ),
  136. hasPersonal ? div({ class: "cv-box personal" }, ...[
  137. cv.photo
  138. ? img({
  139. src: `/blob/${encodeURIComponent(cv.photo)}`,
  140. class: "cv-photo"
  141. })
  142. : null,
  143. cv.name ? h2(`${cv.name}`) : null,
  144. cv.contact ? p(a({ class: "user-link", href: `/author/${encodeURIComponent(cv.contact)}` }, cv.contact)) : null,
  145. cv.description ? p(`${cv.description}`) : null,
  146. cv.languages ? p(`${i18n.cvLanguagesLabel}: ${cv.languages}`) : null,
  147. (cv.personalSkills && cv.personalSkills.length)
  148. ? div(
  149. cv.personalSkills.map(tag =>
  150. a({
  151. href: `/search?query=%23${encodeURIComponent(tag)}`,
  152. class: "tag-link",
  153. style: "margin-right:0.8em;margin-bottom:0.5em;"
  154. }, `#${tag}`)
  155. )
  156. )
  157. : null
  158. ]) : null,
  159. hasOasis ? div({ class: "cv-box oasis" }, ...[
  160. h2(i18n.cvOasisContributorView),
  161. p(`${cv.oasisExperiences}`),
  162. (cv.oasisSkills && cv.oasisSkills.length)
  163. ? div(
  164. cv.oasisSkills.map(tag =>
  165. a({
  166. href: `/search?query=%23${encodeURIComponent(tag)}`,
  167. class: "tag-link",
  168. style: "margin-right:0.8em;margin-bottom:0.5em;"
  169. }, `#${tag}`)
  170. )
  171. )
  172. : null
  173. ]) : null,
  174. hasEducational ? div({ class: "cv-box education" }, ...[
  175. h2(i18n.cvEducationalView),
  176. cv.educationExperiences ? p(`${cv.educationExperiences}`) : null,
  177. (cv.educationalSkills && cv.educationalSkills.length)
  178. ? div(
  179. cv.educationalSkills.map(tag =>
  180. a({
  181. href: `/search?query=%23${encodeURIComponent(tag)}`,
  182. class: "tag-link",
  183. style: "margin-right:0.8em;margin-bottom:0.5em;"
  184. }, `#${tag}`)
  185. )
  186. )
  187. : null
  188. ]) : null,
  189. hasProfessional ? div({ class: "cv-box professional" }, ...[
  190. h2(i18n.cvProfessionalView),
  191. cv.professionalExperiences ? p(`${cv.professionalExperiences}`) : null,
  192. (cv.professionalSkills && cv.professionalSkills.length)
  193. ? div(
  194. cv.professionalSkills.map(tag =>
  195. a({
  196. href: `/search?query=%23${encodeURIComponent(tag)}`,
  197. class: "tag-link",
  198. style: "margin-right:0.8em;margin-bottom:0.5em;"
  199. }, `#${tag}`)
  200. )
  201. )
  202. : null
  203. ]) : null,
  204. hasAvailability ? div({ class: "cv-box availability" }, ...[
  205. h2(i18n.cvAvailabilityView),
  206. cv.location ? p(`${i18n.cvLocationLabel}: ${cv.location}`) : null,
  207. cv.status ? p(`${i18n.cvStatusLabel}: ${cv.status}`) : null,
  208. cv.preferences ? p(`${i18n.cvPreferencesLabel}: ${cv.preferences}`) : null
  209. ]) : null
  210. ])
  211. )
  212. )
  213. );
  214. };