diff --git a/src/app/api/streetcode/streetcodes.api.ts b/src/app/api/streetcode/streetcodes.api.ts index da9a43a0b..3f1b7f3a4 100644 --- a/src/app/api/streetcode/streetcodes.api.ts +++ b/src/app/api/streetcode/streetcodes.api.ts @@ -28,8 +28,12 @@ const StreetcodesApi = { getAllMainPage: () => Agent.get(`${API_ROUTES.STREETCODES.GET_ALL_MAINPAGE}`), getPageMainPage: (page: number, pageSize: number, args: any) => Agent - .get(`${API_ROUTES.STREETCODES.GET_PAGE_MAINPAGE}`, - new URLSearchParams(Object.entries({ page: page.toString(), pageSize: pageSize.toString(), shuffleSeed: args["shuffleSeed"].toString() }))), + .get( + `${API_ROUTES.STREETCODES.GET_PAGE_MAINPAGE}`, + new URLSearchParams(Object.entries({ page: page.toString(), + pageSize: pageSize.toString(), + shuffleSeed: args.shuffleSeed.toString() })), + ), getAllCatalog: (page: number, count: number) => Agent .get( @@ -37,7 +41,9 @@ const StreetcodesApi = { new URLSearchParams({ page: page.toString(), count: count.toString() }), ), - getCount: () => Agent.get(`${API_ROUTES.STREETCODES.GET_COUNT}`), + getCount: (onlyPublished = false) => Agent.get( + `${API_ROUTES.STREETCODES.GET_COUNT}?onlyPublished=${onlyPublished}`, + ), getAllShort: () => Agent.get(`${API_ROUTES.STREETCODES.GET_ALL_SHORT}`), diff --git a/src/app/common/components/ContactForm/ContactForm.component.tsx b/src/app/common/components/ContactForm/ContactForm.component.tsx index 2f27ec3ae..bfde1c211 100644 --- a/src/app/common/components/ContactForm/ContactForm.component.tsx +++ b/src/app/common/components/ContactForm/ContactForm.component.tsx @@ -17,7 +17,6 @@ interface Props { const ContactForm = forwardRef((customClass: Props , ref) => { const [formData, setFormData] = useState({ email: '', message: '' }); const [isVerified, setIsVerified] = useState(false); - const messageLength = formData.message.length | 0; const [messageApi, messageContextHolder] = message.useMessage(); const [form] = Form.useForm(); const handleChange = (e) => setFormData({ ...formData, [e.target.name]: e.target.value }); @@ -36,8 +35,12 @@ const ContactForm = forwardRef((customClass: Props , ref) => { if (isVerified) { const newEmail: Email = { from: formData.email, content: formData.message }; EmailApi.send(newEmail) - .then(successMessage) - .catch(errorMessage); + .then(() => { + successMessage(); + }) + .catch(() => { + errorMessage(); + }); } }; @@ -88,14 +91,9 @@ const ContactForm = forwardRef((customClass: Props , ref) => { maxLength={MAX_SYMBOLS} onChange={handleChange} /> -

- {messageLength} - / - {' '} - {MAX_SYMBOLS} -

{ onChange={handleChange} /> -
+
diff --git a/src/app/common/components/ContactForm/ContactForm.styles.scss b/src/app/common/components/ContactForm/ContactForm.styles.scss index 811e948d6..f7f93ef3b 100644 --- a/src/app/common/components/ContactForm/ContactForm.styles.scss +++ b/src/app/common/components/ContactForm/ContactForm.styles.scss @@ -139,19 +139,32 @@ position: relative; } - .required-input::before { + .required-input::after { content: '*'; position: absolute; - top: 0; - left: f.pxToRem(-8px); + top: f.pxToRem(15px); + right: f.pxToRem(12px); transform: translate(-50%, -50%); color: red; - font-size: 20px; + @include mut.sizedImportant(8px, 8px); } .captchaBlock { @include mut.flexed($direction: column, $justify-content: center, $align-items: center); } + + .required-captcha { + position: relative; + } + .required-captcha::before { + content: '*'; + position: absolute; + top: f.pxToRem(0); + left: f.pxToRem(-8px); + transform: translate(-50%, -50%); + color: red; + @include mut.sizedImportant(8px, 8px); + } } } diff --git a/src/app/common/components/modals/ContactUsModal/ContactUsModal.component.tsx b/src/app/common/components/modals/ContactUsModal/ContactUsModal.component.tsx index 8e0f061bf..25832b6e0 100644 --- a/src/app/common/components/modals/ContactUsModal/ContactUsModal.component.tsx +++ b/src/app/common/components/modals/ContactUsModal/ContactUsModal.component.tsx @@ -4,6 +4,7 @@ import { Form, Modal, Popover, Typography } from 'antd' const { Text } = Typography import { useRef, useState } from 'react'; import CancelBtn from '@images/utils/Cancel_btn.svg'; +import { useMediaQuery } from 'react-responsive'; interface Props { text: string; @@ -15,6 +16,10 @@ export const ContactUsModal = ({ text, toggleState}: Props) => { const [isActive, setActive] = useState(false); const form = useRef(null); + const isDesktop = useMediaQuery({ + query: '(min-width: 1025px)', + }); + const handleClick = () => { setActive(true); toggleState(); @@ -34,12 +39,13 @@ export const ContactUsModal = ({ text, toggleState}: Props) => { footer={null} onCancel={() => setActive(false)} width={"max-content"} - closeIcon={ - } + closeIcon={(isDesktop ? + + + + : )} > -
- ) diff --git a/src/app/common/components/modals/ContactUsModal/ContactUsModal.styles.scss b/src/app/common/components/modals/ContactUsModal/ContactUsModal.styles.scss index cbde2b6e7..906681edc 100644 --- a/src/app/common/components/modals/ContactUsModal/ContactUsModal.styles.scss +++ b/src/app/common/components/modals/ContactUsModal/ContactUsModal.styles.scss @@ -6,11 +6,11 @@ &.ant-modal { .ant-modal-content { @include mut.full-rounded(20px, $overflow: visible); - padding: f.pxToRem(24px) f.pxToRem(40px); + @include mut.rem-padded(0px); box-shadow: 0 7px 11px 2px rgba(0, 0, 0, 0.25); } .ant-modal-close { - @include mut.positioned-as(absolute, $left: 94%, $top: -25px); + @include mut.positioned-as(absolute, $right: -26px, $top: -26px); @include mut.circular(80px, c.$pure-white-color); box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); @@ -27,9 +27,14 @@ @media screen and (max-width: 1024px) { .contactUsModal { @include mut.sizedImportant(90%, 498px); + + .formWrapper { + @include mut.rem-margined($top: 0px); + } &.ant-modal { .ant-modal-close { + @include mut.positioned-as($position: absolute, $right: -17px, $top: -17px); @include mut.sizedImportant(60px, 60px); @include mut.circular(65px, c.$pure-white-color); @@ -45,7 +50,7 @@ .contactUsModal { &.ant-modal { .ant-modal-close { - @include mut.positioned-as($position: absolute, $left: 92.36%, $top: -13px); + @include mut.positioned-as($position: absolute, $right: -11px, $top: -11px); @include mut.sizedImportant(40px, 40px); @include mut.circular(65px, c.$pure-white-color); diff --git a/src/app/common/utils/paginateRequest.tsx b/src/app/common/utils/paginateRequest.tsx index befa24a33..bd684c8ea 100644 --- a/src/app/common/utils/paginateRequest.tsx +++ b/src/app/common/utils/paginateRequest.tsx @@ -17,7 +17,7 @@ export function paginateRequest( } page = currentPage + 1; - return response; + return [response, (currentPage - 1) * pageSize, currentPage * pageSize]; }; return { fetchNextPage }; diff --git a/src/features/AdminPage/NewStreetcode/InterestingFactsBlock/FactsAdminModal/InterestingFactsAdminModal.component.tsx b/src/features/AdminPage/NewStreetcode/InterestingFactsBlock/FactsAdminModal/InterestingFactsAdminModal.component.tsx index dfd5c0b22..969e85e33 100644 --- a/src/features/AdminPage/NewStreetcode/InterestingFactsBlock/FactsAdminModal/InterestingFactsAdminModal.component.tsx +++ b/src/features/AdminPage/NewStreetcode/InterestingFactsBlock/FactsAdminModal/InterestingFactsAdminModal.component.tsx @@ -8,7 +8,7 @@ import CancelBtn from '@assets/images/utils/Cancel_btn.svg'; import useMobx from '@stores/root-store'; import { - Button, Form, Input, message, Modal, Popover, UploadFile, + Button, Form, Input, message, Modal, Popover, UploadFile, } from 'antd'; import FormItem from 'antd/es/form/FormItem'; import TextArea from 'antd/es/input/TextArea'; @@ -22,8 +22,6 @@ import { FactCreate, FactUpdate } from '@/models/streetcode/text-contents.model' import PreviewFileModal from '../../MainBlock/PreviewFileModal/PreviewFileModal.component'; - - interface Props { fact?: FactCreate, open: boolean, @@ -39,11 +37,11 @@ const InterestingFactsAdminModal = ({ fact, open, setModalOpen, onChange }: Prop const [previewOpen, setPreviewOpen] = useState(false); const [hasUploadedPhoto, setHasUploadedPhoto] = useState(false); - const clearModal=() =>{ + const clearModal = () => { form.resetFields(); setModalOpen(false); setFileList([]); - } + }; useEffect(() => { if (fact && open) { @@ -80,9 +78,10 @@ const InterestingFactsAdminModal = ({ fact, open, setModalOpen, onChange }: Prop }, [fact, open, form]); const onSuccesfulSubmit = (formValues: any) => { - factsStore.getFactArray.map((t) => t).forEach(t => { - if (formValues.title == t.title || formValues.factContent == t.factContent || imageId.current == t.imageId) - fact = t; + factsStore.getFactArray.map((t) => t).forEach((t) => { + if (formValues.title === t.title + || formValues.factContent === t.factContent + || imageId.current === t.imageId) fact = t; }); if (fact) { const item = factsStore.factMap.get(fact.id) as FactUpdate; @@ -116,7 +115,7 @@ const InterestingFactsAdminModal = ({ fact, open, setModalOpen, onChange }: Prop try { await form.validateFields(); form.submit(); - message.success("Wow-факт успішно додано!", 2) + message.success('Wow-факт успішно додано!', 2); } catch (error) { message.config({ top: 100, @@ -140,10 +139,11 @@ const InterestingFactsAdminModal = ({ fact, open, setModalOpen, onChange }: Prop footer={null} maskClosable centered - - closeIcon={ - - } + closeIcon={( + + + + )} >
- +
- + ); }; diff --git a/src/features/AdminPage/NewStreetcode/MainBlock/DatePickerPart.component.tsx b/src/features/AdminPage/NewStreetcode/MainBlock/DatePickerPart.component.tsx index 2a649728c..1b5327661 100644 --- a/src/features/AdminPage/NewStreetcode/MainBlock/DatePickerPart.component.tsx +++ b/src/features/AdminPage/NewStreetcode/MainBlock/DatePickerPart.component.tsx @@ -9,7 +9,7 @@ import { Dayjs } from 'dayjs'; import { DatePicker, FormInstance, Input, Select } from 'antd'; import FormItem from 'antd/es/form/FormItem'; -import { dateToString, selectDateOptions } from '@/models/timeline/chronology.model'; +import { DatePickerType, dateToString, selectDateOptions } from '@/models/timeline/chronology.model'; interface Props { setFirstDate: (newDate: Dayjs | null) => void, @@ -19,10 +19,8 @@ interface Props { } const DatePickerPart = React.memo(({ setFirstDate, setSecondDate, form, onChange }: Props) => { - const [dateFirstTimePickerType, setFirstDateTimePickerType] = useState< - 'date' | 'month' | 'year' | 'season-year'>('date'); - const [dateSecondTimePickerType, setSecondDateTimePickerType] = useState< - 'date' | 'month' | 'year' | 'season-year'>('date'); + const [firstDateTimePickerType, setFirstDateTimePickerType] = useState(DatePickerType.Date); + const [secondDateTimePickerType, setSecondDateTimePickerType] = useState(DatePickerType.Date); const capitalize = (text: string): string => { if (!text) { return text; @@ -42,15 +40,15 @@ const DatePickerPart = React.memo(({ setFirstDate, setSecondDate, form, onChange } }); - const onChangeFirstDate = (date: Dayjs | null | undefined) => { + const onChangeFirstDate = async (date: Dayjs | null | undefined) => { if (date) { setFirstDate(date); const dateString = form.getFieldValue('dateString') ?? ''; const index = dateString.indexOf(' – '); if (index < 0) { - form.setFieldValue('dateString', capitalize(dateToString(dateFirstTimePickerType, date))); + form.setFieldValue('dateString', capitalize(dateToString(firstDateTimePickerType, date))); } else { - const newString = dateToString(dateFirstTimePickerType, date); + const newString = dateToString(firstDateTimePickerType, date); form.setFieldValue( 'dateString', capitalize(newString.concat(dateString.substring(index, dateString.length))), @@ -75,7 +73,7 @@ const DatePickerPart = React.memo(({ setFirstDate, setSecondDate, form, onChange }; const onChangeSecondDate = (date: Dayjs | null | undefined) => { - if (date && date !== null && date !== undefined) { + if (date) { setSecondDate(date); const firstDate = form.getFieldValue('streetcodeFirstDate'); if (firstDate && date && date.isBefore(firstDate)) { @@ -100,19 +98,19 @@ const DatePickerPart = React.memo(({ setFirstDate, setSecondDate, form, onChange form.setFieldValue( 'dateString', dateString - .concat(` – ${dateToString(dateSecondTimePickerType, date)}`), + .concat(` – ${dateToString(secondDateTimePickerType, date)}`), ); } else if (date === null || date === undefined) { form.setFieldValue('dateString', dateString.substring(0, index)); } else { const newDateString = dateString - .substring(0, index).concat(` – ${dateToString(dateSecondTimePickerType, date)}`); + .substring(0, index).concat(` – ${dateToString(secondDateTimePickerType, date)}`); form.setFieldValue('dateString', newDateString); } onChange('streetcodeSecondDate', date); } else { - form.setFieldValue('dateString', form.getFieldValue('dateString').split(' – ')[0]); - setSecondDate(date); + form.setFieldValue('dateString', form.getFieldValue('dateString')?.split(' – ')[0]); + setSecondDate(null); form.setFields([ { name: 'streetcodeSecondDate', @@ -125,6 +123,15 @@ const DatePickerPart = React.memo(({ setFirstDate, setSecondDate, form, onChange const [dateString, setDateString] = useState(''); + useEffect(() => { + onChangeFirstDate(form.getFieldValue('streetcodeFirstDate')); + }, [firstDateTimePickerType]); + + useEffect(() => { + onChangeSecondDate(form.getFieldValue('streetcodeSecondDate')); + }, [secondDateTimePickerType]); + + return (
@@ -158,10 +165,9 @@ const DatePickerPart = React.memo(({ setFirstDate, setSecondDate, form, onChange { setSecondDateTimePickerType(val); - onChangeSecondDate(form.getFieldValue('streetcodeSecondDate')); }} /> @@ -206,16 +211,16 @@ const DatePickerPart = React.memo(({ setFirstDate, setSecondDate, form, onChange > diff --git a/src/features/AdminPage/NewsPage/News.component.tsx b/src/features/AdminPage/NewsPage/News.component.tsx index f59fdf524..8721176a8 100644 --- a/src/features/AdminPage/NewsPage/News.component.tsx +++ b/src/features/AdminPage/NewsPage/News.component.tsx @@ -31,7 +31,7 @@ const Newss: React.FC = observer(() => { ImageStore.getImageById(val.imageId!).then((image) => { newsStore.NewsMap.set( key, - { ...val, image}, + { ...val, image }, ); }); } @@ -106,7 +106,7 @@ const Newss: React.FC = observer(() => { }); modalStore.setConfirmationModal('confirmation'); }, - 'Ви впевнені, що хочете видалити чю новину?', + 'Ви впевнені, що хочете видалити цю новину?', ); }} /> diff --git a/src/features/AdminPage/NewsPage/NewsModal/NewsModal.component.tsx b/src/features/AdminPage/NewsPage/NewsModal/NewsModal.component.tsx index 68b591291..aab4ef3b7 100644 --- a/src/features/AdminPage/NewsPage/NewsModal/NewsModal.component.tsx +++ b/src/features/AdminPage/NewsPage/NewsModal/NewsModal.component.tsx @@ -20,8 +20,8 @@ import { Form, Input, message, Modal, + Popover, UploadFile, - Popover } from 'antd'; import ukUAlocaleDatePicker from 'antd/es/date-picker/locale/uk_UA'; import ukUA from 'antd/locale/uk_UA'; @@ -39,7 +39,9 @@ const NewsModal: React.FC<{ afterSubmit?: (news: News) => void; initialValue: any; limit: any; -}> = observer(({ newsItem, open, setIsModalOpen, afterSubmit, initialValue, limit }) => { +}> = observer(({ + newsItem, open, setIsModalOpen, afterSubmit, initialValue, limit, +}) => { const [form] = Form.useForm(); const { newsStore } = useMobx(); const [previewOpen, setPreviewOpen] = useState(false); @@ -47,9 +49,10 @@ const NewsModal: React.FC<{ const [textIsPresent, setTextIsPresent] = useState(false); const [textIsChanged, setTextIsChanged] = useState(false); const imageId = useRef(0); + const image = useRef(undefined); const editorRef = useRef(); const sizeLimit = limit ?? 15000; - const [data, setData] = React.useState(initialValue ?? ""); + const [data, setData] = React.useState(initialValue ?? ''); const [count, setCount] = React.useState(0); const handlePreview = async (file: UploadFile) => { @@ -76,8 +79,10 @@ const NewsModal: React.FC<{ }; useEffect(() => { + editorRef.current?.setContent(''); if (newsItem && open) { imageId.current = newsItem.imageId; + image.current = newsItem.image; form.setFieldsValue({ title: newsItem.title, url: newsItem.url, @@ -99,11 +104,13 @@ const NewsModal: React.FC<{ } } else { imageId.current = 0; + image.current = undefined; } }, [newsItem, open, form]); const removeImage = () => { imageId.current = undefined; + image.current = undefined; if (newsItem) { newsItem.image = undefined; } @@ -117,22 +124,27 @@ const NewsModal: React.FC<{ editorRef.current?.setContent(''); }; - const closeModal =() => { + const closeModal = () => { setIsModalOpen(false); - } + }; dayjs.locale('uk'); const dayJsUa = require("dayjs/locale/uk"); // eslint-disable-line ukUAlocaleDatePicker.lang.shortWeekDays = dayJsUa.weekdaysShort; ukUAlocaleDatePicker.lang.shortMonths = dayJsUa.monthsShort; + const handleTextChange = () => { + setTextIsChanged(true); + if (editorRef.current?.getContent() === '') { setTextIsPresent(false); - } else { - setTextIsPresent(true); + return false; } - setTextIsChanged(true); + + setTextIsPresent(true); + return true; }; + const callErrorMessage = (messageText: string) => { message.config({ top: 100, @@ -146,11 +158,10 @@ const NewsModal: React.FC<{ const handleOk = async () => { try { - handleTextChange(); await form.validateFields(); - if (textIsPresent) { + if (handleTextChange()) { form.submit(); - message.success("Новину успішно додано!", 2) + message.success('Новину успішно додано!', 2); } else { callErrorMessage("Будь ласка, заповніть всі обов'язкові поля"); } @@ -170,16 +181,15 @@ const NewsModal: React.FC<{ creationDate: dayjs(formValues.creationDate), }; - newsStore.getNewsArray.map((t) => t).forEach(t => { - if (formValues.title == t.title || imageId.current == t.imageId) - newsItem = t; + newsStore.getNewsArray.map((t) => t).forEach((t) => { + if (formValues.title == t.title || imageId.current == t.imageId) newsItem = t; }); - //need to fix when url is static because from didn't see ti when u press save button on second time + // need to fix when url is static because from didn't see ti when u press save button on second time let success = false; if (newsItem) { news.id = newsItem.id; news.imageId = imageId.current; - news.image = newsItem.image; + news.image = image.current; Promise.all([ newsStore .updateNews(news) @@ -209,12 +219,8 @@ const NewsModal: React.FC<{ } }; - const handleInit = (value: any, editor: any) => { - setCount(editor.getContent({ format: "text" }).length); - }; - const handleUpdate = (value: any, editor: any) => { - const cCount = editor.getContent({ format: "text" }).length; + const cCount = editor.getContent({ format: 'text' }).length; if (cCount <= sizeLimit) { setData(value); setCount(cCount); @@ -222,7 +228,7 @@ const NewsModal: React.FC<{ }; const handleBeforeAddUndo = (evt: any, editor: any) => { - const cCount = editor.getContent({ format: "text" }).length; + const cCount = editor.getContent({ format: 'text' }).length; if (cCount > sizeLimit) { evt.preventDefault(); } @@ -236,9 +242,11 @@ const NewsModal: React.FC<{ onCancel={closeModal} className="modalContainer" footer={null} - closeIcon={ - - } + closeIcon={( + + + + )} >
@@ -301,7 +310,6 @@ const NewsModal: React.FC<{ onBeforeAddUndo={handleBeforeAddUndo} onInit={(evt, editor) => { editorRef.current = editor; - handleInit; }} initialValue={newsItem ? newsItem.text : ''} init={{ @@ -323,7 +331,10 @@ const NewsModal: React.FC<{ 'body { font-family:Roboto,Helvetica Neue,sans-serif; font-size:14px }', }} /> -

Remaining: {sizeLimit - count}

+

+ Remaining: + {sizeLimit - count} +

{!textIsPresent && textIsChanged && (

Введіть текст

)} @@ -339,6 +350,30 @@ const NewsModal: React.FC<{ return e?.fileList; }} className="image-form-item" + rules={[{ + required: true, + message: 'Додайте зображення', + }, + { + validator: (_, file) => { + if (file) { + let name = ''; + if (file.file) { + name = file.file.name.toLowerCase(); + } else if (file.name) { + name = file.name.toLowerCase(); + } + if (name.endsWith('.jpeg') || name.endsWith('.png') + || name.endsWith('.webp') || name.endsWith('.jpg') || name === '') { + return Promise.resolve(); + } + // eslint-disable-next-line max-len + return Promise.reject(Error('Тільки файли з розширенням webp, jpeg, png, jpg дозволені!')); + } + return Promise.reject(); + }, + }, + ]} > { imageId.current = img.id; + image.current = img as Image; if (newsItem) { newsItem.image = img as Image; } @@ -374,8 +410,12 @@ const NewsModal: React.FC<{

Виберіть чи перетягніть файл

- - + + { @@ -45,25 +45,45 @@ const StreetcodeSlider = () => { const shuffleSeed = Math.floor(Date.now() / 1000); const { fetchNextPage } = paginateRequest(3, StreetcodesApi.getPageMainPage, { shuffleSeed }); + let streetcodesAmount: number; if (!loading.current) { loading.current = true; + try { + streetcodesAmount = await StreetcodesApi.getCount(true); + } catch (e: any) { + streetcodesAmount = 32; // fetch 32 streetcodes if StreetcodesApi.getCount fails + } + + const emptyStreetcodes = Array(streetcodesAmount).fill({}); + setStreetcodes(emptyStreetcodes); + while (true) { try { - const newStreetcodes = await fetchNextPage(); - setStreetcodes((prevState) => [...prevState, ...newStreetcodes]); + const [newStreetcodes, startIdx, endIdx] = await fetchNextPage(); + // eslint-disable-next-line @typescript-eslint/no-loop-func + setStreetcodes((prevState) => { + // replace empty objects to fetched streetcodes + const newState = [ + ...prevState.slice(0, startIdx), + ...newStreetcodes, + ...prevState.slice(endIdx), + ]; + + return newState; + }); const newImages: Image[] = []; const promises = []; + // eslint-disable-next-line no-plusplus for (let i = 0; i < newStreetcodes.length; i++) { - const currentPosition = newImages.length + i; promises.push(ImagesApi.getById(newStreetcodes[i].imageId).then((img) => { - newImages[currentPosition] = img; + newImages[i] = img; })); } await Promise.all(promises).then(() => { - setImages((prevState) => [...prevState, ...newImages]); + setImages((prevState) => [...prevState, ...newImages].slice(0, streetcodesAmount)); }); } catch (error: unknown) { break; diff --git a/src/features/MainPage/StreetcodeSlider/StreetcodeSlider.styles.scss b/src/features/MainPage/StreetcodeSlider/StreetcodeSlider.styles.scss index cdf41bb88..3ce40d65f 100644 --- a/src/features/MainPage/StreetcodeSlider/StreetcodeSlider.styles.scss +++ b/src/features/MainPage/StreetcodeSlider/StreetcodeSlider.styles.scss @@ -30,11 +30,21 @@ $bgImg: '@assets/images/streetcode-card/background.webp'; ::-webkit-scrollbar { width: f.pxToRem(5px); } + + @media (min-width: 768px) and (max-width: 1024px) { + .slick-center{ + padding: 0 f.pxToRem(20px); + } + + .slick-list{ + height: 30rem; + } + } } .slick-slide { width: unset !important; - + @media screen and (max-width: 767px) { width: 100% !important; } @@ -60,4 +70,4 @@ $bgImg: '@assets/images/streetcode-card/background.webp'; padding-bottom: f.pxToRem(20px); } } -} \ No newline at end of file +} diff --git a/src/features/MainPage/StreetcodeSlider/StreetcodeSliderItem/StreetcodeSliderItem.component.tsx b/src/features/MainPage/StreetcodeSlider/StreetcodeSliderItem/StreetcodeSliderItem.component.tsx index 088c50974..997248b87 100644 --- a/src/features/MainPage/StreetcodeSlider/StreetcodeSliderItem/StreetcodeSliderItem.component.tsx +++ b/src/features/MainPage/StreetcodeSlider/StreetcodeSliderItem/StreetcodeSliderItem.component.tsx @@ -32,7 +32,7 @@ const StreetcodeSliderItem = ({ streetcode, image }: Props) => {
-
+
{image?.id ? ( { +export enum DatePickerType { + Date = 'date', + Month = 'month', + SeasonYear = 'season-year', + Year = 'year', +} + +export const dateToString = (typeDate:DatePickerType, date: Dayjs | null):string => { dayjs.locale('uk'); if (!date) { return ''; } - if (typeDate === 'date') { + if (typeDate === DatePickerType.Date) { return date.format('D MMMM YYYY'); } - if (typeDate === 'month') { + if (typeDate === DatePickerType.Month) { return date.format('MMMM YYYY'); } const year = date.format('YYYY'); - if (typeDate === 'year') { + if (typeDate === DatePickerType.Year) { return year; } return `${getSeason(date)} ${year}`;