Skip to content

Commit

Permalink
feature vil-295 refacto and finalise dev
Browse files Browse the repository at this point in the history
  • Loading branch information
GuillaumeLoup committed Mar 25, 2024
1 parent edb02d2 commit 40b1a18
Show file tree
Hide file tree
Showing 16 changed files with 193 additions and 172 deletions.
15 changes: 11 additions & 4 deletions src/components/Steps.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ import Stepper from '@mui/material/Stepper';
import { ActivityContext } from 'src/contexts/activityContext';
import { primaryColor, primaryColorLight2, successColor, warningColor } from 'src/styles/variables.const';

const StepIcon = ({ icon, active, completed, error, onClick }: StepIconProps) => {
const StepIcon = React.forwardRef<HTMLDivElement, StepIconProps>((props, ref) => {
const { icon, active, completed, error } = props;

return (
<div
ref={ref}
style={{
backgroundColor: active ? primaryColor : error ? warningColor : 'white',
color: completed ? (error ? 'white' : successColor) : active ? 'white' : primaryColor,
Expand All @@ -25,13 +28,17 @@ const StepIcon = ({ icon, active, completed, error, onClick }: StepIconProps) =>
borderRadius: '50%',
border: completed ? (error ? `1px solid ${warningColor}` : `1px solid ${successColor}`) : `1px solid ${primaryColor}`,
}}
className={onClick !== undefined ? 'background-hover' : ''}
onClick={onClick}
className={props.onClick ? 'background-hover' : ''}
onClick={props.onClick}
>
{completed && !error ? <CheckIcon /> : icon}
</div>
);
};
});

StepIcon.displayName = 'StepIcon';

export default StepIcon;

interface StepsProps {
steps: string[];
Expand Down
19 changes: 19 additions & 0 deletions src/components/activities/StepsNavigation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';

import { Steps } from 'src/components/Steps';

interface StepsNavigationProps {
currentStep: number;
errorSteps?: number[];
}

const StepsNavigation: React.FC<StepsNavigationProps> = ({ currentStep, errorSteps }) => (
<Steps
steps={['Contenu', 'Forme', 'Prévisualiser']}
urls={['/admin/newportal/contenulibre/1?edit', '/admin/newportal/contenulibre/2', '/admin/newportal/contenulibre/3']}
activeStep={currentStep}
errorSteps={errorSteps}
/>
);

export default StepsNavigation;
2 changes: 1 addition & 1 deletion src/components/activities/content/AddContentCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const AddContentCard = ({ addContent = () => {} }: AddContentCardProps) =

return (
<Card style={{ display: 'inline-block' }}>
<div style={{ display: 'inline-flex', padding: '0.2rem 1rem', alignItems: 'center' }}>
<div style={{ display: 'inline-flex', padding: '0.2rem 1rem', alignItems: 'center', flexWrap: 'wrap' }}>
<span className="text text--bold" style={{ margin: '0 0.5rem' }}>
Ajouter à votre description :
</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ interface SimpleTextEditorProps {

export const SimpleTextEditor = ({
value = '',
placeholder = 'Commencez à écrire ici, ou ajoutez une vidéo ou une image.',
placeholder = 'Commencez à écrire ici, ou ajoutez une vidéo, un son ou une image.',
onChange = () => {},
onFocus = () => {},
onBlur = () => {},
Expand Down
4 changes: 0 additions & 4 deletions src/components/admin/NewAdminNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,8 @@ import GererIcon from 'src/svg/gerer.svg';
import MediathequeIcon from 'src/svg/mediatheque.svg';
import PublierIcon from 'src/svg/publier.svg';

// interface NewAdminNavigationProps {
// changeContent?: (label: string) => void;
// }
interface NavItemProps {
key?: number;

path: string;
selected: boolean;
onClick: React.MouseEventHandler<HTMLDivElement>;
Expand Down
12 changes: 12 additions & 0 deletions src/hooks/useActivity.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// hooks/useActivity.js
import React from 'react';

import { ActivityContext } from 'src/contexts/activityContext';

export function useActivity() {
const context = React.useContext(ActivityContext);
if (context === undefined) {
throw new Error('useActivity must be used within an ActivityProvider');
}
return context;
}
65 changes: 26 additions & 39 deletions src/pages/admin/newportal/contenulibre/1.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
import { useRouter } from 'next/router';
import React from 'react';
import React, { useEffect } from 'react';

import { isFreeContent } from 'src/activity-types/anyActivity';
import { Base } from 'src/components/Base';
import { Steps } from 'src/components/Steps';
import { StepsButton } from 'src/components/StepsButtons';
import { ContentEditor } from 'src/components/activities/content';
import { BackButton } from 'src/components/buttons/BackButton';
import { ActivityContext } from 'src/contexts/activityContext';
import StepsNavigation from 'src/components/activities/StepsNavigation';
import ContentEditor from 'src/components/activities/content/ContentEditor';
import { useActivity } from 'src/hooks/useActivity';
import type { ActivityContent } from 'types/activity.type';
import { ActivityStatus } from 'types/activity.type';

const ContenuLibre = () => {
const ContenuLibreStep1: React.FC = () => {
const { activity, updateActivity, addContent, deleteContent, save } = useActivity();
const router = useRouter();
const { activity, updateActivity, addContent, deleteContent, save } = React.useContext(ActivityContext);

const isEdit = activity !== null && activity.status !== ActivityStatus.DRAFT;

React.useEffect(() => {
useEffect(() => {
if (activity === null && !('activity-id' in router.query) && !sessionStorage.getItem('activity')) {
router.push('/admin/newportal/contenulibre');
} else if (activity && !isFreeContent(activity)) {
Expand All @@ -26,42 +21,34 @@ const ContenuLibre = () => {
}, [activity, router]);

const updateContent = (content: ActivityContent[]): void => {
if (!activity) {
return;
}
if (!activity) return;
updateActivity({ content });
};

const onNext = () => {
save().catch(console.error);
router.push('/admin/newportal/contenulibre/2');
const onNext = async (): Promise<void> => {
const success = await save();
if (success) {
router.push('/admin/newportal/contenulibre/2');
}
};

if (!activity) {
return <Base />;
return <div>Loading...</div>;
}

return (
<Base hideLeftNav>
<div style={{ width: '100%', padding: '0.5rem 1rem 1rem 1rem' }}>
{!isEdit && <BackButton href="/admin/newportal/contenulibre" />}
<Steps
steps={['Contenu', 'Forme', 'Pré-visualiser']}
urls={['/admin/newportal/contenulibre/1?edit', '/admin/newportal/contenulibre/2', '/admin/newportal/contenulibre/3']}
activeStep={0}
/>
<div className="width-900">
<h1>Ecrivez le contenu de votre publication</h1>
<p className="text">
Utilisez l&apos;éditeur de bloc pour définir le contenu de votre publication. Dans l&apos;étape 2 vous pourrez définir l&apos;aspect de la
carte résumée de votre publication.
</p>
<ContentEditor content={activity.content} updateContent={updateContent} addContent={addContent} deleteContent={deleteContent} />
<StepsButton next={onNext} />
</div>
</div>
</Base>
<div>
<StepsNavigation currentStep={0} />
<h1>Ecrivez le contenu de votre publication</h1>
<p>
Utilisez l&apos;éditeur de bloc pour définir le contenu de votre publication. Dans l&apos;étape 2 vous pourrez définir l&apos;aspect de la
carte résumée de votre publication.
</p>
<ContentEditor content={activity.content} updateContent={updateContent} addContent={addContent} deleteContent={deleteContent} />

<StepsButton next={onNext} />
</div>
);
};

export default ContenuLibre;
export default ContenuLibreStep1;
30 changes: 9 additions & 21 deletions src/pages/admin/newportal/contenulibre/2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,43 +9,36 @@ import { getImage } from 'src/activity-types/freeContent.constants';
import type { FreeContentData } from 'src/activity-types/freeContent.types';
import { Base } from 'src/components/Base';
import { Modal } from 'src/components/Modal';
import { Steps } from 'src/components/Steps';
import { StepsButton } from 'src/components/StepsButtons';
import { ActivityCard } from 'src/components/activities/ActivityCard';
import StepsNavigation from 'src/components/activities/StepsNavigation';
import { ImageModal } from 'src/components/activities/content/editors/ImageEditor/ImageModal';
import { LightBox } from 'src/components/lightbox/Lightbox';
import { ActivityContext } from 'src/contexts/activityContext';
import { UserContext } from 'src/contexts/userContext';
import { useActivity } from 'src/hooks/useActivity';
import { primaryColor } from 'src/styles/variables.const';

const ContenuLibre = () => {
const router = useRouter();
const { activity, updateActivity, save } = React.useContext(ActivityContext);
const { activity, updateActivity, save } = useActivity();
const { user } = React.useContext(UserContext);
const [selectedImageUrl, setSelectedImageUrl] = React.useState<string | undefined>(undefined);
const [isAllImagesModalOpen, setIsAllImagesModalOpen] = React.useState(false);
const [isImageModalOpen, setIsImageModalOpen] = React.useState(false);

const data = (activity?.data as FreeContentData) || null;
const errorSteps = React.useMemo(() => {
if (activity !== null && activity.content.filter((c) => c.value.length > 0 && c.value !== '<p></p>\n').length === 0) {
return [0];
}
return [];
}, [activity]);

const hasContentImages = React.useMemo(() => activity !== null && activity.content.some((c) => c.type === 'image'), [activity]);
const imageUrl = React.useMemo(() => getImage(activity?.content ?? [], data), [activity, data]);

React.useEffect(() => {
if (activity === null && !('activity-id' in router.query) && !sessionStorage.getItem('activity')) {
router.push('/admin/newportal/contenulibre/1');
} else if (activity && !isFreeContent(activity)) {
if (!activity || !isFreeContent(activity)) {
router.push('/admin/newportal/contenulibre/1');
}
}, [activity, router]);

if (!activity || !user) {
return <Base></Base>;
return <Base />;
}

const handlePinnedChange = () => {
Expand All @@ -68,14 +61,9 @@ const ContenuLibre = () => {
};

return (
<Base hideLeftNav>
<div>
<div style={{ width: '100%', padding: '0.5rem 1rem 1rem 1rem' }}>
<Steps
steps={['Contenu', 'Forme', 'Pré-visualiser']}
urls={['/admin/newportal/contenulibre/1?edit', '/admin/newportal/contenulibre/2', '/admin/newportal/contenulibre/3']}
activeStep={1}
errorSteps={errorSteps}
/>
<StepsNavigation currentStep={1} />
<div className="width-900">
<h1>Ajustez l&apos;apparence de votre publication</h1>
<p className="text">
Expand Down Expand Up @@ -233,7 +221,7 @@ const ContenuLibre = () => {
setSelectedImageUrl(undefined);
}}
/>
</Base>
</div>
);
};

Expand Down
33 changes: 15 additions & 18 deletions src/pages/admin/newportal/contenulibre/3.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@ import CircularProgress from '@mui/material/CircularProgress';
import { isFreeContent } from 'src/activity-types/anyActivity';
import type { FreeContentData } from 'src/activity-types/freeContent.types';
import { Base } from 'src/components/Base';
import { Steps } from 'src/components/Steps';
import { StepsButton } from 'src/components/StepsButtons';
import { ActivityCard } from 'src/components/activities/ActivityCard';
import StepsNavigation from 'src/components/activities/StepsNavigation';
import { ContentView } from 'src/components/activities/content/ContentView';
import { EditButton } from 'src/components/buttons/EditButton';
import { ActivityContext } from 'src/contexts/activityContext';
import { UserContext } from 'src/contexts/userContext';
import { useActivity } from 'src/hooks/useActivity';
import { ActivityStatus } from 'types/activity.type';

const ContenuLibre = () => {
const router = useRouter();
const { activity, save } = React.useContext(ActivityContext);
const { activity, save } = useActivity();
const { user } = React.useContext(UserContext);
const [isLoading, setIsLoading] = React.useState(false);

Expand All @@ -40,19 +40,21 @@ const ContenuLibre = () => {
const isValid = errorSteps.length === 0;

React.useEffect(() => {
if (activity === null && !('activity-id' in router.query) && !sessionStorage.getItem('activity')) {
if (!activity) {
router.push('/admin/newportal/contenulibre');
} else if (activity && !isFreeContent(activity)) {
return;
}
if (!isFreeContent(activity)) {
router.push('/admin/newportal/contenulibre');
}
}, [activity, router]);

const onPublish = async () => {
const onCreate = async () => {
if (!isValid) {
return;
}
setIsLoading(true);
const { success } = await save(true);
const { success } = await save(false);
if (success) {
router.push('/admin/newportal/contenulibre/success');
}
Expand All @@ -64,14 +66,9 @@ const ContenuLibre = () => {
}

return (
<Base hideLeftNav>
<div>
<div style={{ width: '100%', padding: '0.5rem 1rem 1rem 1rem' }}>
<Steps
steps={['Contenu', 'Forme', 'Prévisualiser']}
urls={['/admin/newportal/contenulibre/1?edit', '/admin/newportal/contenulibre/2', '/admin/newportal/contenulibre/3']}
activeStep={2}
errorSteps={errorSteps}
/>
<StepsNavigation currentStep={2} />
<div className="width-900">
<h1>Pré-visualisez votre publication</h1>
<p className="text" style={{ fontSize: '1.1rem' }}>
Expand All @@ -87,14 +84,14 @@ const ContenuLibre = () => {
{"Modifier à l'étape précédente"}
</Button>
</Link>
<Button variant="outlined" color="primary" onClick={onPublish}>
<Button variant="outlined" color="primary" onClick={onCreate}>
Enregistrer les changements
</Button>
</div>
) : (
<div style={{ width: '100%', textAlign: 'right', margin: '1rem 0' }}>
<Button variant="outlined" color="primary" onClick={onPublish} disabled={errorSteps.length > 0}>
Publier
<Button variant="outlined" color="primary" onClick={onCreate} disabled={errorSteps.length > 0}>
Créer
</Button>
</div>
)}
Expand Down Expand Up @@ -129,7 +126,7 @@ const ContenuLibre = () => {
<Backdrop style={{ zIndex: 2000, color: 'white' }} open={isLoading}>
<CircularProgress color="inherit" />
</Backdrop>
</Base>
</div>
);
};

Expand Down
Loading

0 comments on commit 40b1a18

Please sign in to comment.