Skip to content

timeline wall: final fix #6678

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/default.js
Original file line number Diff line number Diff line change
Expand Up @@ -460,5 +460,6 @@ module.exports = {
PLATFORMUI_SITE_URL: 'https://platform-ui.topcoder-dev.com',
TIMELINE: {
REJECTION_EVENT_REASONS: ['Duplicate Event'],
ALLOWED_FILETYPES: ['image/jpeg', 'image/png', 'video/mp4', 'video/x-msvideo', 'video/webm'],
},
};
4 changes: 3 additions & 1 deletion src/shared/components/GUIKit/PhotoVideoPicker/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ function PhotoVideoPicker({
]);
}}
{...options}
accept={['image/jpeg', 'image/png', 'video/mp4', 'video/x-msvideo', 'video/webm']}
maxFiles={3}
>
{({ getRootProps, getInputProps }) => (
<div styleName="wrapper-container">
Expand Down Expand Up @@ -60,7 +62,7 @@ function PhotoVideoPicker({
) : null
}
{
file.length < 3 ? (
file.length <= 3 ? (
<React.Fragment>

<section
Expand Down
19 changes: 18 additions & 1 deletion src/shared/containers/timeline-wall/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ function TimelineWallContainer(props) {
getAvatar,
userAvatars,
pendingApprovals,
uploading,
} = props;

const role = 'Admin User';
Expand Down Expand Up @@ -75,6 +76,15 @@ function TimelineWallContainer(props) {
}
}, [pendingApprovals]);

useEffect(() => {
const target = document.getElementById(`${selectedFilterValue.year}-${selectedFilterValue.month}`);
if (target) {
target.scrollIntoView({ behavior: 'smooth' }, true);
} else {
window.scrollTo({ top: 0, behavior: 'smooth' });
}
}, [selectedFilterValue]);


const deleteEvent = (id) => {
deleteEventById(authToken, id, () => {
Expand All @@ -96,7 +106,7 @@ function TimelineWallContainer(props) {

return (
<div styleName="container">
<div styleName="header">
<div styleName={isAdmin ? 'header header-admin' : 'header'}>
<img src={TopBanner} alt="top-banner" styleName="header-bg hide-mobile" />
<img src={TopBannerMobile} alt="top-banner" styleName="header-bg hide-desktop show-mobile" />

Expand Down Expand Up @@ -153,8 +163,12 @@ function TimelineWallContainer(props) {
createNewEvent={(body) => {
createNewEvent(authToken, body);
}}
onDoneAddEvent={() => {
getTimelineEvents();
}}
getAvatar={getAvatar}
userAvatars={userAvatars}
uploading={uploading}
/>
<React.Fragment>
{
Expand Down Expand Up @@ -185,6 +199,7 @@ TimelineWallContainer.defaultProps = {
auth: null,
isAdmin: false,
loading: false,
uploading: false,
events: [],
userAvatars: {},
pendingApprovals: [],
Expand All @@ -197,6 +212,7 @@ TimelineWallContainer.propTypes = {
auth: PT.shape(),
isAdmin: PT.bool,
loading: PT.bool,
uploading: PT.bool,
events: PT.arrayOf(PT.shape()),
loadUserDetails: PT.func.isRequired,
createNewEvent: PT.func.isRequired,
Expand All @@ -213,6 +229,7 @@ const mapStateToProps = state => ({
},
isAdmin: state.timelineWall.isAdmin,
loading: state.timelineWall.loading,
uploading: state.timelineWall.uploading,
events: state.timelineWall.events,
userAvatars: state.timelineWall.userAvatars,
pendingApprovals: state.timelineWall.pendingApprovals,
Expand Down
24 changes: 17 additions & 7 deletions src/shared/containers/timeline-wall/modal-event-add/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import React from 'react';
import PT from 'prop-types';
import { Modal } from 'topcoder-react-ui-kit';
import IconCloseGreen from 'assets/images/icon-close-green.svg';
import LoadingIndicator from 'components/LoadingIndicator';

import style from './styles.scss';

function ModalEventAdd({ onClose, isAdmin }) {
function ModalEventAdd({ onClose, isAdmin, uploading }) {
return (
<Modal
theme={{ container: style.container, overlay: style.overlay }}
Expand All @@ -15,12 +16,18 @@ function ModalEventAdd({ onClose, isAdmin }) {
<span styleName="text-title">Confirmation</span>
<button styleName="btn-close" onClick={onClose} type="button"><IconCloseGreen /></button>
</div>
<span styleName="text-description">
{
isAdmin ? 'Thank you! Your event was submitted for review. You’ll receive an email once the review is completed'
: 'Thank you! Your event was added to the Timeline Wall.'
}
</span>
{
uploading ? (
<LoadingIndicator />
) : (
<span styleName="text-description">
{
!isAdmin ? 'Thank you! Your event was submitted for review. You’ll receive an email once the review is completed'
: 'Thank you! Your event was added to the Timeline Wall.'
}
</span>
)
}
<div styleName="separator" />
<div styleName="bottom">
<button
Expand All @@ -34,6 +41,7 @@ function ModalEventAdd({ onClose, isAdmin }) {
onClick={onClose}
styleName="btn-primary"
type="button"
disabled={uploading}
>OK
</button>
</div>
Expand All @@ -47,6 +55,7 @@ function ModalEventAdd({ onClose, isAdmin }) {
ModalEventAdd.defaultProps = {
onClose: () => { },
isAdmin: false,
uploading: false,
};

/**
Expand All @@ -55,6 +64,7 @@ ModalEventAdd.defaultProps = {
ModalEventAdd.propTypes = {
onClose: PT.func,
isAdmin: PT.bool,
uploading: PT.bool,
};

export default ModalEventAdd;
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import PhotoVideoItem from 'components/GUIKit/PhotoVideoItem';
import style from './styles.scss';

function ModalPhotoViewer({ onClose, selectedPhoto, photos }) {
const newPhotos = photos.map((photo, index) => ({ ...photo, id: index }));
const [localSelectedPhoto, setLocalSelectedPhoto] = useState(selectedPhoto);
const selectedPhotoObject = useMemo(
() => _.find(photos, { id: localSelectedPhoto }), [localSelectedPhoto],
() => _.find(newPhotos, { id: localSelectedPhoto }), [localSelectedPhoto],
);

return (
Expand Down
6 changes: 5 additions & 1 deletion src/shared/containers/timeline-wall/styles.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@import '~styles/mixins';
@import "~styles/mixins";

.container {
display: flex;
Expand All @@ -19,6 +19,10 @@
}
}

.header-admin {
min-height: 207px;
}

.header-content-1 {
font-family: BarlowCondensed, sans-serif;
font-weight: 500;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ import FormField from 'components/Settings/FormField';
import FormInputDatePicker from 'components/Settings/FormInputDatePicker';
import FormInputTextArea from 'components/Settings/FormInputTextArea';
import PhotoVideoPicker from 'components/GUIKit/PhotoVideoPicker';
import { config } from 'topcoder-react-utils';
import IconCloseGreen from 'assets/images/icon-close-green.svg';
import IconCloseBlack from 'assets/images/tc-edu/icon-close-big.svg';
import ModalEventAdd from '../../modal-event-add';

import style from './styles.scss';

function AddEvents({
className, isAuthenticated, createNewEvent, isAdmin,
className, isAuthenticated, createNewEvent, isAdmin, onDoneAddEvent, uploading,
}) {
const [formData, setFormData] = useState({
eventName: '',
Expand All @@ -31,13 +32,7 @@ function AddEvents({
&& !!formData.description, [formData]);

const submitEvent = () => {
const form = new FormData();
form.append('title', formData.eventName);
form.append('description', formData.description);
form.append('eventDate', formData.date);
form.append('mediaFiles', formData.files || []);

createNewEvent(form);
createNewEvent(formData);

setFormData({
eventName: '',
Expand Down Expand Up @@ -157,6 +152,10 @@ function AddEvents({
infoText={'Drag & drop your photo or video here\nYou can upload only up to 3 photos/videos'}
infoTextMobile="Drag & drop your photo or video here"
btnText="BROWSE"
options={{
accept: config.TIMELINE.ALLOWED_FILETYPES || [],
maxFiles: 3,
}}
/>
</div>

Expand Down Expand Up @@ -190,8 +189,14 @@ function AddEvents({
{
showModal ? (
<ModalEventAdd
onClose={() => setShowModal(false)}
onClose={() => {
setShowModal(false);
if (isAdmin) {
onDoneAddEvent();
}
}}
isAdmin={isAdmin}
uploading={uploading}
/>
) : null
}
Expand All @@ -206,6 +211,7 @@ AddEvents.defaultProps = {
className: '',
isAuthenticated: false,
isAdmin: false,
uploading: false,
};

/**
Expand All @@ -216,6 +222,8 @@ AddEvents.propTypes = {
isAuthenticated: PT.bool,
createNewEvent: PT.func.isRequired,
isAdmin: PT.bool,
onDoneAddEvent: PT.func.isRequired,
uploading: PT.bool,
};

export default AddEvents;
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ function EventItem({
'color-red': eventItem.color === 'red',
'color-purple': eventItem.color === 'purple',
})}
id={moment(eventItem.eventDate).format('YYYY-MM')}
>
{isLeft ? null : (<div styleName="dot dot-left" />)}
{isLeft ? null : (<IconTooltipLeft styleName="tooltip-indicator" />)}
Expand Down Expand Up @@ -105,7 +106,7 @@ function EventItem({
onClose={() => {
setShowModalPhoto(false);
}}
photos={eventItem.media}
photos={eventItem.mediaFiles}
/>
) : null}

Expand Down
45 changes: 14 additions & 31 deletions src/shared/containers/timeline-wall/timeline-events/index.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import React, { useState, useEffect } from 'react';
import React from 'react';
import PT from 'prop-types';
import moment from 'moment';
import _ from 'lodash';
import cn from 'classnames';
import AddEvent from './add-event';
import Events from './events';
Expand All @@ -22,41 +20,23 @@ function TimelineEvents({
createNewEvent,
getAvatar,
userAvatars,
onDoneAddEvent,
uploading,
}) {
const [localEvents, setLocalEvents] = useState([]);

useEffect(() => {
setLocalEvents(_.filter(events, (event) => {
const eventDate = moment(event.eventDate);
if (!selectedFilterValue.year) {
return true;
}
if (eventDate.year() !== selectedFilterValue.year) {
return false;
}
if (selectedFilterValue.month < 0) {
return true;
}
if (eventDate.month() !== selectedFilterValue.month) {
return false;
}

return true;
}));
}, [events, selectedFilterValue]);

return (
<div className={className} styleName="container">
<div styleName="left-content">
<AddEvent
events={localEvents}
events={events}
isAuthenticated={isAuthenticated}
createNewEvent={createNewEvent}
isAdmin={isAdmin}
onDoneAddEvent={onDoneAddEvent}
uploading={uploading}
/>
{localEvents.length ? (
{events.length ? (
<Events
events={localEvents}
events={events}
isAdmin={isAdmin}
isAuthenticated={isAuthenticated}
removeEvent={(event) => {
Expand All @@ -67,15 +47,15 @@ function TimelineEvents({
/>
)
: null}
{!localEvents.length && !!events.length && selectedFilterValue.month < 0 ? (
{!events.length && !!events.length && selectedFilterValue.month < 0 ? (
<span styleName="text-empty-result">No events have been added for this year. Be the first who adds one.</span>
)
: null}
{!localEvents.length && !!events.length && selectedFilterValue.month >= 0 ? (
{!events.length && !!events.length && selectedFilterValue.month >= 0 ? (
<span styleName="text-empty-result">No events have been added for this month. Be the first who adds one.</span>
)
: null}
{!localEvents.length && !events.length ? (
{!events.length && !events.length ? (
<span styleName="text-empty-result">No events have been added. Be the first who adds one.</span>
)
: null}
Expand Down Expand Up @@ -111,6 +91,7 @@ TimelineEvents.defaultProps = {
isAuthenticated: false,
isAdmin: false,
userAvatars: {},
uploading: false,
};

/**
Expand All @@ -128,7 +109,9 @@ TimelineEvents.propTypes = {
isAdmin: PT.bool,
createNewEvent: PT.func.isRequired,
getAvatar: PT.func.isRequired,
onDoneAddEvent: PT.func.isRequired,
userAvatars: PT.shape(),
uploading: PT.bool,
};

export default TimelineEvents;
Loading