Skip to content
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
6 changes: 4 additions & 2 deletions apps/www/components/adminQuestions/AdminQuestions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useDispatch, useSelector } from 'react-redux';

import spinnerStyles from '../../components/layout/appSpinner.module.scss';
import { TechnologyKey } from '../../constants/technology-icon-items';
import { useUIContext } from '../../contexts/UIContextProvider';
import { ActionCreators } from '../../redux/actions';
import { Question } from '../../redux/reducers/questions';
import { Container } from '../container/Container';
Expand All @@ -25,6 +26,7 @@ const EmptyAdminQuestions = memo(({ questions }: { questions?: Question[] }) =>
});

const AdminQuestions = memo(() => {
const { openEditQuestionModal } = useUIContext();
const [status, setStatus] = useState<'pending' | 'accepted'>('pending');
const [technology] = useState<TechnologyKey | undefined>(undefined);

Expand Down Expand Up @@ -74,9 +76,9 @@ const AdminQuestions = memo(() => {
return;
}

dispatch(ActionCreators.uiOpenEditQuestionModal(question, onEditFinished));
openEditQuestionModal(question, onEditFinished);
},
[dispatch, onEditFinished, questions.data]
[onEditFinished, openEditQuestionModal, questions.data]
);

const updateStatus: React.ChangeEventHandler<HTMLSelectElement> = useCallback((e) => {
Expand Down
133 changes: 66 additions & 67 deletions apps/www/components/headers/ctaHeader/CtaHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import classNames from 'classnames';
import React, { memo } from 'react';
import { connect } from 'react-redux';

import { ActionCreators } from '../../../redux/actions';
import { useUIContext } from '../../../contexts/UIContextProvider';
import { AppState } from '../../../redux/reducers/index';
import {
getAreAnyQuestionSelected,
Expand All @@ -14,59 +14,61 @@ import { Container } from '../../container/Container';

import styles from './ctaHeader.module.scss';

export const CtaHeaderComponent: React.FC<
ReturnType<typeof mapStateToProps> & typeof mapDispatchToProps
> = memo(({ uiOpenAddQuestionModal, areAnyQuestionSelected, isAdmin }) => {
const onDownloadClick: React.MouseEventHandler<HTMLElement> = (_event) => {
reportEvent('Pobierz plik PDF');
// @todo open DownloadSuccessModal
// @todo this.analyticsService.reportPdfDownload(this.selectedQuestionsService.getSelectedIds());
};
export const CtaHeaderComponent: React.FC<ReturnType<typeof mapStateToProps>> = memo(
({ areAnyQuestionSelected, isAdmin }) => {
const { openAddQuestionModal } = useUIContext();
const onDownloadClick: React.MouseEventHandler<HTMLElement> = (_event) => {
reportEvent('Pobierz plik PDF');
// @todo open DownloadSuccessModal
// @todo this.analyticsService.reportPdfDownload(this.selectedQuestionsService.getSelectedIds());
};

const onOpenAddQuestionModalClick: React.MouseEventHandler<HTMLElement> = (_event) => {
reportEvent('Dodaj pytanie');
uiOpenAddQuestionModal();
};
const onOpenAddQuestionModalClick: React.MouseEventHandler<HTMLElement> = (_event) => {
reportEvent('Dodaj pytanie');
openAddQuestionModal();
};

const reportEvent = (action: string) => {
globalReportEvent(action, 'Menu');
};
return (
<div className={classNames('app-cta-header', styles.ctaHeader)}>
<Container as="header" className={styles.appHeaderCta}>
<nav className={styles.appTabs}>
<ActiveLink href="/questions" activeClassName={styles.active}>
<a
data-cy="navigate-list"
onClick={() => reportEvent('Lista pytań')}
className={styles.appTabsTab}
>
Lista pytań
</a>
</ActiveLink>
<ActiveLink href="/selected-questions" activeClassName={styles.active}>
<a
data-cy="navigate-selected-questions"
onClick={() =>
reportEvent(areAnyQuestionSelected ? 'Wybrane pytania' : 'Wybrane pytania (puste)')
}
className={classNames(styles.appTabsTab, {
[styles.hasNotification]: areAnyQuestionSelected,
})}
>
Wybrane pytania
</a>
</ActiveLink>

{isAdmin && (
<ActiveLink href="/admin" activeClassName={styles.active}>
<a className={styles.appTabsTab}>Admin</a>
const reportEvent = (action: string) => {
globalReportEvent(action, 'Menu');
};
return (
<div className={classNames('app-cta-header', styles.ctaHeader)}>
<Container as="header" className={styles.appHeaderCta}>
<nav className={styles.appTabs}>
<ActiveLink href="/questions" activeClassName={styles.active}>
<a
data-cy="navigate-list"
onClick={() => reportEvent('Lista pytań')}
className={styles.appTabsTab}
>
Lista pytań
</a>
</ActiveLink>
<ActiveLink href="/selected-questions" activeClassName={styles.active}>
<a
data-cy="navigate-selected-questions"
onClick={() =>
reportEvent(
areAnyQuestionSelected ? 'Wybrane pytania' : 'Wybrane pytania (puste)'
)
}
className={classNames(styles.appTabsTab, {
[styles.hasNotification]: areAnyQuestionSelected,
})}
>
Wybrane pytania
</a>
</ActiveLink>
)}
</nav>

<div className={styles.callToActionButtons}>
{/* <ActiveLink route={this.props.downloadUrl}>
{isAdmin && (
<ActiveLink href="/admin" activeClassName={styles.active}>
<a className={styles.appTabsTab}>Admin</a>
</ActiveLink>
)}
</nav>

<div className={styles.callToActionButtons}>
{/* <ActiveLink route={this.props.downloadUrl}>
<a
onClick={this.onDownloadClick}
target="_blank"
Expand All @@ -79,18 +81,19 @@ export const CtaHeaderComponent: React.FC<
Pobierz plik PDF
</a>
</ActiveLink> */}
<button
className={classNames(styles.roundButton, 'round-button', 'branding-button-inverse')}
onClick={onOpenAddQuestionModalClick}
data-cy="open-add-question-form"
>
Dodaj pytanie
</button>
</div>
</Container>
</div>
);
});
<button
className={classNames(styles.roundButton, 'round-button', 'branding-button-inverse')}
onClick={onOpenAddQuestionModalClick}
data-cy="open-add-question-form"
>
Dodaj pytanie
</button>
</div>
</Container>
</div>
);
}
);

const mapStateToProps = (state: AppState) => {
return {
Expand All @@ -100,8 +103,4 @@ const mapStateToProps = (state: AppState) => {
};
};

const mapDispatchToProps = {
uiOpenAddQuestionModal: ActionCreators.uiOpenAddQuestionModal,
};

export const CtaHeader = connect(mapStateToProps, mapDispatchToProps)(CtaHeaderComponent);
export const CtaHeader = connect(mapStateToProps)(CtaHeaderComponent);
20 changes: 13 additions & 7 deletions apps/www/components/modals/addQuestionModal/AddQuestionModal.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { isEqual } from 'lodash';
import React, { memo, useState, useEffect, useCallback, forwardRef } from 'react';
import { useDispatch } from 'react-redux';
import React, { forwardRef, memo, useCallback, useEffect, useState } from 'react';

import type { LevelKey } from '../../../constants/level';
import type { TechnologyKey } from '../../../constants/technology-icon-items';
import { ActionCreators } from '../../../redux/actions';
import { useUIContext } from '../../../contexts/UIContextProvider';
import { Question } from '../../../redux/reducers/questions';
import { Api } from '../../../services/Api';
import { useDidMount, useRenderProp } from '../../../utils/hooks';
Expand All @@ -24,15 +23,14 @@ type AddQuestionModalProps = AddQuestionModalOwnProps & CommonModalProps;

export const AddQuestionModal = memo(
forwardRef<HTMLDivElement, AddQuestionModalProps>(({ onClose, originalQuestion }, ref) => {
const { openAddQuestionConfirmationModal } = useUIContext();
const [editedQuestion, setEditedQuestion] = useState<Question>();
const [questionText, setQuestionText] = useState('');
const [level, setLevel] = useState<LevelKey>();
const [technology, setTechnology] = useState<TechnologyKey>();
const [isLoading, setIsLoading] = useState(false);
const [valid, setValid] = useState(false);

const dispatch = useDispatch();

const isValid = useCallback(() => Boolean(level && technology && questionText.trim()), [
level,
questionText,
Expand Down Expand Up @@ -101,11 +99,19 @@ export const AddQuestionModal = memo(
return Api.createQuestion(body)
.then(() => {
onClose({ reason: 'submit' });
dispatch(ActionCreators.uiOpenAddQuestionConfirmationModal());
openAddQuestionConfirmationModal();
})
.finally(() => setIsLoading(false));
}
}, [dispatch, isValid, level, onClose, originalQuestion, questionText, technology]);
}, [
isValid,
level,
onClose,
openAddQuestionConfirmationModal,
originalQuestion,
questionText,
technology,
]);

const validate = useCallback(() => {
setValid(isValid());
Expand Down
27 changes: 14 additions & 13 deletions apps/www/components/modals/appModals/AppModals.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import React, { useRef, memo, useCallback } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import React, { memo, useCallback, useRef } from 'react';
import { CSSTransition } from 'react-transition-group';

import { ActionCreators } from '../../../redux/actions';
import { useUIContext } from '../../../contexts/UIContextProvider';
import { AddQuestionConfirmationModal } from '../addQuestionConfirmationModal/AddQuestionConfirmationModal';
import { AddQuestionModal } from '../addQuestionModal/AddQuestionModal';
import { CommonModalProps } from '../baseModal/BaseModal';
Expand All @@ -14,31 +13,33 @@ export const AppModals = memo(() => {
const addQuestionModalRef = useRef<HTMLDivElement>(null);
const addQuestionConfirmationModalRef = useRef<HTMLDivElement>(null);

const dispatch = useDispatch();
const addQuestionModalState = useSelector((state) => state.ui.addQuestionModal);
const isAddQuestionConfirmationModalOpen = useSelector(
(state) => state.ui.isAddQuestionConfirmationModalOpen
);
const {
addQuestionModalState,
closeAddQuestionModal,
isAddQuestionConfirmationModalOpen,
closeEditQuestionModal,
closeAddQuestionConfirmationModal,
} = useUIContext();

const closeQuestionModal: CommonModalProps['onClose'] = useCallback(
(args) => {
if (addQuestionModalState.onClose) {
addQuestionModalState.onClose(args);
}
if (addQuestionModalState.data) {
dispatch(ActionCreators.uiCloseEditQuestionModal());
closeEditQuestionModal();
} else {
dispatch(ActionCreators.uiCloseAddQuestionModal());
closeAddQuestionModal();
}
},
[addQuestionModalState, dispatch]
[addQuestionModalState, closeAddQuestionModal, closeEditQuestionModal]
);

const closeConfirmationModal: CommonModalProps['onClose'] = useCallback(
(_args) => {
dispatch(ActionCreators.uiCloseAddQuestionConfirmationModal());
closeAddQuestionConfirmationModal();
},
[dispatch]
[closeAddQuestionConfirmationModal]
);

return (
Expand Down
8 changes: 4 additions & 4 deletions apps/www/components/questions/allQuestions/AllQuestions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { connect } from 'react-redux';

import { Level } from '../../../constants/level';
import { technologyIconItems, Technology } from '../../../constants/technology-icon-items';
import { useUIContext } from '../../../contexts/UIContextProvider';
import { ActionCreators } from '../../../redux/actions';
import { AppState } from '../../../redux/reducers/index';
import { Question } from '../../../redux/reducers/questions';
Expand All @@ -29,10 +30,10 @@ const AllQuestionsComponent = React.memo<AllQuestionsComponentProps>(
questions,
selectedQuestionsIds,
route,
uiOpenAddQuestionModal,
selectQuestion,
deselectQuestion,
}) => {
const { openAddQuestionModal } = useUIContext();
const technologyIconItem = technologyIconItems.find((t) => t.name === technology);
const category = (technologyIconItem && technologyIconItem.label) || '';

Expand All @@ -55,8 +56,8 @@ const AllQuestionsComponent = React.memo<AllQuestionsComponentProps>(

const onAddNewClick = useCallback(() => {
reportEvent('CTA Dodaj nowe pytanie');
uiOpenAddQuestionModal();
}, [uiOpenAddQuestionModal, reportEvent]);
openAddQuestionModal();
}, [openAddQuestionModal, reportEvent]);

const toggleQuestion = useCallback(
(questionId: Question['id']) => {
Expand Down Expand Up @@ -141,7 +142,6 @@ const mapStateToProps = (state: AppState) => {
const mapDispatchToProps = {
selectQuestion: ActionCreators.selectQuestion,
deselectQuestion: ActionCreators.deselectQuestion,
uiOpenAddQuestionModal: ActionCreators.uiOpenAddQuestionModal,
};

const AllQuestions = connect(mapStateToProps, mapDispatchToProps)(AllQuestionsComponent);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import classNames from 'classnames';
import React from 'react';
import { connect } from 'react-redux';

import { ActionCreators } from '../../../redux/actions';
import { useUIContext } from '../../../contexts/UIContextProvider';
import { AppState } from '../../../redux/reducers';
import { getAreAnyQuestionSelected, getDownloadUrl } from '../../../redux/selectors/selectors';

Expand All @@ -13,8 +13,9 @@ interface MobileActionButtonsProps {
}

const MobileActionButtonsComponent = React.memo<
MobileActionButtonsProps & ReturnType<typeof mapStateToProps> & typeof mapDispatchToProps
>(({ justDownload, uiOpenSidebar, uiOpenAddQuestionModal }) => {
MobileActionButtonsProps & ReturnType<typeof mapStateToProps>
>(({ justDownload }) => {
const { openSideBar, openAddQuestionModal } = useUIContext();
const onDownloadClick = () => {
// @todo
};
Expand All @@ -25,15 +26,15 @@ const MobileActionButtonsComponent = React.memo<
className={classNames(styles.openSidebar, 'circle-button')}
title="Filtruj wyniki"
aria-label="Filtruj wyniki"
onClick={uiOpenSidebar}
onClick={openSideBar}
/>
)}
{!justDownload && (
<button
className={classNames(styles.addQuestion, 'circle-button')}
title="Dodaj pytanie"
aria-label="Dodaj pytanie"
onClick={uiOpenAddQuestionModal}
onClick={openAddQuestionModal}
/>
)}
{/* {!justDownload && (
Expand Down Expand Up @@ -71,13 +72,5 @@ const mapStateToProps = (state: AppState) => {
};
};

const mapDispatchToProps = {
uiOpenSidebar: ActionCreators.uiOpenSidebar,
uiOpenAddQuestionModal: ActionCreators.uiOpenAddQuestionModal,
};

const MobileActionButtons = connect(
mapStateToProps,
mapDispatchToProps
)(MobileActionButtonsComponent);
const MobileActionButtons = connect(mapStateToProps)(MobileActionButtonsComponent);
export default MobileActionButtons;
Loading