From 286db6beafbad752ae0df6efe6699e76e179f6b3 Mon Sep 17 00:00:00 2001
From: alihadi-mazeh <113048174+alihadi-mazeh@users.noreply.github.com>
Date: Mon, 6 Feb 2023 18:48:22 +0000
Subject: [PATCH] Time and Dates Localized (#4748)

* Time and Dates Localized

* created new file: TimeDateHelper.jsx for helper functions for localizing dates and time

* Simplified helper function
---
 .../admin/manage_users/ManageUserRow.jsx          |  5 ++++-
 .../admin/server_rooms/ServerRoomRow.jsx          |  4 +++-
 .../components/recordings/RecordingRow.jsx        |  6 +++++-
 app/javascript/components/rooms/RoomCard.jsx      |  6 +++++-
 app/javascript/components/rooms/room/Room.jsx     |  6 +++++-
 app/javascript/helpers/DateTimeHelper.jsx         | 15 +++++++++++++++
 app/serializers/application_serializer.rb         |  7 -------
 app/serializers/current_room_serializer.rb        |  4 ----
 app/serializers/room_serializer.rb                |  4 ----
 app/serializers/server_room_serializer.rb         |  4 ----
 app/serializers/user_serializer.rb                |  4 ----
 11 files changed, 37 insertions(+), 28 deletions(-)
 create mode 100644 app/javascript/helpers/DateTimeHelper.jsx

diff --git a/app/javascript/components/admin/manage_users/ManageUserRow.jsx b/app/javascript/components/admin/manage_users/ManageUserRow.jsx
index fe3b15f6..8b036cba 100644
--- a/app/javascript/components/admin/manage_users/ManageUserRow.jsx
+++ b/app/javascript/components/admin/manage_users/ManageUserRow.jsx
@@ -9,6 +9,7 @@ import {
   EllipsisVerticalIcon, HomeIcon, PencilSquareIcon, TrashIcon, NoSymbolIcon,
 } from '@heroicons/react/24/outline';
 import { useTranslation } from 'react-i18next';
+import { localizeDateTimeString } from '../../../helpers/DateTimeHelper';
 import Avatar from '../../users/user/Avatar';
 import Modal from '../../shared_components/modals/Modal';
 import CreateRoomForm from '../../rooms/room/forms/CreateRoomForm';
@@ -21,6 +22,7 @@ export default function ManageUserRow({ user }) {
   const { t } = useTranslation();
   const mutationWrapper = (args) => useCreateServerRoom({ userId: user.id, ...args });
   const updateUserStatus = useUpdateUserStatus();
+  const localizedTime = localizeDateTimeString(user?.created_at, user?.language);
 
   return (
     <tr key={user.id} className="align-middle text-muted border border-2">
@@ -31,7 +33,7 @@ export default function ManageUserRow({ user }) {
           </div>
           <Stack>
             <span className="text-dark fw-bold"> {user.name} </span>
-            <span className="small"> { t('admin.manage_users.user_created_at', { user }) }</span>
+            <span className="small"> { localizedTime }</span>
           </Stack>
         </Stack>
       </td>
@@ -73,6 +75,7 @@ ManageUserRow.propTypes = {
     avatar: PropTypes.string.isRequired,
     name: PropTypes.string.isRequired,
     email: PropTypes.string.isRequired,
+    language: PropTypes.string.isRequired,
     provider: PropTypes.string.isRequired,
     role: PropTypes.shape({
       id: PropTypes.string.isRequired,
diff --git a/app/javascript/components/admin/server_rooms/ServerRoomRow.jsx b/app/javascript/components/admin/server_rooms/ServerRoomRow.jsx
index 5ecddf38..8b42589a 100644
--- a/app/javascript/components/admin/server_rooms/ServerRoomRow.jsx
+++ b/app/javascript/components/admin/server_rooms/ServerRoomRow.jsx
@@ -13,6 +13,7 @@ import useStartMeeting from '../../../hooks/mutations/rooms/useStartMeeting';
 import useRoomStatus from '../../../hooks/mutations/rooms/useRoomStatus';
 import { useAuth } from '../../../contexts/auth/AuthProvider';
 import useRecordingsReSync from '../../../hooks/mutations/admin/server_recordings/useRecordingsReSync';
+import { localizeDateTimeString } from '../../../helpers/DateTimeHelper';
 
 export default function ServerRoomRow({ room }) {
   const {
@@ -24,6 +25,7 @@ export default function ServerRoomRow({ room }) {
   const currentUser = useAuth();
   const roomStatusAPI = useRoomStatus(friendlyId);
   const recordingsResyncAPI = useRecordingsReSync(friendlyId);
+  const localizedTime = localizeDateTimeString(room?.last_session, currentUser?.language);
 
   // TODO - samuel: useRoomStatus will not work if room has an access code. Will need to add bypass in MeetingController
   const handleJoin = () => roomStatusAPI.mutate({ name: currentUser.name });
@@ -35,7 +37,7 @@ export default function ServerRoomRow({ room }) {
     if (online) {
       return t('admin.server_rooms.current_session', { lastSession });
     }
-    return t('admin.server_rooms.last_session', { lastSession });
+    return (localizedTime);
   };
 
   const meetingRunning = () => {
diff --git a/app/javascript/components/recordings/RecordingRow.jsx b/app/javascript/components/recordings/RecordingRow.jsx
index 0d137b95..97b37d80 100644
--- a/app/javascript/components/recordings/RecordingRow.jsx
+++ b/app/javascript/components/recordings/RecordingRow.jsx
@@ -9,10 +9,12 @@ import {
 } from 'react-bootstrap';
 import { toast } from 'react-toastify';
 import { useTranslation } from 'react-i18next';
+import { useAuth } from '../../contexts/auth/AuthProvider';
 import Spinner from '../shared_components/utilities/Spinner';
 import UpdateRecordingForm from './forms/UpdateRecordingForm';
 import DeleteRecordingForm from './forms/DeleteRecordingForm';
 import Modal from '../shared_components/modals/Modal';
+import { localizeDateTimeString } from '../../helpers/DateTimeHelper';
 
 // TODO: Amir - Refactor this.
 export default function RecordingRow({
@@ -29,6 +31,8 @@ export default function RecordingRow({
   const visibilityAPI = useVisibilityAPI();
   const [isEditing, setIsEditing] = useState(false);
   const [isUpdating, setIsUpdating] = useState(false);
+  const currentUser = useAuth();
+  const localizedTime = localizeDateTimeString(recording?.created_at, currentUser?.language);
 
   return (
     <tr key={recording.id} className="align-middle text-muted border border-2">
@@ -66,7 +70,7 @@ export default function RecordingRow({
                 isUpdating && <Spinner animation="grow" variant="brand" />
               }
             </strong>
-            <span className="small text-muted"> {recording.created_at} </span>
+            <span className="small text-muted"> {localizedTime} </span>
           </Stack>
         </Stack>
       </td>
diff --git a/app/javascript/components/rooms/RoomCard.jsx b/app/javascript/components/rooms/RoomCard.jsx
index 3cdf3f2d..fd2d7f3c 100644
--- a/app/javascript/components/rooms/RoomCard.jsx
+++ b/app/javascript/components/rooms/RoomCard.jsx
@@ -5,6 +5,8 @@ import PropTypes from 'prop-types';
 import { DocumentDuplicateIcon, LinkIcon } from '@heroicons/react/24/outline';
 import { toast } from 'react-toastify';
 import { useTranslation } from 'react-i18next';
+import { useAuth } from '../../contexts/auth/AuthProvider';
+import { localizeDateTimeString } from '../../helpers/DateTimeHelper';
 import Spinner from '../shared_components/utilities/Spinner';
 import useStartMeeting from '../../hooks/mutations/rooms/useStartMeeting';
 import MeetingBadges from './MeetingBadges';
@@ -15,6 +17,8 @@ export default function RoomCard({ room }) {
   const navigate = useNavigate();
   const handleClick = useCallback(() => { navigate(room.friendly_id); }, [room.friendly_id]);
   const startMeeting = useStartMeeting(room.friendly_id);
+  const currentUser = useAuth();
+  const localizedTime = localizeDateTimeString(room?.last_session, currentUser?.language);
 
   function copyInvite(friendlyId) {
     navigator.clipboard.writeText(`${window.location}/${friendlyId}/join`);
@@ -40,7 +44,7 @@ export default function RoomCard({ room }) {
             <span className="text-muted">{ t('room.shared_by') } <strong>{ room.shared_owner }</strong></span>
           )}
           { room.last_session ? (
-            <span className="text-muted"> { t('room.last_session', { room }) } </span>
+            <span className="text-muted"> { localizedTime} </span>
           ) : (
             <span className="text-muted mt-2"> { t('room.no_last_session') } </span>
           )}
diff --git a/app/javascript/components/rooms/room/Room.jsx b/app/javascript/components/rooms/room/Room.jsx
index ca8ec8c1..7f30a272 100644
--- a/app/javascript/components/rooms/room/Room.jsx
+++ b/app/javascript/components/rooms/room/Room.jsx
@@ -8,6 +8,8 @@ import {
 import { HomeIcon, Square2StackIcon } from '@heroicons/react/24/outline';
 import { toast } from 'react-toastify';
 import { useTranslation } from 'react-i18next';
+import { useAuth } from '../../../contexts/auth/AuthProvider';
+import { localizeDayDateTimeString } from '../../../helpers/DateTimeHelper';
 import FeatureTabs from './FeatureTabs';
 import Spinner from '../../shared_components/utilities/Spinner';
 import useRoom from '../../../hooks/queries/rooms/useRoom';
@@ -23,7 +25,9 @@ export default function Room() {
     isLoading, isError, data: room, error,
   } = useRoom(friendlyId);
   const startMeeting = useStartMeeting(friendlyId);
+  const currentUser = useAuth();
   const location = useLocation();
+  const localizedTime = localizeDayDateTimeString(room?.last_session, currentUser?.language);
 
   function copyInvite() {
     navigator.clipboard.writeText(`${window.location}/join`);
@@ -62,7 +66,7 @@ export default function Room() {
                         </Stack>
                       </Stack>
                       { room?.last_session ? (
-                        <span className="text-muted"> { t('room.last_session', { room }) }  </span>
+                        <span className="text-muted"> { localizedTime}  </span>
                       ) : (
                         <span className="text-muted"> { t('room.no_last_session') } </span>
                       )}
diff --git a/app/javascript/helpers/DateTimeHelper.jsx b/app/javascript/helpers/DateTimeHelper.jsx
new file mode 100644
index 00000000..32610b06
--- /dev/null
+++ b/app/javascript/helpers/DateTimeHelper.jsx
@@ -0,0 +1,15 @@
+export function localizeDateTimeString(time, language) {
+  const options = {
+    year: 'numeric', month: 'long', day: 'numeric', hour: 'numeric', minute: 'numeric',
+  };
+  const event = new Date(time);
+  return event.toLocaleDateString(language, options);
+}
+
+export function localizeDayDateTimeString(time, language) {
+  const options = {
+    weekday: 'long', year: 'numeric', month: 'long', day: 'numeric', hour: 'numeric', minute: 'numeric',
+  };
+  const event = new Date(time);
+  return event.toLocaleDateString(language, options);
+}
diff --git a/app/serializers/application_serializer.rb b/app/serializers/application_serializer.rb
index 2da502a3..589d6342 100644
--- a/app/serializers/application_serializer.rb
+++ b/app/serializers/application_serializer.rb
@@ -1,11 +1,4 @@
 # frozen_string_literal: true
 
 class ApplicationSerializer < ActiveModel::Serializer
-  def created_at
-    object.created_at.strftime('%A %B %e, %Y %l:%M%P')
-  end
-
-  def updated_at
-    object.updated_at.strftime('%A %B %e, %Y %l:%M%P')
-  end
 end
diff --git a/app/serializers/current_room_serializer.rb b/app/serializers/current_room_serializer.rb
index 7f29ef5c..97e0f98a 100644
--- a/app/serializers/current_room_serializer.rb
+++ b/app/serializers/current_room_serializer.rb
@@ -15,10 +15,6 @@ class CurrentRoomSerializer < ApplicationSerializer
     presentation_thumbnail(object)
   end
 
-  def last_session
-    object.last_session.strftime('%B %e, %Y %l:%M%P')
-  end
-
   def owner_name
     object.user.name
   end
diff --git a/app/serializers/room_serializer.rb b/app/serializers/room_serializer.rb
index 2533779f..ab039dc7 100644
--- a/app/serializers/room_serializer.rb
+++ b/app/serializers/room_serializer.rb
@@ -8,8 +8,4 @@ class RoomSerializer < ApplicationSerializer
   def shared_owner
     object.user.name
   end
-
-  def last_session
-    object.last_session&.strftime('%B %e, %Y %l:%M%P')
-  end
 end
diff --git a/app/serializers/server_room_serializer.rb b/app/serializers/server_room_serializer.rb
index f95aa75b..ac0eea8e 100644
--- a/app/serializers/server_room_serializer.rb
+++ b/app/serializers/server_room_serializer.rb
@@ -6,8 +6,4 @@ class ServerRoomSerializer < RoomSerializer
   def owner
     object.user.name
   end
-
-  def last_session
-    object.last_session&.strftime('%A %B %e, %Y %l:%M%P')
-  end
 end
diff --git a/app/serializers/user_serializer.rb b/app/serializers/user_serializer.rb
index 3566a89d..6097971d 100644
--- a/app/serializers/user_serializer.rb
+++ b/app/serializers/user_serializer.rb
@@ -10,8 +10,4 @@ class UserSerializer < ApplicationSerializer
   def avatar
     user_avatar(object)
   end
-
-  def created_at
-    object.created_at.strftime('%A %B %e, %Y')
-  end
 end
-- 
GitLab