vue-app.ejs 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. <script>
  2. var sort_data = function (objects, sort) {
  3. if(sort == 'desc'){
  4. return objects.sort(function(a, b) {
  5. a = moment(a.start_date);
  6. b = moment(b.start_date);
  7. return a>b ? -1 : a<b ? 1 : 0;
  8. });
  9. } else if(sort == "asc"){
  10. return objects.sort(function(a,b){return moment(a.start_date) - moment(b.start_date)});
  11. }
  12. }
  13. var generate_search_terms = function(projects){
  14. var terms = [];
  15. projects.forEach(project => {
  16. terms.push({ text: project.title, type: 'project', classes : 'result-project' });
  17. var date = moment(new Date(project.date)).format('YYYY');
  18. terms.push({ text: date, type: 'year', classes : 'result-date' });
  19. project.tags.forEach(tag => {
  20. terms.push({ text: tag, type: 'tag', classes : 'result-tag' });
  21. })
  22. project.contacts.forEach(contact => {
  23. terms.push({text: contact.name, type: 'contact', classes : 'result-contact'});
  24. })
  25. });
  26. var filtered_terms = [];
  27. terms.forEach(term => {
  28. var found = false;
  29. for (let i = 0; i < filtered_terms.length; i++) {
  30. if(term.text == filtered_terms[i].text) found = true;
  31. }
  32. if(found == false) filtered_terms.push(term);
  33. });
  34. return filtered_terms;
  35. }
  36. var app = new Vue({
  37. el: '#vue-app',
  38. data: {
  39. view : {
  40. type: 'cards',
  41. sort : 'desc'
  42. },
  43. contactMessage : {
  44. name: "",
  45. email: "",
  46. content: ""
  47. },
  48. contactMessageSuccess : false,
  49. contactMessageError : false,
  50. projects : sort_data(projectsList, 'desc'),
  51. search_query : '',
  52. search_tags : [],
  53. autocompleteSearchTerms: generate_search_terms(projectsList)
  54. },
  55. methods: {
  56. filterProjects: function(){
  57. console.log('Filtering projects')
  58. },
  59. getDate: function(date){
  60. return moment(new Date(date)).fromNow();
  61. },
  62. getSearchTagIcon: function(category){
  63. switch (category) {
  64. case 'contact':
  65. return 'fa-user';
  66. case 'tag':
  67. return 'fa-tag';
  68. case 'project':
  69. return 'fa-folder';
  70. case 'year':
  71. return 'fa-calendar';
  72. default:
  73. return '';
  74. }
  75. },
  76. sendMessage: function(contactMessage){
  77. if(contactMessage.name != "" && contactMessage.email != "" && contactMessage.content != ""){
  78. console.log("sending message");
  79. var req = new XMLHttpRequest();
  80. req.overrideMimeType("application/json");
  81. req.open('POST', "https://bj2npxevi6.execute-api.us-east-1.amazonaws.com/prod/jamesperet-lambda-mailer", true);
  82. req.onload = function() {
  83. var res = req.responseText;
  84. if(req.status != 200) {
  85. app.contactMessageError = true;
  86. app.mixpanelTrack('Error', { message: contactMessage, error: req });
  87. } else {
  88. app.contactMessageSuccess = true;
  89. app.mixpanelTrack('Contact Message Sent', { message: contactMessage })
  90. }
  91. };
  92. req.send(JSON.stringify(contactMessage));
  93. }
  94. },
  95. resetContactForm: function(){
  96. if(app.contactMessageError == true) app.contactMessageError = false;
  97. else{
  98. app.contactMessageSuccess = false;
  99. app.contactMessage.content = ""
  100. }
  101. },
  102. mixpanelTrack: function(event_name, properties){
  103. if (location.hostname !== "localhost" && location.hostname !== "127.0.0.1"){
  104. mixpanel.track(event_name, properties);
  105. console.log(`Tracking: ${event_name}, ${JSON.stringify(properties)}`)
  106. } else {
  107. console.log('No tracking in ' + location.hostname);
  108. }
  109. }
  110. },
  111. computed: {
  112. filterSearchTerms() {
  113. if(this.search_query.length == 1) return [];
  114. return this.autocompleteSearchTerms.filter(i => {
  115. return i.text.toLowerCase().indexOf(this.search_query.toLowerCase()) !== -1;
  116. });
  117. },
  118. filteredProjects(){
  119. var result = [];
  120. if(this.search_tags.length == 0){
  121. return this.projects;
  122. } else {
  123. console.log(this.search_tags);
  124. var filtered = [];
  125. this.projects.forEach(project => {
  126. filtered.push(project);
  127. })
  128. this.search_tags.forEach(search_tag => {
  129. search = search_tag.text.toLowerCase();
  130. if(search_tag.type == 'project'){
  131. filtered = filtered.filter(project => {
  132. title = project.title.toLowerCase();
  133. if(title.includes(search) || title == search ){
  134. return true
  135. }
  136. });
  137. } else if(search_tag.type == 'tag') {
  138. console.log("search is tag")
  139. filtered = filtered.filter(project => {
  140. for (let i = 0; i < project.tags.length; i++) {
  141. const tag = project.tags[i];
  142. if(tag == search) return true;
  143. }
  144. })
  145. } else if(search_tag.type == 'contact') {
  146. console.log("search is contact")
  147. filtered = filtered.filter(project => {
  148. for (let i = 0; i < project.contacts.length; i++) {
  149. var contact = project.contacts[i].name.toLowerCase();
  150. if(contact == search) return true;
  151. }
  152. })
  153. } else if(search_tag.type == 'date') {
  154. console.log("search is date")
  155. filtered = filtered.filter(project => {
  156. if(moment(new Date(project.date)).format('YYYY') == search) return true
  157. })
  158. } else {
  159. filtered = filtered.filter(project => {
  160. title = project.title.toLowerCase();
  161. if(title.includes(search) || title == search ){
  162. return true
  163. }
  164. for (let i = 0; i < project.tags.length; i++) {
  165. const tag = project.tags[i];
  166. if(tag.includes(search) || tag == search) {
  167. return true;
  168. }
  169. }
  170. for (let i = 0; i < project.contacts.length; i++) {
  171. var contact = project.contacts[i].name.toLowerCase();
  172. if(contact.includes(search) || contact == search) {
  173. return true;
  174. }
  175. }
  176. if(moment(new Date(project.date)).format('YYYY') == search) return true
  177. if(project.description.includes(search)){
  178. return true
  179. }
  180. return false;
  181. })
  182. }
  183. });
  184. return filtered;
  185. }
  186. }
  187. },
  188. mounted: function () {
  189. this.$nextTick(function () {
  190. // Code that will run only after the
  191. // entire view has been rendered
  192. if(app.projects.length > 0) console.log(app.projects);
  193. })
  194. }
  195. })
  196. </script>