Skip to content
Snippets Groups Projects
Unverified Commit 286db6be authored by alihadi-mazeh's avatar alihadi-mazeh Committed by GitHub
Browse files

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
parent a6f72267
Branches
Tags
No related merge requests found
...@@ -9,6 +9,7 @@ import { ...@@ -9,6 +9,7 @@ import {
EllipsisVerticalIcon, HomeIcon, PencilSquareIcon, TrashIcon, NoSymbolIcon, EllipsisVerticalIcon, HomeIcon, PencilSquareIcon, TrashIcon, NoSymbolIcon,
} from '@heroicons/react/24/outline'; } from '@heroicons/react/24/outline';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { localizeDateTimeString } from '../../../helpers/DateTimeHelper';
import Avatar from '../../users/user/Avatar'; import Avatar from '../../users/user/Avatar';
import Modal from '../../shared_components/modals/Modal'; import Modal from '../../shared_components/modals/Modal';
import CreateRoomForm from '../../rooms/room/forms/CreateRoomForm'; import CreateRoomForm from '../../rooms/room/forms/CreateRoomForm';
...@@ -21,6 +22,7 @@ export default function ManageUserRow({ user }) { ...@@ -21,6 +22,7 @@ export default function ManageUserRow({ user }) {
const { t } = useTranslation(); const { t } = useTranslation();
const mutationWrapper = (args) => useCreateServerRoom({ userId: user.id, ...args }); const mutationWrapper = (args) => useCreateServerRoom({ userId: user.id, ...args });
const updateUserStatus = useUpdateUserStatus(); const updateUserStatus = useUpdateUserStatus();
const localizedTime = localizeDateTimeString(user?.created_at, user?.language);
return ( return (
<tr key={user.id} className="align-middle text-muted border border-2"> <tr key={user.id} className="align-middle text-muted border border-2">
...@@ -31,7 +33,7 @@ export default function ManageUserRow({ user }) { ...@@ -31,7 +33,7 @@ export default function ManageUserRow({ user }) {
</div> </div>
<Stack> <Stack>
<span className="text-dark fw-bold"> {user.name} </span> <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>
</Stack> </Stack>
</td> </td>
...@@ -73,6 +75,7 @@ ManageUserRow.propTypes = { ...@@ -73,6 +75,7 @@ ManageUserRow.propTypes = {
avatar: PropTypes.string.isRequired, avatar: PropTypes.string.isRequired,
name: PropTypes.string.isRequired, name: PropTypes.string.isRequired,
email: PropTypes.string.isRequired, email: PropTypes.string.isRequired,
language: PropTypes.string.isRequired,
provider: PropTypes.string.isRequired, provider: PropTypes.string.isRequired,
role: PropTypes.shape({ role: PropTypes.shape({
id: PropTypes.string.isRequired, id: PropTypes.string.isRequired,
......
...@@ -13,6 +13,7 @@ import useStartMeeting from '../../../hooks/mutations/rooms/useStartMeeting'; ...@@ -13,6 +13,7 @@ import useStartMeeting from '../../../hooks/mutations/rooms/useStartMeeting';
import useRoomStatus from '../../../hooks/mutations/rooms/useRoomStatus'; import useRoomStatus from '../../../hooks/mutations/rooms/useRoomStatus';
import { useAuth } from '../../../contexts/auth/AuthProvider'; import { useAuth } from '../../../contexts/auth/AuthProvider';
import useRecordingsReSync from '../../../hooks/mutations/admin/server_recordings/useRecordingsReSync'; import useRecordingsReSync from '../../../hooks/mutations/admin/server_recordings/useRecordingsReSync';
import { localizeDateTimeString } from '../../../helpers/DateTimeHelper';
export default function ServerRoomRow({ room }) { export default function ServerRoomRow({ room }) {
const { const {
...@@ -24,6 +25,7 @@ export default function ServerRoomRow({ room }) { ...@@ -24,6 +25,7 @@ export default function ServerRoomRow({ room }) {
const currentUser = useAuth(); const currentUser = useAuth();
const roomStatusAPI = useRoomStatus(friendlyId); const roomStatusAPI = useRoomStatus(friendlyId);
const recordingsResyncAPI = useRecordingsReSync(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 // 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 }); const handleJoin = () => roomStatusAPI.mutate({ name: currentUser.name });
...@@ -35,7 +37,7 @@ export default function ServerRoomRow({ room }) { ...@@ -35,7 +37,7 @@ export default function ServerRoomRow({ room }) {
if (online) { if (online) {
return t('admin.server_rooms.current_session', { lastSession }); return t('admin.server_rooms.current_session', { lastSession });
} }
return t('admin.server_rooms.last_session', { lastSession }); return (localizedTime);
}; };
const meetingRunning = () => { const meetingRunning = () => {
......
...@@ -9,10 +9,12 @@ import { ...@@ -9,10 +9,12 @@ import {
} from 'react-bootstrap'; } from 'react-bootstrap';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useAuth } from '../../contexts/auth/AuthProvider';
import Spinner from '../shared_components/utilities/Spinner'; import Spinner from '../shared_components/utilities/Spinner';
import UpdateRecordingForm from './forms/UpdateRecordingForm'; import UpdateRecordingForm from './forms/UpdateRecordingForm';
import DeleteRecordingForm from './forms/DeleteRecordingForm'; import DeleteRecordingForm from './forms/DeleteRecordingForm';
import Modal from '../shared_components/modals/Modal'; import Modal from '../shared_components/modals/Modal';
import { localizeDateTimeString } from '../../helpers/DateTimeHelper';
// TODO: Amir - Refactor this. // TODO: Amir - Refactor this.
export default function RecordingRow({ export default function RecordingRow({
...@@ -29,6 +31,8 @@ export default function RecordingRow({ ...@@ -29,6 +31,8 @@ export default function RecordingRow({
const visibilityAPI = useVisibilityAPI(); const visibilityAPI = useVisibilityAPI();
const [isEditing, setIsEditing] = useState(false); const [isEditing, setIsEditing] = useState(false);
const [isUpdating, setIsUpdating] = useState(false); const [isUpdating, setIsUpdating] = useState(false);
const currentUser = useAuth();
const localizedTime = localizeDateTimeString(recording?.created_at, currentUser?.language);
return ( return (
<tr key={recording.id} className="align-middle text-muted border border-2"> <tr key={recording.id} className="align-middle text-muted border border-2">
...@@ -66,7 +70,7 @@ export default function RecordingRow({ ...@@ -66,7 +70,7 @@ export default function RecordingRow({
isUpdating && <Spinner animation="grow" variant="brand" /> isUpdating && <Spinner animation="grow" variant="brand" />
} }
</strong> </strong>
<span className="small text-muted"> {recording.created_at} </span> <span className="small text-muted"> {localizedTime} </span>
</Stack> </Stack>
</Stack> </Stack>
</td> </td>
......
...@@ -5,6 +5,8 @@ import PropTypes from 'prop-types'; ...@@ -5,6 +5,8 @@ import PropTypes from 'prop-types';
import { DocumentDuplicateIcon, LinkIcon } from '@heroicons/react/24/outline'; import { DocumentDuplicateIcon, LinkIcon } from '@heroicons/react/24/outline';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useAuth } from '../../contexts/auth/AuthProvider';
import { localizeDateTimeString } from '../../helpers/DateTimeHelper';
import Spinner from '../shared_components/utilities/Spinner'; import Spinner from '../shared_components/utilities/Spinner';
import useStartMeeting from '../../hooks/mutations/rooms/useStartMeeting'; import useStartMeeting from '../../hooks/mutations/rooms/useStartMeeting';
import MeetingBadges from './MeetingBadges'; import MeetingBadges from './MeetingBadges';
...@@ -15,6 +17,8 @@ export default function RoomCard({ room }) { ...@@ -15,6 +17,8 @@ export default function RoomCard({ room }) {
const navigate = useNavigate(); const navigate = useNavigate();
const handleClick = useCallback(() => { navigate(room.friendly_id); }, [room.friendly_id]); const handleClick = useCallback(() => { navigate(room.friendly_id); }, [room.friendly_id]);
const startMeeting = useStartMeeting(room.friendly_id); const startMeeting = useStartMeeting(room.friendly_id);
const currentUser = useAuth();
const localizedTime = localizeDateTimeString(room?.last_session, currentUser?.language);
function copyInvite(friendlyId) { function copyInvite(friendlyId) {
navigator.clipboard.writeText(`${window.location}/${friendlyId}/join`); navigator.clipboard.writeText(`${window.location}/${friendlyId}/join`);
...@@ -40,7 +44,7 @@ export default function RoomCard({ room }) { ...@@ -40,7 +44,7 @@ export default function RoomCard({ room }) {
<span className="text-muted">{ t('room.shared_by') } <strong>{ room.shared_owner }</strong></span> <span className="text-muted">{ t('room.shared_by') } <strong>{ room.shared_owner }</strong></span>
)} )}
{ room.last_session ? ( { 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> <span className="text-muted mt-2"> { t('room.no_last_session') } </span>
)} )}
......
...@@ -8,6 +8,8 @@ import { ...@@ -8,6 +8,8 @@ import {
import { HomeIcon, Square2StackIcon } from '@heroicons/react/24/outline'; import { HomeIcon, Square2StackIcon } from '@heroicons/react/24/outline';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useAuth } from '../../../contexts/auth/AuthProvider';
import { localizeDayDateTimeString } from '../../../helpers/DateTimeHelper';
import FeatureTabs from './FeatureTabs'; import FeatureTabs from './FeatureTabs';
import Spinner from '../../shared_components/utilities/Spinner'; import Spinner from '../../shared_components/utilities/Spinner';
import useRoom from '../../../hooks/queries/rooms/useRoom'; import useRoom from '../../../hooks/queries/rooms/useRoom';
...@@ -23,7 +25,9 @@ export default function Room() { ...@@ -23,7 +25,9 @@ export default function Room() {
isLoading, isError, data: room, error, isLoading, isError, data: room, error,
} = useRoom(friendlyId); } = useRoom(friendlyId);
const startMeeting = useStartMeeting(friendlyId); const startMeeting = useStartMeeting(friendlyId);
const currentUser = useAuth();
const location = useLocation(); const location = useLocation();
const localizedTime = localizeDayDateTimeString(room?.last_session, currentUser?.language);
function copyInvite() { function copyInvite() {
navigator.clipboard.writeText(`${window.location}/join`); navigator.clipboard.writeText(`${window.location}/join`);
...@@ -62,7 +66,7 @@ export default function Room() { ...@@ -62,7 +66,7 @@ export default function Room() {
</Stack> </Stack>
</Stack> </Stack>
{ room?.last_session ? ( { 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> <span className="text-muted"> { t('room.no_last_session') } </span>
)} )}
......
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);
}
# frozen_string_literal: true # frozen_string_literal: true
class ApplicationSerializer < ActiveModel::Serializer 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 end
...@@ -15,10 +15,6 @@ class CurrentRoomSerializer < ApplicationSerializer ...@@ -15,10 +15,6 @@ class CurrentRoomSerializer < ApplicationSerializer
presentation_thumbnail(object) presentation_thumbnail(object)
end end
def last_session
object.last_session.strftime('%B %e, %Y %l:%M%P')
end
def owner_name def owner_name
object.user.name object.user.name
end end
......
...@@ -8,8 +8,4 @@ class RoomSerializer < ApplicationSerializer ...@@ -8,8 +8,4 @@ class RoomSerializer < ApplicationSerializer
def shared_owner def shared_owner
object.user.name object.user.name
end end
def last_session
object.last_session&.strftime('%B %e, %Y %l:%M%P')
end
end end
...@@ -6,8 +6,4 @@ class ServerRoomSerializer < RoomSerializer ...@@ -6,8 +6,4 @@ class ServerRoomSerializer < RoomSerializer
def owner def owner
object.user.name object.user.name
end end
def last_session
object.last_session&.strftime('%A %B %e, %Y %l:%M%P')
end
end end
...@@ -10,8 +10,4 @@ class UserSerializer < ApplicationSerializer ...@@ -10,8 +10,4 @@ class UserSerializer < ApplicationSerializer
def avatar def avatar
user_avatar(object) user_avatar(object)
end end
def created_at
object.created_at.strftime('%A %B %e, %Y')
end
end end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment