From 87086daf29c5a258f34bb009ceae2de5c4dbfa99 Mon Sep 17 00:00:00 2001
From: johnsonpham <phamthanhtrinh.vt@gmail.com>
Date: Thu, 27 Aug 2015 10:13:55 +0700
Subject: [PATCH 1/7] =?UTF-8?q?fix=20bug=20for=20Issue=201:=20The=20proble?=
 =?UTF-8?q?m=20is=20not=20that=20end=20date=20is=20in=20the=20past=20(see?=
 =?UTF-8?q?=20my=20clock=20at=20top=20right=20corner=20of=20the=20image).?=
 =?UTF-8?q?=20The=20message=20error=20in=20this=20case=20should=20be=20?=
 =?UTF-8?q?=E2=80=9CEvent=20Start=20date=20time=20cannot=20be=20after=20it?=
 =?UTF-8?q?s=20End=20date=20time."?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/main/webapp/assets/modules/create-event/create-event.html | 4 ++--
 src/main/webapp/assets/modules/translation/messages_en.json   | 1 +
 src/main/webapp/assets/modules/translation/messages_vi.json   | 1 +
 3 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/main/webapp/assets/modules/create-event/create-event.html b/src/main/webapp/assets/modules/create-event/create-event.html
index f6550dc69..87df07e1c 100644
--- a/src/main/webapp/assets/modules/create-event/create-event.html
+++ b/src/main/webapp/assets/modules/create-event/create-event.html
@@ -23,7 +23,7 @@ <h2 translate="createYourNewEvent"></h2>
                    options="uiConfig.fromNowDatetimeConfig" ng-required="true"/>
             <div class="error-messages" ng-show="(webinarForm.$submitted || webinarForm.startDate.$dirty) && (webinarForm.startDate.$invalid)">
               <div translate="requiredThisField" ng-show="webinarForm.startDate.$error.required"/>
-              <div translate="cannotInPast" ng-show="state('error-past-date')"/>
+              <div translate="mustBeInTheFuture" ng-show="state('error-past-date')"/>
               <div translate="startDateGTEndDate" ng-show="state('error-range-date')"/>
             </div>
           </div>
@@ -35,7 +35,7 @@ <h2 translate="createYourNewEvent"></h2>
                    class="input-style"  ng-required="true"/>
             <div class="error-messages" ng-show="(webinarForm.$submitted || webinarForm.endDate.$dirty) && (webinarForm.endDate.$invalid)">
               <div translate="requiredThisField" ng-show="webinarForm.endDate.$error.required"/>
-              <div translate="cannotInPast" ng-show="state('error-past-date')"/>
+              <div translate="mustBeInTheFuture" ng-show="state('error-past-date')"/>
             </div>
           </div>
         </div>
diff --git a/src/main/webapp/assets/modules/translation/messages_en.json b/src/main/webapp/assets/modules/translation/messages_en.json
index 667e40c42..246b391c8 100644
--- a/src/main/webapp/assets/modules/translation/messages_en.json
+++ b/src/main/webapp/assets/modules/translation/messages_en.json
@@ -684,6 +684,7 @@
   "allEvents": "All Events",
   "whatDoWeOffer": "What do we offer?",
   "cannotInPast": "This field cannot be in the past.",
+  "mustBeInTheFuture": "This field should be in the future.",
   "register": "Register",
   "upcomingEvents": "Upcoming Events",
   "viewMoreEvents": "View More Events",
diff --git a/src/main/webapp/assets/modules/translation/messages_vi.json b/src/main/webapp/assets/modules/translation/messages_vi.json
index 2d3c1157a..6906aa162 100644
--- a/src/main/webapp/assets/modules/translation/messages_vi.json
+++ b/src/main/webapp/assets/modules/translation/messages_vi.json
@@ -684,6 +684,7 @@
   "allEvents": "Tất cả Sự Kiện",
   "whatDoWeOffer": "Phúc lợi công ty",
   "cannotInPast": "Trường này không được ở quá khứ.",
+  "mustBeInTheFuture": "Trường này phải ở tương lai.",
   "register": "Đăng Ký",
   "upcomingEvents": "Sự Kiện Sắp Diễn Ra",
   "viewMoreEvents": "Các Sự Kiện Khác",

From 673f9ce5d76556cff6fbb7219de59dd517c2f4bf Mon Sep 17 00:00:00 2001
From: johnsonpham <phamthanhtrinh.vt@gmail.com>
Date: Thu, 27 Aug 2015 10:19:33 +0700
Subject: [PATCH 2/7] fix bug loading for Create Event page

---
 .../webapp/assets/modules/create-event/createEventController.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/webapp/assets/modules/create-event/createEventController.js b/src/main/webapp/assets/modules/create-event/createEventController.js
index 3353c3a02..bb3593f6b 100644
--- a/src/main/webapp/assets/modules/create-event/createEventController.js
+++ b/src/main/webapp/assets/modules/create-event/createEventController.js
@@ -2,13 +2,13 @@ techlooper.controller("createEventController", function ($scope, $translate, jso
 
   $scope.createWebinar = function () {
     $scope.webinarForm.$setSubmitted();
-    utils.sendNotification(jsonValue.notifications.loading, $(window).height());
     $anchorScroll();
     if ($scope.webinarForm.$invalid) {
       return;
     }
 
     apiService.createWebinar($scope.webinar).success(function (data) {
+      utils.sendNotification(jsonValue.notifications.loading, $(window).height());
       var title = utils.toAscii(data.name);
       window.location.href = sprintf('#/event-details/'+title+'-'+data.createdDateTime+ '-id');
     }).finally(function () {

From 269465cbcb3c8aeb3ff360c2160e5a0c5d437497 Mon Sep 17 00:00:00 2001
From: Phuong H <phuonghqh@gmail.com>
Date: Thu, 27 Aug 2015 10:25:56 +0700
Subject: [PATCH 3/7] Able to update google calendar

---
 .../techlooper/config/CoreConfiguration.java  | 49 ++++---------------
 .../sec/SwitchingAuthenticationProvider.java  |  2 +-
 .../techlooper/controller/UserController.java |  2 +-
 .../com/techlooper/entity/CalendarInfo.java   | 39 +++++++++++++++
 .../com/techlooper/entity/WebinarEntity.java  | 38 +++++++-------
 .../com/techlooper/model/SocialConfig.java    | 10 ++++
 .../com/techlooper/model/UserProfileDto.java  |  4 +-
 .../techlooper/service/WebinarService.java    |  2 +-
 .../service/impl/WebinarServiceImpl.java      | 30 +++++++++---
 src/main/resources/local/socialConfig.json    |  3 +-
 .../resources/local/techlooper.properties     |  5 +-
 .../resources/production/socialConfig.json    |  3 +-
 src/main/resources/staging/socialConfig.json  |  3 +-
 13 files changed, 116 insertions(+), 74 deletions(-)
 create mode 100644 src/main/java/com/techlooper/entity/CalendarInfo.java

diff --git a/src/main/java/com/techlooper/config/CoreConfiguration.java b/src/main/java/com/techlooper/config/CoreConfiguration.java
index 78c2c41da..ad145b1d6 100644
--- a/src/main/java/com/techlooper/config/CoreConfiguration.java
+++ b/src/main/java/com/techlooper/config/CoreConfiguration.java
@@ -93,8 +93,6 @@ public class CoreConfiguration implements ApplicationContextAware {
 
   @Value("classpath:google-auth/techLooper.p12")
   private org.springframework.core.io.Resource googleApiAuthResource;
-//  @Value("classpath:google-auth")
-//  private org.springframework.core.io.Resource googleApiAuthResource;
 
   private ApplicationContext applicationContext;
 
@@ -392,13 +390,18 @@ public JsonNode vietnamworksConfiguration() throws IOException {
 
   @Bean
   @DependsOn("jsonConfigRepository")
+  public SocialConfig googleSocialConfig() {
+    return applicationContext.getBean(JsonConfigRepository.class).getSocialConfig().stream()
+      .filter(socialConfig -> socialConfig.getProvider() == SocialProvider.GOOGLE)
+      .findFirst().get();
+  }
+
+  @Bean
   public Calendar googleCalendar() throws GeneralSecurityException, IOException {
     JacksonFactory jsonFactory = JacksonFactory.getDefaultInstance();
     HttpTransport transport = GoogleNetHttpTransport.newTrustedTransport();
 
-    SocialConfig googleConfig = applicationContext.getBean(JsonConfigRepository.class).getSocialConfig().stream()
-      .filter(socialConfig -> socialConfig.getProvider() == SocialProvider.GOOGLE)
-      .findFirst().get();
+    SocialConfig googleConfig = googleSocialConfig();
 
 //    GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(transport, jsonFactory,
 //      googleConfig.getApiKey(), googleConfig.getSecretKey(),
@@ -417,45 +420,11 @@ public Calendar googleCalendar() throws GeneralSecurityException, IOException {
       .setServiceAccountId(googleConfig.getServiceAccountEmail())
       .setServiceAccountPrivateKeyFromP12File(googleApiAuthResource.getFile())
       .setServiceAccountScopes(Collections.singleton(CalendarScopes.CALENDAR))
-      .setServiceAccountUser("techlooperawesome@gmail.com")
+      .setServiceAccountUser(googleConfig.getCalendarId())
       .build();
 
-//    boolean bool = credential.refreshToken();
-//    String token = credential.getAccessToken();
-//    System.out.println(bool);
-//    System.out.println(token);
-
     return new Calendar.Builder(transport, jsonFactory, credential)
       .setApplicationName("Techlooper").build();
-
-//    Event event = new Event()
-//      .setSummary("Google I/O 2015")
-//      .setLocation("800 Howard St., San Francisco, CA 94103")
-//      .setDescription("A chance to hear more about Google's developer products.");
-//
-//    DateTime startDateTime = new DateTime("2015-09-28T09:00:00-07:00");
-//    EventDateTime start = new EventDateTime()
-//      .setDateTime(startDateTime)
-//      .setTimeZone("America/Los_Angeles");
-//    event.setStart(start);
-//
-//    DateTime endDateTime = new DateTime("2015-09-28T17:00:00-07:00");
-//    EventDateTime end = new EventDateTime()
-//      .setDateTime(endDateTime)
-//      .setTimeZone("America/Los_Angeles");
-//    event.setEnd(end);
-//
-//    EventAttendee[] attendees = new EventAttendee[]{
-//      new EventAttendee().setEmail("phuonghqh@gmail.com"),
-//      new EventAttendee().setEmail("thu.hoang@navigosgroup.com"),
-//    };
-//    event.setAttendees(Arrays.asList(attendees));
-//
-//    String calendarId = "techlooperawesome@gmail.com";
-//    event = calendar.events().insert(calendarId, event).setSendNotifications(true).execute();
-//    System.out.printf("Event created: %s\n", event.getHtmlLink());
-//    event.getHangoutLink()
-//    return calendar;
   }
 
   public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
diff --git a/src/main/java/com/techlooper/config/web/sec/SwitchingAuthenticationProvider.java b/src/main/java/com/techlooper/config/web/sec/SwitchingAuthenticationProvider.java
index fab2d7832..aa50e4acc 100644
--- a/src/main/java/com/techlooper/config/web/sec/SwitchingAuthenticationProvider.java
+++ b/src/main/java/com/techlooper/config/web/sec/SwitchingAuthenticationProvider.java
@@ -25,7 +25,7 @@ public Authentication authenticate(Authentication authentication) throws Authent
       }
     }
     catch (Exception ex) {
-      LOGGER.debug(ex.getMessage(), ex);
+      LOGGER.debug(ex.getMessage());
     }
 
     return providers.get(SocialProvider.VIETNAMWORKS).authenticate(authentication);
diff --git a/src/main/java/com/techlooper/controller/UserController.java b/src/main/java/com/techlooper/controller/UserController.java
index 0f56099cd..686429829 100644
--- a/src/main/java/com/techlooper/controller/UserController.java
+++ b/src/main/java/com/techlooper/controller/UserController.java
@@ -317,7 +317,7 @@ public WebinarInfoDto findWebinarById(@PathVariable Long id) {
   }
 
   @RequestMapping(value = "user/webinar/join", method = RequestMethod.POST)
-  public WebinarInfoDto joinWebinar(@RequestBody JoinBySocialDto joinBySocialDto) {
+  public WebinarInfoDto joinWebinar(@RequestBody JoinBySocialDto joinBySocialDto) throws IOException {
     return webinarService.joinWebinar(joinBySocialDto);
   }
 }
diff --git a/src/main/java/com/techlooper/entity/CalendarInfo.java b/src/main/java/com/techlooper/entity/CalendarInfo.java
new file mode 100644
index 000000000..9d9112878
--- /dev/null
+++ b/src/main/java/com/techlooper/entity/CalendarInfo.java
@@ -0,0 +1,39 @@
+package com.techlooper.entity;
+
+import java.io.Serializable;
+
+/**
+ * Created by phuonghqh on 8/27/15.
+ */
+public class CalendarInfo implements Serializable {
+
+  private String id;
+
+  private String htmlLink;
+
+  private String hangoutLink;
+
+  public String getId() {
+    return id;
+  }
+
+  public void setId(String id) {
+    this.id = id;
+  }
+
+  public String getHtmlLink() {
+    return htmlLink;
+  }
+
+  public void setHtmlLink(String htmlLink) {
+    this.htmlLink = htmlLink;
+  }
+
+  public String getHangoutLink() {
+    return hangoutLink;
+  }
+
+  public void setHangoutLink(String hangoutLink) {
+    this.hangoutLink = hangoutLink;
+  }
+}
diff --git a/src/main/java/com/techlooper/entity/WebinarEntity.java b/src/main/java/com/techlooper/entity/WebinarEntity.java
index 2d85874cf..b4ebfe548 100644
--- a/src/main/java/com/techlooper/entity/WebinarEntity.java
+++ b/src/main/java/com/techlooper/entity/WebinarEntity.java
@@ -37,15 +37,29 @@ public class WebinarEntity {
   @Field(type = FieldType.String, index = FieldIndex.not_analyzed)
   private String where = "Google Hangout";
 
-  @Field(type = FieldType.String, index = FieldIndex.not_analyzed)
-  private String calendarUrl;
+  @Field(type = FieldType.Nested)
+  private CalendarInfo calendarInfo;
 
-  @Field(type = FieldType.String, index = FieldIndex.not_analyzed)
-  private String hangoutLink;
+//  @Field(type = FieldType.String, index = FieldIndex.not_analyzed)
+//  private String calendarUrl;
+//
+//  @Field(type = FieldType.String, index = FieldIndex.not_analyzed)
+//  private String hangoutLink;
+//
+//  @Field(type = FieldType.String, index = FieldIndex.not_analyzed)
+//  private String eventId;
 
   @Field(type = FieldType.String)
   private String whatEvent;
 
+  public CalendarInfo getCalendarInfo() {
+    return calendarInfo;
+  }
+
+  public void setCalendarInfo(CalendarInfo calendarInfo) {
+    this.calendarInfo = calendarInfo;
+  }
+
   public Long getCreatedDateTime() {
     return createdDateTime;
   }
@@ -110,22 +124,6 @@ public void setWhere(String where) {
     this.where = where;
   }
 
-  public String getCalendarUrl() {
-    return calendarUrl;
-  }
-
-  public void setCalendarUrl(String calendarUrl) {
-    this.calendarUrl = calendarUrl;
-  }
-
-  public String getHangoutLink() {
-    return hangoutLink;
-  }
-
-  public void setHangoutLink(String hangoutLink) {
-    this.hangoutLink = hangoutLink;
-  }
-
   public String getWhatEvent() {
     return whatEvent;
   }
diff --git a/src/main/java/com/techlooper/model/SocialConfig.java b/src/main/java/com/techlooper/model/SocialConfig.java
index dbbd30a7b..4aa60e7f8 100644
--- a/src/main/java/com/techlooper/model/SocialConfig.java
+++ b/src/main/java/com/techlooper/model/SocialConfig.java
@@ -22,6 +22,16 @@ public class SocialConfig {
 
   private String serviceAccountEmail;
 
+  private String calendarId;
+
+  public String getCalendarId() {
+    return calendarId;
+  }
+
+  public void setCalendarId(String calendarId) {
+    this.calendarId = calendarId;
+  }
+
   public String getServiceAccountEmail() {
     return serviceAccountEmail;
   }
diff --git a/src/main/java/com/techlooper/model/UserProfileDto.java b/src/main/java/com/techlooper/model/UserProfileDto.java
index c6c7d37b7..d9b90744f 100644
--- a/src/main/java/com/techlooper/model/UserProfileDto.java
+++ b/src/main/java/com/techlooper/model/UserProfileDto.java
@@ -2,10 +2,12 @@
 
 import com.techlooper.entity.vnw.RoleName;
 
+import java.io.Serializable;
+
 /**
  * Created by NguyenDangKhoa on 7/30/15.
  */
-public class UserProfileDto {
+public class UserProfileDto implements Serializable {
 
   private String username;
 
diff --git a/src/main/java/com/techlooper/service/WebinarService.java b/src/main/java/com/techlooper/service/WebinarService.java
index a5a76ae5e..df26afcd2 100644
--- a/src/main/java/com/techlooper/service/WebinarService.java
+++ b/src/main/java/com/techlooper/service/WebinarService.java
@@ -21,5 +21,5 @@ public interface WebinarService {
 
   WebinarInfoDto findWebinarById(Long id);
 
-  WebinarInfoDto joinWebinar(JoinBySocialDto joinBySocialDto);
+  WebinarInfoDto joinWebinar(JoinBySocialDto joinBySocialDto) throws IOException;
 }
diff --git a/src/main/java/com/techlooper/service/impl/WebinarServiceImpl.java b/src/main/java/com/techlooper/service/impl/WebinarServiceImpl.java
index ce52e1bed..610eaea71 100644
--- a/src/main/java/com/techlooper/service/impl/WebinarServiceImpl.java
+++ b/src/main/java/com/techlooper/service/impl/WebinarServiceImpl.java
@@ -1,13 +1,16 @@
 package com.techlooper.service.impl;
 
 import com.google.api.client.util.DateTime;
+import com.google.api.client.util.Value;
 import com.google.api.services.calendar.Calendar;
 import com.google.api.services.calendar.model.Event;
 import com.google.api.services.calendar.model.EventAttendee;
 import com.google.api.services.calendar.model.EventDateTime;
 import com.techlooper.dto.JoinBySocialDto;
 import com.techlooper.dto.WebinarInfoDto;
+import com.techlooper.entity.CalendarInfo;
 import com.techlooper.entity.WebinarEntity;
+import com.techlooper.model.SocialConfig;
 import com.techlooper.model.UserProfileDto;
 import com.techlooper.repository.elasticsearch.WebinarRepository;
 import com.techlooper.service.CompanyService;
@@ -46,7 +49,8 @@ public class WebinarServiceImpl implements WebinarService {
   @Resource
   private CompanyService companyService;
 
-  private static final String CALENDAR_ID = "techlooperawesome@gmail.com";
+  @Resource
+  private SocialConfig googleSocialConfig;
 
   public WebinarInfoDto createWebinarInfo(WebinarInfoDto webinarInfoDto, UserProfileDto organiser) throws IOException {
 
@@ -67,11 +71,13 @@ public WebinarInfoDto createWebinarInfo(WebinarInfoDto webinarInfoDto, UserProfi
 
     event.setAttendees(Arrays.asList(attendees));
 
-    event = googleCalendar.events().insert(CALENDAR_ID, event).setSendNotifications(true).execute();
+    event = googleCalendar.events().insert(googleSocialConfig.getCalendarId(), event).setSendNotifications(true).execute();
 
     WebinarEntity entity = dozerMapper.map(webinarInfoDto, WebinarEntity.class);
-    entity.setCalendarUrl(event.getHtmlLink());
-    entity.setHangoutLink(event.getHangoutLink());
+    entity.setCalendarInfo(dozerMapper.map(event, CalendarInfo.class));
+//    entity.setEventId(event.getId());
+//    entity.setCalendarUrl(event.getHtmlLink());
+//    entity.setHangoutLink(event.getHangoutLink());
 
     entity.setOrganiser(organiser);
 
@@ -130,10 +136,22 @@ public WebinarInfoDto findWebinarById(Long id) {
     return null;
   }
 
-  public WebinarInfoDto joinWebinar(JoinBySocialDto joinBySocialDto) {
+  public WebinarInfoDto joinWebinar(JoinBySocialDto joinBySocialDto) throws IOException {
     WebinarEntity webinar = webinarRepository.findOne(joinBySocialDto.getId());
+    if (webinar.getAttendees().size() == 100) {
+      return dozerMapper.map(webinar, WebinarInfoDto.class);
+    }
+
     UserProfileDto attendee = dozerMapper.map(joinBySocialDto, UserProfileDto.class);
-    webinar.getAttendees().add(attendee);
+    if (webinar.getAttendees().add(attendee)) {
+      Event event = googleCalendar.events().get(googleSocialConfig.getCalendarId(), webinar.getCalendarInfo().getId()).execute();
+      EventAttendee att = new EventAttendee().setEmail(attendee.getEmail())
+        .setDisplayName(String.format("%s %s", joinBySocialDto.getFirstName(), joinBySocialDto.getLastName()));
+      event.getAttendees().add(att);
+      event = googleCalendar.events().update(googleSocialConfig.getCalendarId(), webinar.getCalendarInfo().getId(), event)
+        .setSendNotifications(true).execute();
+      webinar.setCalendarInfo(dozerMapper.map(event, CalendarInfo.class));
+    }
     return dozerMapper.map(webinarRepository.save(webinar), WebinarInfoDto.class);
   }
 }
diff --git a/src/main/resources/local/socialConfig.json b/src/main/resources/local/socialConfig.json
index a1ce79715..63591a721 100644
--- a/src/main/resources/local/socialConfig.json
+++ b/src/main/resources/local/socialConfig.json
@@ -43,7 +43,8 @@
     "serviceAccountEmail": "339114452335-ndprm0gt8gsl86ek5ganv7767mg2gc89@developer.gserviceaccount.com",
     "apiUrl": {
       "login": "https://accounts.google.com/o/oauth2/auth?scope=email profile&redirect_uri={redirectUri}&response_type=code&client_id={apiKey}"
-    }
+    },
+    "calendarId": "techlooperawesome@gmail.com"
   },
   {
     "provider": "TWITTER",
diff --git a/src/main/resources/local/techlooper.properties b/src/main/resources/local/techlooper.properties
index e1d91e1d4..e6fd7f9af 100644
--- a/src/main/resources/local/techlooper.properties
+++ b/src/main/resources/local/techlooper.properties
@@ -68,4 +68,7 @@ jobAlert.subject.en = Hot Jobs For You
 jobAlert.subject.vi = Vi\u1EC7c L\u00E0m H\u1EA5p D\u1EABn Cho B\u1EA1n
 scheduled.cron.jobAlert = 0 42 15 * * ?
 #This property should be true in only one production server, others should be false
-jobAlert.enable = false
\ No newline at end of file
+jobAlert.enable = false
+
+google.calendar.id = techlooperawesome@gmail.com
+google.calendar.account.user = techlooperawesome@gmail.com
\ No newline at end of file
diff --git a/src/main/resources/production/socialConfig.json b/src/main/resources/production/socialConfig.json
index f5ce4aaf4..d38b1b9d6 100644
--- a/src/main/resources/production/socialConfig.json
+++ b/src/main/resources/production/socialConfig.json
@@ -43,7 +43,8 @@
     "serviceAccountEmail": "339114452335-ndprm0gt8gsl86ek5ganv7767mg2gc89@developer.gserviceaccount.com",
     "apiUrl": {
       "login": "https://accounts.google.com/o/oauth2/auth?scope=email profile&redirect_uri={redirectUri}&response_type=code&client_id={apiKey}"
-    }
+    },
+    "calendarId": "techlooperawesome@gmail.com"
   },
   {
     "provider": "TWITTER",
diff --git a/src/main/resources/staging/socialConfig.json b/src/main/resources/staging/socialConfig.json
index a5731fad1..64a8c0398 100644
--- a/src/main/resources/staging/socialConfig.json
+++ b/src/main/resources/staging/socialConfig.json
@@ -33,7 +33,8 @@
       "users": "https://api.github.com/users/{username}",
       "repos": "https://api.github.com/users/{username}/repos",
       "followers": "https://api.github.com/users/{username}/followers"
-    }
+    },
+    "calendarId": "techlooperawesome@gmail.com"
   },
   {
     "provider": "GOOGLE",

From 83e86c5ca38c02169efbefe579ef9c8a8a2eecef Mon Sep 17 00:00:00 2001
From: johnsonpham <phamthanhtrinh.vt@gmail.com>
Date: Thu, 27 Aug 2015 11:01:16 +0700
Subject: [PATCH 4/7] update translate

---
 src/main/webapp/assets/modules/translation/messages_vi.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/webapp/assets/modules/translation/messages_vi.json b/src/main/webapp/assets/modules/translation/messages_vi.json
index 6906aa162..0c172d05c 100644
--- a/src/main/webapp/assets/modules/translation/messages_vi.json
+++ b/src/main/webapp/assets/modules/translation/messages_vi.json
@@ -679,7 +679,7 @@
   "jobAlertFail" : "Bạn có thể tạo tối đa 5 Thông Báo Việc Làm với địa chỉ email này.",
   "searchAll": "Tìm Ngay",
   "oneSearchAllJobs": "Một lần tìm. Vạn công việc",
-  "postAnEvent": "Tạo Sự Kiện",
+  "postAnEvent": "Đăng Sự Kiện",
   "webinar": "Webinar",
   "allEvents": "Tất cả Sự Kiện",
   "whatDoWeOffer": "Phúc lợi công ty",

From 9b4bd4136b4b9db29c5cdd0b9855dfcbb9885e60 Mon Sep 17 00:00:00 2001
From: johnsonpham <phamthanhtrinh.vt@gmail.com>
Date: Thu, 27 Aug 2015 11:01:57 +0700
Subject: [PATCH 5/7] fix bug for responsive on tablet

---
 .../assets/sass/z-responsive-candidate.sass   | 44 ++++++++++++++++++-
 1 file changed, 42 insertions(+), 2 deletions(-)

diff --git a/src/main/webapp/assets/sass/z-responsive-candidate.sass b/src/main/webapp/assets/sass/z-responsive-candidate.sass
index e3754cc34..2f30ae0dc 100644
--- a/src/main/webapp/assets/sass/z-responsive-candidate.sass
+++ b/src/main/webapp/assets/sass/z-responsive-candidate.sass
@@ -1,4 +1,4 @@
-@media (min-width: 320px) and (max-width: 768px)
+@media (min-width: 320px) and (max-width: 767px)
   .body-content
     padding-bottom: 0
   .navbar
@@ -1703,7 +1703,7 @@
           ul li .select-group
             float: left
             width: 100%
-@media (min-width: 720px) and (max-width: 999px)
+@media (min-width: 768px) and (max-width: 999px)
   .techlooper-homepage
     .main-banner-block
       .main-banner-content
@@ -1736,4 +1736,44 @@
           .time-and-payment-block
             .col-md-4
               float: left
+  .header-site
+    .main-menu-job-seeker-block
+      .main-menu-job-seeker-content
+        ul
+          li
+            a
+              background: transparent !important
+              padding: 5px 0 5px 5px !important
+  .personal-site-container
+    .personal-site-content-detail
+      .job-alert-box .box-content
+        .it-job-corner-content
+          background: transparent
+          .left
+            width: 100%
+            display: inline-block
+            clear: both
+            padding-bottom: 20px
+          .right
+            width: 100%
+            clear: both
+            display: inline-block
+  .content-page-block.event-details-page
+    .content-page-detail
+      .organiser-info
+        .left-content
+          width: 15%
+        .right-content
+          width: 85%
+  .content-page-block.events-page
+    .content-page-detail
+      .events-list-block
+        .events-items
+          .events-item
+            width: 100%
+            margin: 0 20px 0 0
+
+
+
+
 

From a46385b4c5272e9a1cabc2245ee0eb8f5068da80 Mon Sep 17 00:00:00 2001
From: johnsonpham <phamthanhtrinh.vt@gmail.com>
Date: Thu, 27 Aug 2015 11:14:52 +0700
Subject: [PATCH 6/7] update responsive

---
 src/main/webapp/assets/sass/z-responsive-candidate.sass | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/main/webapp/assets/sass/z-responsive-candidate.sass b/src/main/webapp/assets/sass/z-responsive-candidate.sass
index 2f30ae0dc..083673183 100644
--- a/src/main/webapp/assets/sass/z-responsive-candidate.sass
+++ b/src/main/webapp/assets/sass/z-responsive-candidate.sass
@@ -1772,6 +1772,8 @@
           .events-item
             width: 100%
             margin: 0 20px 0 0
+            .right-content
+              width: 70%
 
 
 

From acfff06b0611d871ff226fd7db95e3f4ef2e500e Mon Sep 17 00:00:00 2001
From: Phuong H <phuonghqh@gmail.com>
Date: Thu, 27 Aug 2015 11:21:46 +0700
Subject: [PATCH 7/7] Able to join Google calendar

---
 .../techlooper/config/CoreConfiguration.java  |  2 +-
 .../com/techlooper/entity/WebinarEntity.java  |  7 +++---
 .../com/techlooper/model/SocialConfig.java    | 10 ++++++++
 src/main/resources/local/socialConfig.json    |  3 ++-
 .../resources/local/techlooper.properties     |  3 ---
 .../resources/production/socialConfig.json    |  3 ++-
 src/main/resources/staging/socialConfig.json  |  7 +++---
 src/main/webapp/assets/modules/_appStart.js   | 23 ++++++++++---------
 .../modules/common/joinAnythingService.js     | 17 ++++----------
 9 files changed, 40 insertions(+), 35 deletions(-)

diff --git a/src/main/java/com/techlooper/config/CoreConfiguration.java b/src/main/java/com/techlooper/config/CoreConfiguration.java
index ad145b1d6..cf991efcf 100644
--- a/src/main/java/com/techlooper/config/CoreConfiguration.java
+++ b/src/main/java/com/techlooper/config/CoreConfiguration.java
@@ -420,7 +420,7 @@ public Calendar googleCalendar() throws GeneralSecurityException, IOException {
       .setServiceAccountId(googleConfig.getServiceAccountEmail())
       .setServiceAccountPrivateKeyFromP12File(googleApiAuthResource.getFile())
       .setServiceAccountScopes(Collections.singleton(CalendarScopes.CALENDAR))
-      .setServiceAccountUser(googleConfig.getCalendarId())
+      .setServiceAccountUser(googleConfig.getCalendarOwner())
       .build();
 
     return new Calendar.Builder(transport, jsonFactory, credential)
diff --git a/src/main/java/com/techlooper/entity/WebinarEntity.java b/src/main/java/com/techlooper/entity/WebinarEntity.java
index b4ebfe548..46d7cedf3 100644
--- a/src/main/java/com/techlooper/entity/WebinarEntity.java
+++ b/src/main/java/com/techlooper/entity/WebinarEntity.java
@@ -6,6 +6,7 @@
 
 import java.util.Collection;
 import java.util.Date;
+import java.util.Set;
 
 /**
  * Created by phuonghqh on 8/18/15.
@@ -29,7 +30,7 @@ public class WebinarEntity {
   private String description;
 
   @Field(type = FieldType.Nested)
-  private Collection<UserProfileDto> attendees;
+  private Set<UserProfileDto> attendees;
 
   @Field(type = FieldType.Nested)
   private UserProfileDto organiser;
@@ -100,11 +101,11 @@ public void setDescription(String description) {
     this.description = description;
   }
 
-  public Collection<UserProfileDto> getAttendees() {
+  public Set<UserProfileDto> getAttendees() {
     return attendees;
   }
 
-  public void setAttendees(Collection<UserProfileDto> attendees) {
+  public void setAttendees(Set<UserProfileDto> attendees) {
     this.attendees = attendees;
   }
 
diff --git a/src/main/java/com/techlooper/model/SocialConfig.java b/src/main/java/com/techlooper/model/SocialConfig.java
index 4aa60e7f8..bdc1e12c8 100644
--- a/src/main/java/com/techlooper/model/SocialConfig.java
+++ b/src/main/java/com/techlooper/model/SocialConfig.java
@@ -24,6 +24,16 @@ public class SocialConfig {
 
   private String calendarId;
 
+  private String calendarOwner;
+
+  public String getCalendarOwner() {
+    return calendarOwner;
+  }
+
+  public void setCalendarOwner(String calendarOwner) {
+    this.calendarOwner = calendarOwner;
+  }
+
   public String getCalendarId() {
     return calendarId;
   }
diff --git a/src/main/resources/local/socialConfig.json b/src/main/resources/local/socialConfig.json
index 63591a721..79cf7dd43 100644
--- a/src/main/resources/local/socialConfig.json
+++ b/src/main/resources/local/socialConfig.json
@@ -44,7 +44,8 @@
     "apiUrl": {
       "login": "https://accounts.google.com/o/oauth2/auth?scope=email profile&redirect_uri={redirectUri}&response_type=code&client_id={apiKey}"
     },
-    "calendarId": "techlooperawesome@gmail.com"
+    "calendarId": "3e6ru1tn5lpoi3a98ere9i4fu4@group.calendar.google.com",
+    "calendarOwner": "techlooperawesome@gmail.com"
   },
   {
     "provider": "TWITTER",
diff --git a/src/main/resources/local/techlooper.properties b/src/main/resources/local/techlooper.properties
index e6fd7f9af..ca6e36518 100644
--- a/src/main/resources/local/techlooper.properties
+++ b/src/main/resources/local/techlooper.properties
@@ -69,6 +69,3 @@ jobAlert.subject.vi = Vi\u1EC7c L\u00E0m H\u1EA5p D\u1EABn Cho B\u1EA1n
 scheduled.cron.jobAlert = 0 42 15 * * ?
 #This property should be true in only one production server, others should be false
 jobAlert.enable = false
-
-google.calendar.id = techlooperawesome@gmail.com
-google.calendar.account.user = techlooperawesome@gmail.com
\ No newline at end of file
diff --git a/src/main/resources/production/socialConfig.json b/src/main/resources/production/socialConfig.json
index d38b1b9d6..306054e94 100644
--- a/src/main/resources/production/socialConfig.json
+++ b/src/main/resources/production/socialConfig.json
@@ -44,7 +44,8 @@
     "apiUrl": {
       "login": "https://accounts.google.com/o/oauth2/auth?scope=email profile&redirect_uri={redirectUri}&response_type=code&client_id={apiKey}"
     },
-    "calendarId": "techlooperawesome@gmail.com"
+    "calendarId": "3iahuurbarqql927vhtibk49pc@group.calendar.google.com",
+    "calendarOwner": "techlooperawesome@gmail.com"
   },
   {
     "provider": "TWITTER",
diff --git a/src/main/resources/staging/socialConfig.json b/src/main/resources/staging/socialConfig.json
index 64a8c0398..bdabc3074 100644
--- a/src/main/resources/staging/socialConfig.json
+++ b/src/main/resources/staging/socialConfig.json
@@ -33,8 +33,7 @@
       "users": "https://api.github.com/users/{username}",
       "repos": "https://api.github.com/users/{username}/repos",
       "followers": "https://api.github.com/users/{username}/followers"
-    },
-    "calendarId": "techlooperawesome@gmail.com"
+    }
   },
   {
     "provider": "GOOGLE",
@@ -44,7 +43,9 @@
     "serviceAccountEmail": "339114452335-ndprm0gt8gsl86ek5ganv7767mg2gc89@developer.gserviceaccount.com",
     "apiUrl": {
       "login": "https://accounts.google.com/o/oauth2/auth?scope=email profile&redirect_uri={redirectUri}&response_type=code&client_id={apiKey}"
-    }
+    },
+    "calendarId": "3e6ru1tn5lpoi3a98ere9i4fu4@group.calendar.google.com",
+    "calendarOwner": "techlooperawesome@gmail.com"
   },
   {
     "provider": "TWITTER",
diff --git a/src/main/webapp/assets/modules/_appStart.js b/src/main/webapp/assets/modules/_appStart.js
index 7fb791713..bcdc79775 100644
--- a/src/main/webapp/assets/modules/_appStart.js
+++ b/src/main/webapp/assets/modules/_appStart.js
@@ -2,17 +2,6 @@ techlooper.run(function (shortcutFactory, connectionFactory, loadingBoxFactory,
                          signInService, historyFactory, userService, routerService, $location,
                          utils, $rootScope, $translate, jsonValue, localStorageService, securityService,
                          apiService, resourcesService, seoService, joinAnythingService) {
-  shortcutFactory.initialize();
-  connectionFactory.initialize();
-  loadingBoxFactory.initialize();
-  cleanupFactory.initialize();
-  historyFactory.initialize();
-  routerService.initialize();
-  userService.initialize();
-  securityService.initialize();
-  seoService.initialize();
-  joinAnythingService.initialize();
-
   $rootScope.apiService = apiService;
   $rootScope.resourcesService = resourcesService;
 
@@ -59,4 +48,16 @@ techlooper.run(function (shortcutFactory, connectionFactory, loadingBoxFactory,
   }
 
   $rootScope.today = moment().format(jsonValue.dateFormat);
+
+  //Exec all services
+  shortcutFactory.initialize();
+  connectionFactory.initialize();
+  loadingBoxFactory.initialize();
+  cleanupFactory.initialize();
+  historyFactory.initialize();
+  routerService.initialize();
+  userService.initialize();
+  securityService.initialize();
+  seoService.initialize();
+  joinAnythingService.initialize();
 });
\ No newline at end of file
diff --git a/src/main/webapp/assets/modules/common/joinAnythingService.js b/src/main/webapp/assets/modules/common/joinAnythingService.js
index 6a3145b31..d33d9859d 100644
--- a/src/main/webapp/assets/modules/common/joinAnythingService.js
+++ b/src/main/webapp/assets/modules/common/joinAnythingService.js
@@ -4,34 +4,27 @@ techlooper.factory("joinAnythingService", function (apiService, localStorageServ
     initialize: function () {}
   };
 
-  var email = localStorageService.get("email");
-  if (!email) {
-    $rootScope.$broadcast("joinAnythingWithoutEmail");
-  }
-
   var param = $location.search();
-  if ($.isEmptyObject(param) || !email) {
+  if ($.isEmptyObject(param)) {
     return instance;
   }
 
   var joinAnything = localStorageService.get("joinAnything");
-  var firstName = localStorageService.get("firstName");
-  var lastName = localStorageService.get("lastName");
+  var email = param.email;
+  var firstName = param.firstName;
+  var lastName = param.lastName;
   var id = localStorageService.get("id");
 
   switch (joinAnything) {
     case "webinar":
       apiService.joinWebinar(id, firstName, lastName, email)
         .success(function (webinar) {
-          //var joinEvents = localStorageService.get("joinEvents") || [];
-          //joinEvents.push(id);
-          //localStorageService.set("joinEvents", joinEvents);
           $rootScope.$broadcast("joinAnything", webinar);
         });
       break;
   }
 
-  localStorageService.remove("joinForm");
+  localStorageService.remove("joinAnything");
   localStorageService.remove("id");
 
   return instance;