diff --git a/package-lock.json b/package-lock.json
index 4b7a91c..3bb1324 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12,6 +12,7 @@
"@testing-library/react": "^12.1.2",
"@testing-library/user-event": "^13.5.0",
"axios": "^0.25.0",
+ "jalaali-js": "^1.2.3",
"jalali-moment": "^3.3.10",
"lord-icon-element": "^3.3.3",
"lottie-web": "^5.8.1",
@@ -9402,6 +9403,11 @@
"resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
"integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0="
},
+ "node_modules/jalaali-js": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/jalaali-js/-/jalaali-js-1.2.3.tgz",
+ "integrity": "sha512-irl0pXL59Xl0Oz6jyOiJed/NxrVeS6fSx6a8atQOH/LsPWPZwBCxwe5XVEIqjnwt69FRxvnCCwQn5dTMxwbazQ=="
+ },
"node_modules/jalali-moment": {
"version": "3.3.11",
"resolved": "https://registry.npmjs.org/jalali-moment/-/jalali-moment-3.3.11.tgz",
@@ -24081,6 +24087,11 @@
}
}
},
+ "jalaali-js": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/jalaali-js/-/jalaali-js-1.2.3.tgz",
+ "integrity": "sha512-irl0pXL59Xl0Oz6jyOiJed/NxrVeS6fSx6a8atQOH/LsPWPZwBCxwe5XVEIqjnwt69FRxvnCCwQn5dTMxwbazQ=="
+ },
"jalali-moment": {
"version": "3.3.11",
"resolved": "https://registry.npmjs.org/jalali-moment/-/jalali-moment-3.3.11.tgz",
diff --git a/package.json b/package.json
index a6b04c3..c18a747 100644
--- a/package.json
+++ b/package.json
@@ -7,6 +7,7 @@
"@testing-library/react": "^12.1.2",
"@testing-library/user-event": "^13.5.0",
"axios": "^0.25.0",
+ "jalaali-js": "^1.2.3",
"jalali-moment": "^3.3.10",
"lord-icon-element": "^3.3.3",
"lottie-web": "^5.8.1",
diff --git a/src/App.js b/src/App.js
index c89c0ba..fd593c9 100644
--- a/src/App.js
+++ b/src/App.js
@@ -652,7 +652,14 @@ function App() {
{LOGIN && }
{LOGIN && }
- } />
+
+ : } />
} />
} />
} />
- } />
+ />} /> */}
} />
diff --git a/src/assets/img/stickynote.svg b/src/assets/img/stickynote.svg
new file mode 100644
index 0000000..e268029
--- /dev/null
+++ b/src/assets/img/stickynote.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/img/vuesax-linear-direct-left.svg b/src/assets/img/vuesax-linear-direct-left.svg
index 134353a..927141c 100644
--- a/src/assets/img/vuesax-linear-direct-left.svg
+++ b/src/assets/img/vuesax-linear-direct-left.svg
@@ -1,8 +1,8 @@
-
-
+
+
diff --git a/src/components/Calendar/CalendarComponents/Calendar.js b/src/components/Calendar/CalendarComponents/Calendar.js
new file mode 100644
index 0000000..574b186
--- /dev/null
+++ b/src/components/Calendar/CalendarComponents/Calendar.js
@@ -0,0 +1,341 @@
+import React, { useState, useRef, useEffect } from 'react';
+import moment from "jalali-moment";
+import './dateBox.css'
+import {
+ getDateAccordingToMonth,
+ shallowClone,
+ getValueType,
+} from './shared/generalUtils';
+import {
+ TYPE_SINGLE_DATE,
+ TYPE_RANGE,
+ TYPE_MUTLI_DATE,
+} from './shared/constants';
+import { useLocaleUtils, useLocaleLanguage } from './shared/hooks';
+
+import { Header, MonthSelector, YearSelector, DaysList } from './components';
+import { VscCircleFilled } from "react-icons/vsc";
+import { GoPrimitiveDot } from "react-icons/go";
+// import { IoDocumentTextOutline } from "react-icons/io";
+
+// import Exam from '../azmoon-list/Exam';
+import { IoDocumentTextOutline } from "react-icons/io5";
+const Clock = () => {
+ let today = new Date();
+ let h = today.getHours();
+ let m = today.getMinutes();
+ // const [h,setH]=useState(today.getHours());
+ // const [m, setM] = useState(today.getMinutes());
+ // const [s, setS] = useState(today.getSeconds());
+ const [counter, setCounter] = useState(0);
+
+ setTimeout(() => {
+ setCounter(counter + 1);
+ }, 1000);
+
+ return (
+
+ ساعت
+ {h < 10 ? "0" + h : h}:{m < 10 ? "0" + m : m}
+
+ );
+}
+
+var today = new Date();
+// var time = today.getHours() + ":" + today.getMinutes();
+
+let m = moment();
+// -------get-date--------------------
+let date = m.jDate();
+//----------get-day-and month------------------
+let day = m.jDay();
+let monthNum = m.jMonth() + 1;
+//create-week---------------------------
+let date_list;
+let active_list;
+
+ const Calendar = ({
+ value,
+ onChange,
+ onDisabledDayError,
+ calendarClassName,
+ calendarTodayClassName,
+ calendarSelectedDayClassName,
+ calendarRangeStartClassName,
+ calendarRangeBetweenClassName,
+ calendarRangeEndClassName,
+ disabledDays,
+ colorPrimary,
+ colorPrimaryLight,
+ slideAnimationDuration,
+ minimumDate,
+ maximumDate,
+ selectorStartingYear,
+ selectorEndingYear,
+ locale,
+ shouldHighlightWeekends,
+ renderFooter,
+ customDaysClassName,
+ events,
+ renderEvents,
+ type
+}) => {
+ const calendarElement = useRef(null);
+ const [mainState, setMainState] = useState({
+ activeDate: null,
+ monthChangeDirection: '',
+ isMonthSelectorOpen: false,
+ isYearSelectorOpen: false,
+ });
+ const [eventInFooter, setEventInFooter] = useState(null);
+ useEffect(() => {
+ const handleKeyUp = ({ key }) => {
+ /* istanbul ignore else */
+ if (key === 'Tab')
+ calendarElement.current.classList.remove('-noFocusOutline');
+ };
+ calendarElement.current.addEventListener('keyup', handleKeyUp, false);
+ return () => {
+ // calendarElement.current.removeEventListener('keyup', handleKeyUp, false);
+ };
+ });
+
+ const { getToday } = useLocaleUtils(locale);
+ const { weekDays: weekDaysList, isRtl } = useLocaleLanguage(locale);
+ const today = getToday();
+
+ const createStateToggler = (property) => () => {
+ setMainState({ ...mainState, [property]: !mainState[property] });
+ };
+
+ const toggleMonthSelector = createStateToggler('isMonthSelectorOpen');
+ const toggleYearSelector = createStateToggler('isYearSelectorOpen');
+
+ const getComputedActiveDate = () => {
+ const valueType = getValueType(value);
+ if (valueType === TYPE_MUTLI_DATE && value.length)
+ return shallowClone(value[0]);
+ if (valueType === TYPE_SINGLE_DATE && value) return shallowClone(value);
+ if (valueType === TYPE_RANGE && value.from) return shallowClone(value.from);
+ return shallowClone(today);
+ };
+
+ const activeDate = mainState.activeDate
+ ? shallowClone(mainState.activeDate)
+ : getComputedActiveDate();
+
+ const weekdays = weekDaysList.map((weekDay) => (
+
+ { type == 'dashboard' ? weekDay.name : weekDay.short}
+
+ ));
+
+ const handleMonthChange = (direction) => {
+ setMainState({
+ ...mainState,
+ monthChangeDirection: direction,
+ });
+ };
+
+ const updateDate = () => {
+ setMainState({
+ ...mainState,
+ activeDate: getDateAccordingToMonth(
+ activeDate,
+ mainState.monthChangeDirection
+ ),
+ monthChangeDirection: '',
+ });
+ };
+
+ const selectMonth = (newMonthNumber) => {
+ setMainState({
+ ...mainState,
+ activeDate: { ...activeDate, month: newMonthNumber },
+ isMonthSelectorOpen: false,
+ });
+ };
+
+ const selectYear = (year) => {
+ setMainState({
+ ...mainState,
+ activeDate: { ...activeDate, year },
+ isYearSelectorOpen: false,
+ });
+ };
+ let year = m.jYear();
+ // ------get---month---------
+ // let monthNum = m.jMonth()+1;
+ let month;
+ switch (monthNum) {
+ case 1:
+ month = "فروردین";
+ break;
+ case 2:
+ month = "اردیبهشت";
+ break;
+ case 3:
+ month = "خرداد";
+ break;
+ case 4:
+ month = "تیر";
+ break;
+ case 5:
+ month = "مرداد";
+ break;
+ case 6:
+ month = "شهریور";
+ break;
+ case 7:
+ month = "مهر";
+ break;
+ case 8:
+ month = "آبان";
+ break;
+ case 9:
+ month = "آذر";
+ break;
+ case 10:
+ month = "دی";
+ break;
+ case 11:
+ month = "بهمن";
+ break;
+ case 12:
+ month = "اسفند";
+ break;
+ default:
+ month = "فروردین";
+ break;
+ }
+ // console.log("oooo"+m.jDay());
+
+ // const SetTime =()=>{
+ // setTimeout(()=>{
+ // set_time(today.getHours() + ":" + today.getMinutes());
+ // },1000);
+ // SetTime();
+ // // console.log("tic");
+ // }
+
+
+
+ return (
+
+ {/*
*/}
+
+
+
+
+
+
+
{weekdays}
+
+
setEventInFooter(event)}
+ type={type}
+ />
+
+ {/*
+ {
+ type == 'dashboard' ? <>
رویداد ها:
{eventInFooter ? eventInFooter : 'رویدادی در این روز وجود ندارد!'}
> : eventInFooter
+ }
+
+
+
+ {renderFooter()} */}
+
+
+ );
+};
+
+Calendar.defaultProps = {
+ minimumDate: null,
+ maximumDate: null,
+ colorPrimary: '#0eca2d',
+ colorPrimaryLight: '#cff4d5',
+ slideAnimationDuration: '0.4s',
+ calendarClassName: '',
+ locale: 'en',
+ value: null,
+ renderFooter: () => null,
+ renderEvents : () => null,
+ customDaysClassName: [],
+ events: [],
+};
+
+
+export default Calendar;
\ No newline at end of file
diff --git a/src/components/Calendar/CalendarComponents/DatePicker.css b/src/components/Calendar/CalendarComponents/DatePicker.css
new file mode 100644
index 0000000..c7010fb
--- /dev/null
+++ b/src/components/Calendar/CalendarComponents/DatePicker.css
@@ -0,0 +1,672 @@
+.DatePicker {
+ position: relative;
+ display: inline-block;
+ z-index: 100;
+}
+
+.DatePicker__input {
+ background: #fff;
+ border: 1px solid #ddd;
+ padding: 0.4em 0.8em;
+ font-family: inherit;
+ text-align: center;
+ font-size: 12px;
+}
+
+.DatePicker__input.-rtl {
+ direction: rtl;
+}
+
+.DatePicker__input::placeholder {
+ color: #979797;
+}
+
+.DatePicker__calendarContainer.-top + .DatePicker__calendarArrow {
+ top: auto;
+ bottom: calc(100% + 10px);
+ transform: translateY(-2.5rem) rotate(180deg);
+ animation: fadeArrowFlipped 0.3s forwards;
+}
+
+.DatePicker__calendarContainer {
+ position: absolute;
+ top: calc(100% + 20px);
+ left: 50%;
+ transform: translateX(-50%);
+}
+
+.DatePicker__calendarContainer.-top {
+ top: auto;
+ bottom: calc(100% + 20px);
+}
+
+.Calendar,
+.Calendar * {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ direction: ltr;
+}
+
+.Calendar,
+.Calendar.-rtl * {
+ direction: rtl;
+}
+
+.DatePicker__calendarArrow {
+ position: absolute;
+ width: 0;
+ height: 0;
+ top: calc(100% + 10px);
+ left: 0;
+ right: 0;
+ margin: 0 auto;
+ border-style: solid;
+ z-index: 10;
+ border-width: 0 10px 10px 10px;
+ border-color: transparent transparent #fff transparent;
+}
+
+.Calendar {
+ --cl-color-black: #444444;
+ --cl-color-disabled: #d4d4d4;
+ --cl-color-error: #ff2929;
+ font-size: 10px;
+ background: #fff;
+ box-shadow: 0 1em 4em rgba(0, 0, 0, 0.07);
+ border-radius: 1em;
+ position: relative;
+ user-select: none;
+ padding-top: 1.2em;
+ display: flex;
+ flex-direction: column;
+ width: 33em;
+ z-index: 10;
+ max-width: 90vw;
+ min-height: 36.7em;
+}
+
+.DatePicker .Calendar,
+.DatePicker__calendarArrow {
+ transform: translateY(2.5em);
+ opacity: 0;
+ animation: fadeCalendar 0.3s forwards;
+}
+
+.DatePicker__calendarContainer.-top .Calendar {
+ transform: translateY(-2.5em);
+}
+
+.Calendar.-noFocusOutline *:focus {
+ outline: none !important;
+}
+
+.Calendar > :not(.Calendar__footer) button {
+ font-family: inherit;
+ background: transparent;
+ cursor: pointer;
+ -webkit-tap-highlight-color: transparent;
+ outline: none;
+}
+
+.Calendar__header {
+ display: flex;
+ color: var(--cl-color-black);
+ padding: 2em 2.9em;
+ align-items: center;
+ overflow: hidden;
+}
+
+.Calendar__monthArrowWrapper {
+ line-height: 0;
+ font-size: 1em;
+ padding: 3px;
+ position: relative;
+ border: none;
+ z-index: 1;
+ opacity: 1;
+ transition: 0.2s;
+}
+
+.Calendar__monthArrowWrapper:focus {
+ outline: 1px dashed rgba(0, 0, 0, 0.4);
+ outline-offset: 2px;
+}
+
+.Calendar__monthArrowWrapper:disabled,
+.Calendar__monthArrowWrapper.-hidden {
+ opacity: 0;
+ pointer-events: none;
+}
+
+.Calendar__monthArrowWrapper.-left {
+ transform: rotate(90deg);
+}
+.Calendar.-rtl .Calendar__monthArrowWrapper.-left {
+ transform: rotate(-90deg);
+}
+
+.Calendar__monthArrowWrapper.-right {
+ transform: rotate(-90deg);
+}
+.Calendar.-rtl .Calendar__monthArrowWrapper.-right {
+ transform: rotate(90deg);
+}
+
+.Calendar__monthArrowWrapper:active .Calendar__monthArrow {
+ transform: scale(0.7);
+}
+
+.Calendar__monthArrow {
+ border-radius: 50%;
+ transition: var(--animation-duration) transform;
+ pointer-events: none;
+ background-repeat: no-repeat;
+ display: block;
+ width: 1.7em;
+ height: 1.7em;
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cg class='nc-icon-wrapper' fill='%23000000'%3E%3Cdefs stroke='none'%3E%3C/defs%3E%3Cpath class='cls-1' d='M12 23.25V.75' fill='none' stroke='%23000000' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5px'%3E%3C/path%3E%3Cpath class='cls-2' d='M22.5 11.25L12 .75 1.5 11.25' fill='none' stroke='%23000000' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5px' fill-rule='evenodd'%3E%3C/path%3E%3C/g%3E%3C/svg%3E");
+ background-size: 100% 100%;
+}
+
+.Calendar__monthYearContainer {
+ flex: 1;
+ position: relative;
+}
+
+.Calendar__monthYear {
+ font-size: 1.6em;
+ font-weight: 500;
+ display: flex;
+ align-items: center;
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 50%;
+ will-change: transform, opacity;
+ backface-visibility: hidden;
+ transform: translateZ(0);
+ transition: var(--animation-duration);
+ line-height: 1;
+}
+
+.Calendar__monthYear.-hiddenNext {
+ opacity: 0;
+ transform: translateX(50%);
+}
+
+.Calendar.-rtl .Calendar__monthYear.-hiddenNext {
+ transform: translateX(-150%);
+}
+
+.Calendar__monthYear.-hiddenPrevious {
+ opacity: 0;
+ transform: translateX(-150%);
+}
+
+.Calendar.-rtl .Calendar__monthYear.-hiddenPrevious {
+ transform: translateX(50%);
+}
+
+.Calendar__monthYear.-shown {
+ opacity: 1;
+ margin-top: auto;
+ margin-bottom: auto;
+ transform: translateX(-50%);
+}
+
+.Calendar__monthYear.-shownAnimated {
+ animation: var(--animation-duration) fadeTextToCenter forwards;
+}
+
+.Calendar__monthYear > * {
+ padding: 0.2em 0.5em;
+ border: 1px solid transparent;
+ transition: var(--animation-duration);
+ font-size: 1.05em;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ transform: translateX(0) scale(0.95);
+ will-change: transform;
+ border-radius: 5px;
+}
+
+.Calendar__monthYear:not(.-shown) > *,
+.Calendar__monthYear > *.-hidden {
+ cursor: default;
+ pointer-events: none;
+}
+
+.Calendar__monthText {
+ margin-left: -0.3em;
+}
+.Calendar__yearText:last-child {
+ margin-right: -0.3em;
+}
+
+.Calendar__monthYear.-shown > *:hover,
+.Calendar:not(.-noFocusOutline) .Calendar__monthYear.-shown > *:focus,
+.Calendar__monthYear > *.-activeBackground {
+ background: #f5f5f5;
+}
+
+.Calendar__monthText:hover {
+ transform: translateX(-0.2em) scale(0.95);
+}
+.Calendar.-rtl .Calendar__monthText:hover {
+ transform: translateX(0.2em) scale(0.95);
+}
+
+.Calendar__yearText:hover {
+ transform: translateX(0.2em) scale(0.95);
+}
+.Calendar.-rtl .Calendar__yearText:hover {
+ transform: translateX(-0.2em) scale(0.95);
+}
+
+.Calendar__monthYear .Calendar__yearText.-hidden {
+ transform: translateX(50%);
+ opacity: 0;
+}
+
+.Calendar.-rtl .Calendar__monthYear .Calendar__yearText.-hidden {
+ transform: translateX(-50%);
+}
+
+.Calendar__monthYear .Calendar__monthText.-hidden {
+ transform: translateX(-50%);
+ opacity: 0;
+}
+
+.Calendar.-rtl .Calendar__monthYear .Calendar__monthText.-hidden {
+ transform: translateX(50%);
+}
+
+.Calendar__monthYear:not(.-shown) > * {
+ pointer-events: none;
+}
+
+.Calendar__monthSelectorAnimationWrapper,
+.Calendar__yearSelectorAnimationWrapper {
+ position: absolute;
+ width: 100%;
+ height: 80%;
+ bottom: 0;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ overflow: hidden;
+}
+
+.Calendar__monthSelectorWrapper {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.Calendar__monthSelector {
+ padding: 0 2.5em;
+ align-content: center;
+ padding-bottom: 2em;
+}
+
+.Calendar__monthSelector,
+.Calendar__yearSelector {
+ display: flex;
+ flex-wrap: wrap;
+ position: relative;
+ z-index: 2;
+ background-color: #fff;
+ transform: translateY(-150%);
+ will-change: transform;
+ transition: 0.6s;
+ height: 100%;
+}
+
+.Calendar__yearSelectorWrapper {
+ width: 100%;
+ height: 100%;
+}
+
+.Calendar__yearSelectorWrapper::after,
+.Calendar__yearSelectorWrapper::before {
+ content: '';
+ width: 100%;
+ height: 5em;
+ position: absolute;
+ left: 0;
+ opacity: 0;
+ transition: 0.4s;
+ transition-delay: 0.2s;
+}
+
+.Calendar__yearSelectorWrapper::after {
+ background-image: linear-gradient(to bottom, #fff, #fff 10%, rgba(245, 245, 245, 0));
+ top: -0.1em;
+}
+
+.Calendar__yearSelectorWrapper::before {
+ background-image: linear-gradient(to top, #fff, #fff 10%, rgba(245, 245, 245, 0));
+ bottom: 0;
+}
+
+.Calendar__yearSelectorWrapper.-faded::after,
+.Calendar__yearSelectorWrapper.-faded::before {
+ opacity: 1;
+ z-index: 3;
+}
+
+.Calendar__yearSelector {
+ align-content: flex-start;
+ scrollbar-width: 0;
+ overflow: scroll;
+ position: relative;
+ width: 100%;
+ padding: 5em 2em;
+ -ms-overflow-style: none;
+}
+
+.Calendar__yearSelector::-webkit-scrollbar {
+ display: none;
+}
+
+.Calendar__yearSelectorItem {
+ width: 25%;
+ display: flex;
+ justify-content: center;
+}
+
+.Calendar__yearSelectorItem:not(:nth-child(-n + 4)) {
+ margin-top: 1.5em;
+}
+
+.Calendar__yearSelectorText {
+ border: none;
+ font-size: 1.4em;
+ min-width: 85%;
+ padding: 0.2em 0.5em;
+ border-radius: 8.5px;
+}
+
+.Calendar__monthSelector.-open,
+.Calendar__yearSelector.-open {
+ transform: translateY(0);
+}
+
+.Calendar__yearSelectorText:focus,
+.Calendar__monthSelectorItemText:focus {
+ outline: 1px dashed rgba(0, 0, 0, 0.4);
+ outline-offset: 2px;
+}
+
+.Calendar__monthSelectorItem {
+ width: calc(100% / 3);
+ display: flex;
+ justify-content: center;
+}
+
+.Calendar__monthSelectorItem:not(:nth-child(-n + 3)) {
+ margin-top: 2em;
+}
+
+.Calendar__monthSelectorItemText {
+ border: none;
+ padding: 0.4em 0.4em;
+ border-radius: 8.5px;
+ font-size: 1.3em;
+ min-width: 70%;
+ transition: 0.3s;
+}
+
+.Calendar__monthSelectorItem:not(.-active) .Calendar__monthSelectorItemText:not(:disabled):hover,
+.Calendar__yearSelectorItem:not(.-active) .Calendar__yearSelectorText:not(:disabled):hover {
+ background: #f5f5f5;
+}
+
+.Calendar__monthSelectorItemText:disabled,
+.Calendar__yearSelectorText:disabled {
+ opacity: 0.5;
+ cursor: default;
+}
+
+.Calendar__monthSelectorItem.-active .Calendar__monthSelectorItemText,
+.Calendar__yearSelectorItem.-active .Calendar__yearSelectorText {
+ background-color: var(--cl-color-primary);
+ color: #fff;
+}
+
+.Calendar__weekDays {
+ display: flex;
+ justify-content: space-between;
+ color: var(--cl-color-disabled);
+ font-size: 1.2em;
+ margin-bottom: 0.7em;
+ padding: 0 2.6em;
+ position: relative;
+}
+
+.Calendar__weekDay {
+ display: block;
+ width: calc(100% / 7);
+ text-align: center;
+ text-decoration: none;
+}
+
+.Calendar__sectionWrapper {
+ position: relative;
+ min-height: 25.8em;
+ overflow: hidden;
+}
+
+.Calendar__section {
+ display: flex;
+ flex-direction: column;
+ padding: 0 3.2em;
+ position: absolute;
+ color: var(--cl-color-black);
+ top: 0;
+ padding-top: 0.5em;
+ left: 0;
+ width: 100%;
+ will-change: transform, opacity;
+ transform: translateZ(0);
+ backface-visibility: hidden;
+ transition: var(--animation-duration);
+}
+
+.Calendar__section.-hiddenPrevious {
+ opacity: 0.5;
+ transform: translateX(-90%);
+}
+
+.Calendar.-rtl .Calendar__section.-hiddenPrevious {
+ transform: translateX(90%);
+}
+
+.Calendar__section.-hiddenNext {
+ opacity: 0.5;
+ transform: translateX(90%);
+}
+
+.Calendar.-rtl .Calendar__section.-hiddenNext {
+ transform: translateX(-90%);
+}
+
+.Calendar__section.-shown {
+ opacity: 1;
+ transform: translateX(0);
+}
+
+.Calendar__section.-shownAnimated {
+ animation: var(--animation-duration) FadeContentToCenter forwards;
+}
+
+.Calendar__weekRow {
+ display: flex;
+ width: 100%;
+}
+
+.Calendar__day {
+ display: block;
+ width: calc(100% / 7);
+ text-align: center;
+ padding: calc(0.25em - 1px) 0;
+ font-size: 1.6em;
+ border-radius: 50%;
+ transition: 0.2s;
+ border: 1px solid transparent;
+ margin-bottom: 0.3em;
+ color: rgba(0, 0, 0, 0.8);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ cursor: pointer;
+}
+
+.Calendar__day:focus {
+ outline: 1px dashed rgba(0, 0, 0, 0.4);
+ outline-offset: 2px;
+}
+
+.Calendar__day.-ltr {
+ min-height: 2.6em;
+ font-size: 1.45em;
+}
+
+.Calendar__day.-rtl {
+ font-size: 1.55em;
+ height: 2.45em;
+}
+
+.Calendar__day:not(.-blank):not(.-selectedStart):not(.-selectedEnd):not(.-selectedBetween):not(.-selected):hover {
+ background: #eaeaea;
+ border-radius: 50%;
+ color: var(--cl-color-black);
+ border-color: transparent;
+}
+
+.Calendar__day.-selected,
+.Calendar__day.-selectedStart,
+.Calendar__day.-selectedEnd {
+ background: var(--cl-color-primary);
+ color: #fff;
+}
+
+.Calendar__day.-ltr.-selectedStart {
+ border-radius: 0;
+ border-top-left-radius: 100em;
+ border-bottom-left-radius: 100em;
+}
+
+.Calendar__day.-rtl.-selectedStart {
+ border-radius: 0;
+ border-top-right-radius: 100em;
+ border-bottom-right-radius: 100em;
+}
+
+.Calendar__day.-selectedBetween {
+ background: var(--cl-color-primary-light);
+ color: var(--cl-color-primary);
+ border-radius: 0;
+}
+
+.Calendar__day.-ltr.-selectedEnd {
+ border-top-right-radius: 100em;
+ border-bottom-right-radius: 100em;
+}
+
+.Calendar__day.-rtl.-selectedEnd {
+ border-top-left-radius: 100em;
+ border-bottom-left-radius: 100em;
+}
+
+.Calendar__day.-weekend:not(.-selected):not(.-blank):not(.-selectedStart):not(.-selectedEnd):not(.-selectedBetween) {
+ color: var(--cl-color-error);
+}
+
+.Calendar__day.-weekend.-today:not(.-selectedStart):not(.-selectedEnd):not(.-selectedBetween)::after {
+ background: var(--cl-color-error);
+}
+
+.Calendar__day.-disabled {
+ color: var(--cl-color-disabled) !important;
+ background: transparent !important;
+ cursor: default !important;
+}
+.Calendar__day.-selected {
+ border-radius: 50%;
+}
+.Calendar__day.-today:not(.-selectedStart):not(.-selectedEnd):not(.-selectedBetween) {
+ font-weight: 600;
+ color: var(--cl-color-black);
+ color: #000;
+ position: relative;
+}
+
+.Calendar__day.-today:not(.-selectedStart):not(.-selectedEnd):not(.-selectedBetween)::after {
+ content: '';
+ position: absolute;
+ bottom: 0.2em;
+ display: block;
+ width: 0.6em;
+ height: 1px;
+ background: #000;
+ left: 50%;
+ opacity: 0.5;
+ transform: translateX(-50%);
+ transition: 0.2s;
+}
+
+.Calendar__day.-today:hover:not(.-selectedStart):not(.-selectedEnd):not(.-selectedBetween)::after {
+ opacity: 0;
+}
+
+.Calendar__day.-blank {
+ color: transparent;
+ cursor: default;
+ pointer-events: none;
+}
+
+.Calendar__footer {
+ position: relative;
+ z-index: 1;
+}
+
+@keyframes fadeCalendar {
+ from {
+ opacity: 0;
+ }
+
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+@keyframes fadeArrowFlipped {
+ from {
+ opacity: 0;
+ }
+
+ to {
+ opacity: 1;
+ transform: translateY(0) rotate(180deg);
+ }
+}
+
+@keyframes fadeTextToCenter {
+ to {
+ opacity: 1;
+ transform: translateX(-50%);
+ }
+}
+
+@keyframes FadeContentToCenter {
+ to {
+ opacity: 1;
+ transform: translateX(0);
+ }
+}
diff --git a/src/components/Calendar/CalendarComponents/DatePicker.js b/src/components/Calendar/CalendarComponents/DatePicker.js
new file mode 100644
index 0000000..6f81669
--- /dev/null
+++ b/src/components/Calendar/CalendarComponents/DatePicker.js
@@ -0,0 +1,203 @@
+import React, { useState, useEffect, useRef, useLayoutEffect } from 'react';
+
+import Calendar from './Calendar';
+import DatePickerInput from './DatePickerInput';
+import { getValueType } from './shared/generalUtils';
+import { TYPE_SINGLE_DATE, TYPE_MUTLI_DATE, TYPE_RANGE } from './shared/constants';
+
+const DatePicker = ({
+ value,
+ onChange,
+ formatInputText,
+ inputPlaceholder,
+ inputClassName,
+ inputName,
+ renderInput,
+ wrapperClassName,
+ calendarClassName,
+ calendarTodayClassName,
+ calendarSelectedDayClassName,
+ calendarRangeStartClassName,
+ calendarRangeBetweenClassName,
+ calendarRangeEndClassName,
+ calendarPopperPosition,
+ disabledDays,
+ onDisabledDayError,
+ colorPrimary,
+ colorPrimaryLight,
+ slideAnimationDuration,
+ minimumDate,
+ maximumDate,
+ selectorStartingYear,
+ selectorEndingYear,
+ locale,
+ shouldHighlightWeekends,
+ renderFooter,
+ customDaysClassName,
+}) => {
+ const calendarContainerElement = useRef(null);
+ const inputElement = useRef(null);
+ const shouldPreventToggle = useRef(false);
+ const [isCalendarOpen, setCalendarVisiblity] = useState(false);
+
+ useEffect(() => {
+ const handleBlur = () => {
+ setCalendarVisiblity(false);
+ };
+ window.addEventListener('blur', handleBlur, false);
+ return () => {
+ window.removeEventListener('blur', handleBlur, false);
+ };
+ }, []);
+
+ // handle input focus/blur
+ useEffect(() => {
+ const valueType = getValueType(value);
+ if (valueType === TYPE_MUTLI_DATE) return; // no need to close the calendar
+ const shouldCloseCalendar =
+ valueType === TYPE_SINGLE_DATE ? !isCalendarOpen : !isCalendarOpen && value.from && value.to;
+ if (shouldCloseCalendar) inputElement.current.blur();
+ }, [value, isCalendarOpen]);
+
+ const handleBlur = e => {
+ e.persist();
+ if (!isCalendarOpen) return;
+ const isInnerElementFocused = calendarContainerElement.current.contains(e.relatedTarget);
+ if (shouldPreventToggle.current) {
+ shouldPreventToggle.current = false;
+ inputElement.current.focus();
+ } else if (isInnerElementFocused && e.relatedTarget) {
+ e.relatedTarget.focus();
+ } else {
+ setCalendarVisiblity(false);
+ }
+ };
+
+ const openCalendar = () => {
+ if (!shouldPreventToggle.current) setCalendarVisiblity(true);
+ };
+
+ // Keep the calendar in the screen bounds if input is near the window edges
+ useLayoutEffect(() => {
+ if (!isCalendarOpen) return;
+ const { left, width, height, top } = calendarContainerElement.current.getBoundingClientRect();
+ const { clientWidth, clientHeight } = document.documentElement;
+ const isOverflowingFromRight = left + width > clientWidth;
+ const isOverflowingFromLeft = left < 0;
+ const isOverflowingFromBottom = top + height > clientHeight;
+
+ const getLeftStyle = () => {
+ const overflowFromRightDistance = left + width - clientWidth;
+
+ if (!isOverflowingFromRight && !isOverflowingFromLeft) return;
+ const overflowFromLeftDistance = Math.abs(left);
+ const rightPosition = isOverflowingFromLeft ? overflowFromLeftDistance : 0;
+
+ const leftStyle = isOverflowingFromRight
+ ? `calc(50% - ${overflowFromRightDistance}px)`
+ : `calc(50% + ${rightPosition}px)`;
+ return leftStyle;
+ };
+
+ calendarContainerElement.current.style.left = getLeftStyle();
+ if (
+ (calendarPopperPosition === 'auto' && isOverflowingFromBottom) ||
+ calendarPopperPosition === 'top'
+ ) {
+ calendarContainerElement.current.classList.add('-top');
+ }
+ }, [isCalendarOpen]);
+
+ const handleCalendarChange = newValue => {
+ const valueType = getValueType(value);
+ onChange(newValue);
+ if (valueType === TYPE_SINGLE_DATE) setCalendarVisiblity(false);
+ else if (valueType === TYPE_RANGE && newValue.from && newValue.to) setCalendarVisiblity(false);
+ };
+
+ const handleKeyUp = ({ key }) => {
+ switch (key) {
+ case 'Enter':
+ setCalendarVisiblity(true);
+ break;
+ case 'Escape':
+ setCalendarVisiblity(false);
+ shouldPreventToggle.current = true;
+ break;
+ }
+ };
+
+ useEffect(() => {
+ if (!isCalendarOpen && shouldPreventToggle.current) {
+ inputElement.current.focus();
+ shouldPreventToggle.current = false;
+ }
+ }, [shouldPreventToggle, isCalendarOpen]);
+
+ return (
+
+
+ {isCalendarOpen && (
+ <>
+
{
+ shouldPreventToggle.current = true;
+ }}
+ >
+
+
+
+ >
+ )}
+
+ );
+};
+
+DatePicker.defaultProps = {
+ wrapperClassName: '',
+ locale: 'en',
+ calendarPopperPosition: 'auto',
+};
+
+export default DatePicker;
diff --git a/src/components/Calendar/CalendarComponents/DatePickerInput.js b/src/components/Calendar/CalendarComponents/DatePickerInput.js
new file mode 100644
index 0000000..30d3ee7
--- /dev/null
+++ b/src/components/Calendar/CalendarComponents/DatePickerInput.js
@@ -0,0 +1,93 @@
+import React from 'react';
+
+import { useLocaleUtils, useLocaleLanguage } from './shared/hooks';
+import { putZero, getValueType } from './shared/generalUtils';
+import { TYPE_SINGLE_DATE, TYPE_RANGE, TYPE_MUTLI_DATE } from './shared/constants';
+
+const DatePickerInput = React.forwardRef(
+ (
+ { value, inputPlaceholder, inputClassName, inputName, formatInputText, renderInput, locale },
+ ref,
+ ) => {
+ const { getLanguageDigits } = useLocaleUtils(locale);
+ const {
+ from: fromWord,
+ to: toWord,
+ yearLetterSkip,
+ digitSeparator,
+ defaultPlaceholder,
+ isRtl,
+ } = useLocaleLanguage(locale);
+
+ const getSingleDayValue = () => {
+ if (!value) return '';
+ const year = getLanguageDigits(value.year);
+ const month = getLanguageDigits(putZero(value.month));
+ const day = getLanguageDigits(putZero(value.day));
+ return `${year}/${month}/${day}`;
+ };
+
+ const getDayRangeValue = () => {
+ if (!value.from || !value.to) return '';
+ const { from, to } = value;
+ const fromText = `${getLanguageDigits(putZero(from.year))
+ .toString()
+ .slice(yearLetterSkip)}/${getLanguageDigits(putZero(from.month))}/${getLanguageDigits(
+ putZero(from.day),
+ )}`;
+ const toText = `${getLanguageDigits(putZero(to.year))
+ .toString()
+ .slice(yearLetterSkip)}/${getLanguageDigits(putZero(to.month))}/${getLanguageDigits(
+ putZero(to.day),
+ )}`;
+ return `${fromWord} ${fromText} ${toWord} ${toText}`;
+ };
+
+ const getMultiDateValue = () => {
+ return value.map(date => getLanguageDigits(date.day)).join(`${digitSeparator} `);
+ };
+
+ const getValue = () => {
+ if (formatInputText()) return formatInputText();
+ const valueType = getValueType(value);
+ switch (valueType) {
+ case TYPE_SINGLE_DATE:
+ return getSingleDayValue();
+ case TYPE_RANGE:
+ return getDayRangeValue();
+ case TYPE_MUTLI_DATE:
+ return getMultiDateValue();
+ }
+ };
+
+ const placeholderValue = inputPlaceholder || defaultPlaceholder;
+ const render = () => {
+ return (
+ renderInput({ ref }) || (
+
+ )
+ );
+ };
+
+ return render();
+ },
+);
+
+DatePickerInput.defaultProps = {
+ formatInputText: () => '',
+ renderInput: () => null,
+ inputPlaceholder: '',
+ inputClassName: '',
+ inputName: '',
+};
+
+export default DatePickerInput;
diff --git a/src/components/Calendar/CalendarComponents/components/DaysList.js b/src/components/Calendar/CalendarComponents/components/DaysList.js
new file mode 100644
index 0000000..170f83d
--- /dev/null
+++ b/src/components/Calendar/CalendarComponents/components/DaysList.js
@@ -0,0 +1,399 @@
+import React, { useRef, useEffect } from 'react';
+
+import {
+ getSlideDate,
+ handleSlideAnimationEnd,
+ animateContent,
+} from '../shared/sliderHelpers';
+import {
+ deepCloneObject,
+ isSameDay,
+ createUniqueRange,
+ getValueType,
+} from '../shared/generalUtils';
+import {
+ TYPE_SINGLE_DATE,
+ TYPE_RANGE,
+ TYPE_MUTLI_DATE,
+} from '../shared/constants';
+import handleKeyboardNavigation from '../shared/keyboardNavigation';
+import { useLocaleUtils, useLocaleLanguage } from '../shared/hooks';
+
+const DaysList = ({
+ activeDate,
+ value,
+ monthChangeDirection,
+ onSlideChange,
+ disabledDays,
+ onDisabledDayError,
+ minimumDate,
+ maximumDate,
+ onChange,
+ locale,
+ calendarTodayClassName,
+ calendarSelectedDayClassName,
+ calendarRangeStartClassName,
+ calendarRangeEndClassName,
+ calendarRangeBetweenClassName,
+ shouldHighlightWeekends,
+ isQuickSelectorOpen,
+ customDaysClassName,
+ events,
+ showEvent,
+ type
+}) => {
+ const calendarSectionWrapper = useRef(null);
+ const { isRtl, weekDays: weekDaysList } = useLocaleLanguage(locale);
+ const {
+ getToday,
+ isBeforeDate,
+ checkDayInDayRange,
+ getMonthFirstWeekday,
+ getMonthLength,
+ getLanguageDigits,
+ getMonthName,
+ } = useLocaleUtils(locale);
+ const today = getToday();
+
+ useEffect(() => {
+ if (!monthChangeDirection) return;
+ animateContent({
+ direction: monthChangeDirection,
+ parent: calendarSectionWrapper.current,
+ });
+ }, [monthChangeDirection]);
+
+ const getDayRangeValue = (day) => {
+ const clonedDayRange = deepCloneObject(value);
+ const dayRangeValue =
+ clonedDayRange.from && clonedDayRange.to
+ ? { from: null, to: null }
+ : clonedDayRange;
+ const dayRangeProp = !dayRangeValue.from ? 'from' : 'to';
+ dayRangeValue[dayRangeProp] = day;
+ const { from, to } = dayRangeValue;
+
+ // swap from and to values if from is later than to
+ if (isBeforeDate(dayRangeValue.to, dayRangeValue.from)) {
+ dayRangeValue.from = to;
+ dayRangeValue.to = from;
+ }
+
+ const checkIncludingDisabledDay = (disabledDay) => {
+ return checkDayInDayRange({
+ day: disabledDay,
+ from: dayRangeValue.from,
+ to: dayRangeValue.to,
+ });
+ };
+ const includingDisabledDay = disabledDays.find(checkIncludingDisabledDay);
+ if (includingDisabledDay) {
+ onDisabledDayError(includingDisabledDay);
+ return value;
+ }
+
+ return dayRangeValue;
+ };
+
+ const getMultiDateValue = (day) => {
+ const isAlreadyExisting = value.some((valueDay) =>
+ isSameDay(valueDay, day)
+ );
+ const addedToValue = [...value, day];
+ const removedFromValue = value.filter(
+ (valueDay) => !isSameDay(valueDay, day)
+ );
+ return isAlreadyExisting ? removedFromValue : addedToValue;
+ };
+
+ const handleDayClick = (day) => {
+ const getNewValue = () => {
+ const valueType = getValueType(value);
+ switch (valueType) {
+ case TYPE_SINGLE_DATE:
+ return day;
+ case TYPE_RANGE:
+ return getDayRangeValue(day);
+ case TYPE_MUTLI_DATE:
+ return getMultiDateValue(day);
+ }
+ };
+ const newValue = getNewValue();
+ onChange(newValue);
+ };
+
+ const isSingleDateSelected = (day) => {
+ const valueType = getValueType(value);
+ if (valueType === TYPE_SINGLE_DATE) return isSameDay(day, value);
+ if (valueType === TYPE_MUTLI_DATE)
+ return value.some((valueDay) => isSameDay(valueDay, day));
+ };
+
+ const getDayStatus = (dayItem) => {
+ const isToday = isSameDay(dayItem, today);
+ const isSelected = isSingleDateSelected(dayItem);
+ const { from: startingDay, to: endingDay } = value || {};
+ const isStartingDayRange = isSameDay(dayItem, startingDay);
+ const isEndingDayRange = isSameDay(dayItem, endingDay);
+ const isWithinRange = checkDayInDayRange({
+ day: dayItem,
+ from: startingDay,
+ to: endingDay,
+ });
+ return {
+ isToday,
+ isSelected,
+ isStartingDayRange,
+ isEndingDayRange,
+ isWithinRange,
+ };
+ };
+
+ const getDayClassNames = (dayItem) => {
+ const {
+ isToday,
+ isSelected,
+ isStartingDayRange,
+ isEndingDayRange,
+ isWithinRange,
+ } = getDayStatus(dayItem);
+ const customDayItemClassName = customDaysClassName.find((day) =>
+ isSameDay(dayItem, day)
+ );
+
+ const classNames = ''
+ .concat(isToday && !isSelected ? ` -today ${calendarTodayClassName}` : '')
+ .concat(!dayItem.isStandard ? ' -blank' : '')
+ .concat(dayItem.isWeekend && shouldHighlightWeekends ? ' -weekend' : '')
+ .concat(
+ customDayItemClassName ? ` ${customDayItemClassName.className}` : ''
+ )
+ .concat(isSelected ? ` -selected ${calendarSelectedDayClassName}` : '')
+ .concat(
+ isStartingDayRange
+ ? ` -selectedStart ${calendarRangeStartClassName}`
+ : ''
+ )
+ .concat(
+ isEndingDayRange ? ` -selectedEnd ${calendarRangeEndClassName}` : ''
+ )
+ .concat(
+ isWithinRange
+ ? ` -selectedBetween ${calendarRangeBetweenClassName}`
+ : ''
+ )
+ .concat(dayItem.isDisabled ? ' -disabled' : '');
+ return classNames;
+ };
+
+ const getViewMonthDays = (date) => {
+ // to match month starting date with the correct weekday label
+ const prependingBlankDays = createUniqueRange(
+ getMonthFirstWeekday(date),
+ 'starting-blank'
+ );
+ const standardDays = createUniqueRange(getMonthLength(date)).map((day) => ({
+ ...day,
+ isStandard: true,
+ month: date.month,
+ year: date.year,
+ }));
+ const allDays = [...prependingBlankDays, ...standardDays];
+ return allDays;
+ };
+
+ const handleDayPress = ({ isDisabled, ...dayItem }) => {
+ if (isDisabled) {
+ onDisabledDayError(dayItem); // good for showing error messages
+ } else handleDayClick(dayItem);
+ };
+
+ const isDayReachableByKeyboard = ({
+ isOnActiveSlide,
+ isStandard,
+ isSelected,
+ isStartingDayRange,
+ isToday,
+ day,
+ }) => {
+ if (isQuickSelectorOpen || !isOnActiveSlide || !isStandard) return false;
+ if (isSelected || isStartingDayRange || isToday || day === 1) return true;
+ };
+
+ const renderEachWeekDays = (
+ { id, value: day, month, year, isStandard },
+ index
+ ) => {
+ const dayItem = { day, month, year };
+ const isInDisabledDaysRange = disabledDays.some((disabledDay) =>
+ isSameDay(dayItem, disabledDay)
+ );
+ const isBeforeMinimumDate = isBeforeDate(dayItem, minimumDate);
+ const isAfterMaximumDate = isBeforeDate(maximumDate, dayItem);
+ const isNotInValidRange =
+ isStandard && (isBeforeMinimumDate || isAfterMaximumDate);
+ const isDisabled = isInDisabledDaysRange || isNotInValidRange;
+ const isWeekend = weekDaysList.some(
+ (weekDayItem, weekDayItemIndex) =>
+ weekDayItem.isWeekend && weekDayItemIndex === index
+ );
+ const additionalClass = getDayClassNames({
+ ...dayItem,
+ isWeekend,
+ isStandard,
+ isDisabled,
+ });
+ const dayLabel = `${weekDaysList[index].name}, ${day} ${getMonthName(
+ month
+ )} ${year}`;
+ const isOnActiveSlide = month === activeDate.month;
+ const dayStatus = getDayStatus(dayItem);
+ const { isSelected, isStartingDayRange, isEndingDayRange, isWithinRange } =
+ dayStatus;
+ const shouldEnableKeyboardNavigation = isDayReachableByKeyboard({
+ ...dayItem,
+ ...dayStatus,
+ isOnActiveSlide,
+ isStandard,
+ });
+
+ // showing Dots Of Events
+ const specialDate = (sDay, sMonth, sYear) => {
+ return events.map((e) => {
+ if (sDay == e.day && sMonth == e.month && sYear == e.year) {
+ return . ;
+
+ }
+ })
+
+ };
+
+ const showEventDescription = (sDay, sMonth, sYear) => {
+
+ return events.map((e) => {
+
+ if (sDay == e.day && sMonth == e.month && sYear == e.year) {
+
+ return ()
+
+ }
+
+ })
+
+
+ }
+ return (
+ {
+ handleDayPress({ ...dayItem, isDisabled });
+ // console.log(specialDate(day));
+ // console.log(showEventDescription(day))
+ showEvent(showEventDescription(day, month, year))
+
+ }}
+ onKeyDown={({ key }) => {
+ /* istanbul ignore else */
+ if (key === 'Enter') handleDayPress({ ...dayItem, isDisabled });
+ }}
+ aria-disabled={isDisabled}
+ aria-label={dayLabel}
+ aria-selected={
+ isSelected || isStartingDayRange || isEndingDayRange || isWithinRange
+ }
+ {...(!isStandard || !isOnActiveSlide || isQuickSelectorOpen
+ ? { 'aria-hidden': true }
+ : {})}
+ role="gridcell"
+ data-is-default-selectable={shouldEnableKeyboardNavigation}
+ >
+
{!isStandard ? '' : getLanguageDigits(day)}
+ {/* Dots Of Events */}
+
{specialDate(day, month, year)}
+
+ );
+ };
+
+ const renderMonthDays = (isInitialActiveChild) => {
+ const date = getSlideDate({
+ activeDate,
+ isInitialActiveChild,
+ monthChangeDirection,
+ parent: calendarSectionWrapper.current,
+ });
+ const allDays = getViewMonthDays(date);
+ const renderSingleWeekRow = (weekRowIndex) => {
+ const eachWeekDays = allDays
+ .slice(weekRowIndex * 7, weekRowIndex * 7 + 7)
+ .map(renderEachWeekDays);
+ return (
+
+ {eachWeekDays}
+
+ );
+ };
+ return Array.from(Array(6).keys()).map(renderSingleWeekRow);
+ };
+
+ const handleKeyDown = (e) => {
+ handleKeyboardNavigation(e, { allowVerticalArrows: true });
+ };
+
+ return (
+
+
{
+ handleSlideAnimationEnd(e);
+ onSlideChange();
+ }}
+ className="Calendar__section -shown"
+ role="rowgroup"
+ >
+ {renderMonthDays(true)}
+
+
{
+ handleSlideAnimationEnd(e);
+ onSlideChange();
+ }}
+ className="Calendar__section -hiddenNext"
+ role="rowgroup"
+ >
+ {renderMonthDays(false)}
+
+
+ );
+};
+
+DaysList.defaultProps = {
+ onChange: () => { },
+ onDisabledDayError: () => { },
+ disabledDays: [],
+ calendarTodayClassName: '',
+ calendarSelectedDayClassName: '',
+ calendarRangeStartClassName: '',
+ calendarRangeBetweenClassName: '',
+ calendarRangeEndClassName: '',
+ shouldHighlightWeekends: false,
+};
+
+export default DaysList;
diff --git a/src/components/Calendar/CalendarComponents/components/Header.js b/src/components/Calendar/CalendarComponents/components/Header.js
new file mode 100644
index 0000000..4a8523a
--- /dev/null
+++ b/src/components/Calendar/CalendarComponents/components/Header.js
@@ -0,0 +1,168 @@
+import React, { useEffect, useRef } from 'react';
+
+import { isSameDay } from '../shared/generalUtils';
+import { getSlideDate, animateContent, handleSlideAnimationEnd } from '../shared/sliderHelpers';
+import { useLocaleUtils, useLocaleLanguage } from '../shared/hooks';
+
+const Header = ({
+ maximumDate,
+ minimumDate,
+ onMonthChange,
+ activeDate,
+ monthChangeDirection,
+ onMonthSelect,
+ onYearSelect,
+ isMonthSelectorOpen,
+ isYearSelectorOpen,
+ locale,
+ type
+}) => {
+ const headerElement = useRef(null);
+ const monthYearWrapperElement = useRef(null);
+
+ const { getMonthName, isBeforeDate, getLanguageDigits } = useLocaleUtils(locale);
+ const {
+ isRtl,
+ nextMonth,
+ previousMonth,
+ openMonthSelector,
+ closeMonthSelector,
+ openYearSelector,
+ closeYearSelector,
+ } = useLocaleLanguage(locale);
+
+ useEffect(() => {
+ if (!monthChangeDirection) return;
+ animateContent({
+ direction: monthChangeDirection,
+ parent: monthYearWrapperElement.current,
+ });
+ }, [monthChangeDirection]);
+
+ useEffect(() => {
+ const isOpen = isMonthSelectorOpen || isYearSelectorOpen;
+ const monthText = headerElement.current.querySelector(
+ '.Calendar__monthYear.-shown .Calendar__monthText',
+ );
+ const yearText = monthText.nextSibling;
+ const hasActiveBackground = element => element.classList.contains('-activeBackground');
+ const isInitialRender =
+ !isOpen && !hasActiveBackground(monthText) && !hasActiveBackground(yearText);
+ if (isInitialRender) return;
+
+ const arrows = [...headerElement.current.querySelectorAll('.Calendar__monthArrowWrapper')];
+ const hasMonthSelectorToggled = isMonthSelectorOpen || hasActiveBackground(monthText);
+ const primaryElement = hasMonthSelectorToggled ? monthText : yearText;
+ const secondaryElement = hasMonthSelectorToggled ? yearText : monthText;
+
+ let translateXDirection = hasMonthSelectorToggled ? 1 : -1;
+ if (isRtl) translateXDirection *= -1;
+ const scale = !isOpen ? 0.95 : 1;
+ const translateX = !isOpen ? 0 : `${(translateXDirection * secondaryElement.offsetWidth) / 2}`;
+ if (!isOpen) {
+ secondaryElement.removeAttribute('aria-hidden');
+ } else {
+ secondaryElement.setAttribute('aria-hidden', true);
+ }
+ secondaryElement.setAttribute('tabindex', isOpen ? '-1' : '0');
+ secondaryElement.style.transform = '';
+ primaryElement.style.transform = `scale(${scale}) ${
+ translateX ? `translateX(${translateX}px)` : ''
+ }`;
+ primaryElement.classList.toggle('-activeBackground');
+ secondaryElement.classList.toggle('-hidden');
+ arrows.forEach(arrow => {
+ const isHidden = arrow.classList.contains('-hidden');
+ arrow.classList.toggle('-hidden');
+ if (isHidden) {
+ arrow.removeAttribute('aria-hidden');
+ arrow.setAttribute('tabindex', '0');
+ } else {
+ arrow.setAttribute('aria-hidden', true);
+ arrow.setAttribute('tabindex', '-1');
+ }
+ });
+ }, [isMonthSelectorOpen, isYearSelectorOpen]);
+
+ const getMonthYearText = isInitialActiveChild => {
+ const date = getSlideDate({
+ isInitialActiveChild,
+ monthChangeDirection,
+ activeDate,
+ parent: monthYearWrapperElement.current,
+ });
+ const year = getLanguageDigits(date.year);
+ const month = getMonthName(date.month);
+ return { month, year };
+ };
+
+ const isNextMonthArrowDisabled =
+ maximumDate &&
+ isBeforeDate(maximumDate, { ...activeDate, month: activeDate.month + 1, day: 1 });
+ const isPreviousMonthArrowDisabled =
+ minimumDate &&
+ (isBeforeDate({ ...activeDate, day: 1 }, minimumDate) ||
+ isSameDay(minimumDate, { ...activeDate, day: 1 }));
+
+ const onMonthChangeTrigger = direction => {
+ const isMonthChanging = Array.from(monthYearWrapperElement.current.children).some(child =>
+ child.classList.contains('-shownAnimated'),
+ );
+ if (isMonthChanging) return;
+ onMonthChange(direction);
+ };
+
+ // first button text is the one who shows the current month and year(initial active child)
+ const monthYearButtons = [true, false].map(isInitialActiveChild => {
+ const { month, year } = getMonthYearText(isInitialActiveChild);
+ const isActiveMonth = month === getMonthName(activeDate.month);
+
+ return (
+ <>
+
+ {month}
+
+
+ {year}
+
+ >
+ );
+ });
+
+ return (
+
+ {type == 'dashboard' ?
+
+
+ {monthYearButtons}
+
+ :
+ <>
+
+
+
+ {monthYearButtons}
+
+
+ >
+
+ }
+
+ );
+};
+
+export default Header;
diff --git a/src/components/Calendar/CalendarComponents/components/MonthSelector.js b/src/components/Calendar/CalendarComponents/components/MonthSelector.js
new file mode 100644
index 0000000..aafbd2c
--- /dev/null
+++ b/src/components/Calendar/CalendarComponents/components/MonthSelector.js
@@ -0,0 +1,74 @@
+import React, { useRef, useEffect } from 'react';
+
+import { isSameDay } from '../shared/generalUtils';
+import handleKeyboardNavigation from '../shared/keyboardNavigation';
+import { useLocaleUtils, useLocaleLanguage } from '../shared/hooks';
+
+const MonthSelector = ({ activeDate, maximumDate, minimumDate, onMonthSelect, isOpen, locale }) => {
+ const monthSelector = useRef(null);
+
+ useEffect(() => {
+ const classToggleMethod = isOpen ? 'add' : 'remove';
+ monthSelector.current.classList[classToggleMethod]('-open');
+ }, [isOpen]);
+
+ const { getMonthNumber, isBeforeDate } = useLocaleUtils(locale);
+ const { months: monthsList } = useLocaleLanguage(locale);
+
+ const handleKeyDown = e => {
+ handleKeyboardNavigation(e, { allowVerticalArrows: false });
+ };
+
+ const renderMonthSelectorItems = () =>
+ monthsList.map(persianMonth => {
+ const monthNumber = getMonthNumber(persianMonth);
+ const monthDate = { day: 1, month: monthNumber, year: activeDate.year };
+ const isAfterMaximumDate =
+ maximumDate && isBeforeDate(maximumDate, { ...monthDate, month: monthNumber });
+ const isBeforeMinimumDate =
+ minimumDate &&
+ (isBeforeDate({ ...monthDate, month: monthNumber + 1 }, minimumDate) ||
+ isSameDay({ ...monthDate, month: monthNumber + 1 }, minimumDate));
+ const isSelected = monthNumber === activeDate.month;
+ return (
+
+ {
+ onMonthSelect(monthNumber);
+ }}
+ className="Calendar__monthSelectorItemText"
+ type="button"
+ disabled={isAfterMaximumDate || isBeforeMinimumDate}
+ aria-pressed={isSelected}
+ data-is-default-selectable={isSelected}
+ >
+ {persianMonth}
+
+
+ );
+ });
+ return (
+
+
+
+ {renderMonthSelectorItems()}
+
+
+
+ );
+};
+
+export default MonthSelector;
diff --git a/src/components/Calendar/CalendarComponents/components/YearSelector.js b/src/components/Calendar/CalendarComponents/components/YearSelector.js
new file mode 100644
index 0000000..115bad6
--- /dev/null
+++ b/src/components/Calendar/CalendarComponents/components/YearSelector.js
@@ -0,0 +1,99 @@
+import React, { useRef, useEffect } from 'react';
+
+import { MINIMUM_SELECTABLE_YEAR_SUBTRACT, MAXIMUM_SELECTABLE_YEAR_SUM } from '../shared/constants';
+import handleKeyboardNavigation from '../shared/keyboardNavigation';
+import { useLocaleUtils } from '../shared/hooks';
+
+const YearSelector = ({
+ isOpen,
+ activeDate,
+ onYearSelect,
+ selectorStartingYear,
+ selectorEndingYear,
+ maximumDate,
+ minimumDate,
+ locale,
+}) => {
+ const wrapperElement = useRef(null);
+ const yearListElement = useRef(null);
+
+ const { getLanguageDigits, getToday } = useLocaleUtils(locale);
+ const startingYearValue =
+ selectorStartingYear || getToday().year - MINIMUM_SELECTABLE_YEAR_SUBTRACT;
+ const endingYearValue = selectorEndingYear || getToday().year + MAXIMUM_SELECTABLE_YEAR_SUM;
+ const allYears = [];
+ for (let i = startingYearValue; i <= endingYearValue; i += 1) {
+ allYears.push(i);
+ }
+ useEffect(() => {
+ const classToggleMethod = isOpen ? 'add' : 'remove';
+ const activeSelectorYear = wrapperElement.current.querySelector(
+ '.Calendar__yearSelectorItem.-active',
+ );
+ if (!activeSelectorYear) {
+ throw new RangeError(
+ `Provided value for year is out of selectable year range. You're probably using a wrong locale prop value or your provided value's locale is different from the date picker locale. Try changing the 'locale' prop or the value you've provided.`,
+ );
+ }
+ wrapperElement.current.classList[classToggleMethod]('-faded');
+ yearListElement.current.scrollTop =
+ activeSelectorYear.offsetTop - activeSelectorYear.offsetHeight * 5;
+ yearListElement.current.classList[classToggleMethod]('-open');
+ }, [isOpen]);
+
+ const renderSelectorYears = () => {
+ return allYears.map(item => {
+ const isAfterMaximumDate = maximumDate && item > maximumDate.year;
+ const isBeforeMinimumDate = minimumDate && item < minimumDate.year;
+ const isSelected = activeDate.year === item;
+ return (
+
+ {
+ onYearSelect(item);
+ }}
+ disabled={isAfterMaximumDate || isBeforeMinimumDate}
+ aria-pressed={isSelected}
+ data-is-default-selectable={isSelected}
+ >
+ {getLanguageDigits(item)}
+
+
+ );
+ });
+ };
+
+ const handleKeyDown = e => {
+ handleKeyboardNavigation(e, { allowVerticalArrows: false });
+ };
+
+ return (
+
+
+
+ {renderSelectorYears()}
+
+
+
+ );
+};
+
+YearSelector.defaultProps = {
+ selectorStartingYear: 0,
+ selectorEndingYear: 0,
+};
+
+export default YearSelector;
diff --git a/src/components/Calendar/CalendarComponents/components/index.js b/src/components/Calendar/CalendarComponents/components/index.js
new file mode 100644
index 0000000..7cc422f
--- /dev/null
+++ b/src/components/Calendar/CalendarComponents/components/index.js
@@ -0,0 +1,4 @@
+export { default as Header } from './Header';
+export { default as MonthSelector } from './MonthSelector';
+export { default as YearSelector } from './YearSelector';
+export { default as DaysList } from './DaysList';
diff --git a/src/components/Calendar/CalendarComponents/dateBox.css b/src/components/Calendar/CalendarComponents/dateBox.css
new file mode 100644
index 0000000..dfd8ad7
--- /dev/null
+++ b/src/components/Calendar/CalendarComponents/dateBox.css
@@ -0,0 +1,187 @@
+/* @font-face {
+ font-family: IRANSansBold;
+ src: url(../../../assets/font/IRANSans/IRANSans_Bold.ttf);
+} */
+
+/* @font-face {
+ font-family: IRANSans;
+ src: url(../../../assets/font/IRANSans/IRANSans.ttf);
+} */
+@font-face {
+ font-family: IRANSansX-Bold;
+ src: url(../../../assets/font/IRANSansX/Webfonts/fonts/woff2/IRANSansX-Bold.woff2) format("woff2"),
+ url(../../../assets/font/IRANSansX/Webfonts/fonts/woff/IRANSansX-Bold.woff) format("woff");
+ }
+
+ @font-face {
+ font-family: IRANSansX-Regular;
+ src: url(../../../assets/font/IRANSansX/Webfonts/fonts/woff2/IRANSansX-Regular.woff2) format("woff2"),
+ url(../../../assets/font/IRANSansX/Webfonts/fonts/woff/IRANSansX-Regular.woff) format("woff");
+ }
+
+ @font-face {
+ font-family: IRANSansXFaNum-Regular;
+ src: url(../../../assets/font/IRANSansX/Farsi-numerals/IRANSansXFaNum-Regular.ttf) format("woff2"),
+ url(../../../assets/font/IRANSansX/Farsi-numerals/Webfonts/Woff/IRANSansXFaNum-Regular.woff) format("woff");
+ }
+ @font-face {
+ font-family: IRANSansXFaNum-Bold;
+ src: url(../../../assets/font/IRANSansX/Farsi-numerals/IRANSansXFaNum-Bold.ttf) format("woff2"),
+ url(../../../assets/font/IRANSansX/Farsi-numerals/Webfonts/Woff/IRANSansXFaNum-Bold.woff) format("woff");
+ }
+
+ *{
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ }
+
+ .date-box{
+ width: 100%;
+ /* height: 106px; */
+ border-radius: 17px;
+ /* box-shadow: 0 0 38px -15px #ADADAD; */
+ border: 1px solid #E0E0E0;
+ direction: rtl;
+ background-color: white;
+ padding-bottom: 15px;
+ }
+
+ .date-box-p1{
+ width: 90%;
+ display: inline-flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-top: 10px;
+ margin-right: 17.5px;
+ }
+
+ .date-box-p1-year-and-month{
+ display: flex;
+ align-items: center;
+ /* font-family: IRANSansBold; */
+ font-family: IRANSansX-Bold;
+ font-size: 19px;
+ color: #df1452;
+ }
+
+ .dbp1-month{
+ margin-left: 2px;
+ color: #df1452;
+ }
+
+ .dbp1-year{
+ margin-right: 2px;
+ color: #df1452;
+ font-family: IRANSansXFaNum-Bold;
+ }
+
+ .date-box-p1-time{
+ display: flex;
+ align-items: center;
+ /* font-family: IRANSans; */
+ font-family: IRANSansX-Regular;
+ font-size: 9px;
+ border-radius: 10px;
+ padding: 1.5px 6px;
+ background-color: #eac8d5;
+ border-radius: 2px;
+ /* color: #013273 !important; */
+ }
+
+
+ .date-box-p2{
+ width: 90%;
+ margin: 0 auto;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-top: 6px;
+ }
+
+ .date-box-p2-item{
+ text-align: center;
+ position: relative;
+ cursor: default;
+ }
+
+ .dbp2i-dayname{
+ font-size: 11px;
+ /* font-family: IRANSans; */
+ font-family: IRANSansX-Regular;
+ color: #A2B4CB;
+ }
+
+ .dbp2i-date{
+ font-size: 15px;
+ margin-top: 10px;
+ padding: 2px;
+ color: #A9BACF;
+ font-family: IRANSansXFaNum-Regular;
+ }
+
+ .date-box-p2-item:nth-child(7) .dbp2i-dayname{
+ color: #FFC491 !important;
+ }
+
+ .date-box-p2-item:nth-child(7) .dbp2i-date{
+ color: #F6923B !important;
+ }
+
+ .dbp2i-have-Exam{
+ color: #E3FC08;
+ position: absolute;
+ bottom: -15px;
+ left: 50%;
+ transform: translateX(-50%);
+ }
+
+ .date-box-p3{
+ width: 90%;
+ margin: 0 auto;
+ margin-top: 18px;
+ font-family: IRANSansX-Regular;
+ font-size: 13px;
+ color: #013273;
+ }
+
+ .date-box-p3-item{
+ /* display: none; */
+ max-height: 0px;
+ transform: scaleY(0);
+ transform-origin: top;
+ transition: all 0.5s;
+ }
+
+ .date-box-p3-item-item{
+ display: flex;
+ align-items: center;
+ }
+
+ .date-box-p3-item-item-icon{
+ font-size: 16px;
+ margin-left: 3px;
+ }
+
+ .date-box-p3-item-active{
+ /* display: block; */
+ max-height: 200px;
+ transform: scaleY(1);
+ }
+
+
+
+
+ /* --------responsive-setting---------------------------------------------------------- */
+
+ @media screen and (max-width: 1270px){
+ .dbp2i-dayname{
+ font-size: 10px;
+ }
+ }
+
+ @media screen and (max-width: 1160px){
+ .dbp2i-dayname{
+ font-size: 9px;
+ }
+ }
\ No newline at end of file
diff --git a/src/components/Calendar/CalendarComponents/index.js b/src/components/Calendar/CalendarComponents/index.js
new file mode 100644
index 0000000..a983b77
--- /dev/null
+++ b/src/components/Calendar/CalendarComponents/index.js
@@ -0,0 +1,3 @@
+export { default} from './DatePicker';
+export * from './Calendar';
+export { default as utils } from './shared/localeUtils';
diff --git a/src/components/Calendar/CalendarComponents/shared/constants.js b/src/components/Calendar/CalendarComponents/shared/constants.js
new file mode 100644
index 0000000..bceb3a1
--- /dev/null
+++ b/src/components/Calendar/CalendarComponents/shared/constants.js
@@ -0,0 +1,104 @@
+export const PERSIAN_NUMBERS = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'];
+
+export const PERSIAN_MONTHS = [
+ 'فروردین',
+ 'اردیبهشت',
+ 'خرداد',
+ 'تیر',
+ 'مرداد',
+ 'شهریور',
+ 'مهر',
+ 'آبان',
+ 'آذر',
+ 'دی',
+ 'بهمن',
+ 'اسفند',
+];
+
+export const GREGORIAN_MONTHS = [
+ 'January',
+ 'February',
+ 'March',
+ 'April',
+ 'May',
+ 'June',
+ 'July',
+ 'August',
+ 'September',
+ 'October',
+ 'November',
+ 'December',
+];
+
+export const PERSIAN_WEEK_DAYS = [
+ {
+ name: 'شنبه',
+ short: 'ش',
+ },
+ {
+ name: 'یکشنبه',
+ short: 'ی',
+ },
+ {
+ name: 'دوشنبه',
+ short: 'د',
+ },
+ {
+ name: 'سه شنبه',
+ short: 'س',
+ },
+ {
+ name: 'چهارشنبه',
+ short: 'چ',
+ },
+ {
+ name: 'پنجشنبه',
+ short: 'پ',
+ },
+ {
+ name: 'جمعه',
+ short: 'ج',
+ isWeekend: true,
+ },
+];
+
+export const GREGORIAN_WEEK_DAYS = [
+ {
+ name: 'Sunday',
+ short: 'S',
+ isWeekend: true,
+ },
+ {
+ name: 'Monday',
+ short: 'M',
+ },
+ {
+ name: 'Tuesday',
+ short: 'T',
+ },
+ {
+ name: 'Wednesday',
+ short: 'W',
+ },
+ {
+ name: 'Thursday',
+ short: 'T',
+ },
+ {
+ name: 'Friday',
+ short: 'F',
+ },
+ {
+ name: 'Saturday',
+ short: 'S',
+ isWeekend: true,
+ },
+];
+
+export const MINIMUM_SELECTABLE_YEAR_SUBTRACT = 100;
+
+export const MAXIMUM_SELECTABLE_YEAR_SUM = 50;
+
+export const TYPE_SINGLE_DATE = 'SINGLE_DATE';
+export const TYPE_RANGE = 'RANGE';
+export const TYPE_MUTLI_DATE = 'MUTLI_DATE';
diff --git a/src/components/Calendar/CalendarComponents/shared/generalUtils.js b/src/components/Calendar/CalendarComponents/shared/generalUtils.js
new file mode 100644
index 0000000..fd379b6
--- /dev/null
+++ b/src/components/Calendar/CalendarComponents/shared/generalUtils.js
@@ -0,0 +1,69 @@
+import { TYPE_SINGLE_DATE, TYPE_RANGE, TYPE_MUTLI_DATE } from './constants';
+
+/*
+ These utility functions don't depend on locale of the date picker(Persian or Gregorian)
+*/
+
+const createUniqueRange = (number, startingId) =>
+ Array.from(Array(number).keys()).map(key => ({
+ value: key + 1,
+ id: `${startingId}-${key}`,
+ }));
+
+const isSameDay = (day1, day2) => {
+ if (!day1 || !day2) return false;
+ return day1.day === day2.day && day1.month === day2.month && day1.year === day2.year;
+};
+
+const putZero = number => (number.toString().length === 1 ? `0${number}` : number);
+
+const toExtendedDay = date => [date.year, date.month, date.day];
+
+const shallowClone = value => ({ ...value });
+
+const deepCloneObject = obj =>
+ JSON.parse(JSON.stringify(obj, (key, value) => (typeof value === 'undefined' ? null : value)));
+
+const getDateAccordingToMonth = (date, direction) => {
+ const toSum = direction === 'NEXT' ? 1 : -1;
+ let newMonthIndex = date.month + toSum;
+ let newYear = date.year;
+ if (newMonthIndex < 1) {
+ newMonthIndex = 12;
+ newYear -= 1;
+ }
+ if (newMonthIndex > 12) {
+ newMonthIndex = 1;
+ newYear += 1;
+ }
+ const newDate = { year: newYear, month: newMonthIndex, day: 1 };
+ return newDate;
+};
+
+const hasProperty = (object, propertyName) =>
+ Object.prototype.hasOwnProperty.call(object || {}, propertyName);
+
+const getValueType = value => {
+ if (Array.isArray(value)) return TYPE_MUTLI_DATE;
+ if (hasProperty(value, 'from') && hasProperty(value, 'to')) return TYPE_RANGE;
+ if (
+ !value ||
+ (hasProperty(value, 'year') && hasProperty(value, 'month') && hasProperty(value, 'day'))
+ ) {
+ return TYPE_SINGLE_DATE;
+ }
+ throw new TypeError(
+ `The passed value is malformed! Please make sure you're using one of the valid value types for date picker.`,
+ );
+};
+
+export {
+ createUniqueRange,
+ isSameDay,
+ putZero,
+ toExtendedDay,
+ shallowClone,
+ deepCloneObject,
+ getDateAccordingToMonth,
+ getValueType,
+};
diff --git a/src/components/Calendar/CalendarComponents/shared/hooks.js b/src/components/Calendar/CalendarComponents/shared/hooks.js
new file mode 100644
index 0000000..1656e5b
--- /dev/null
+++ b/src/components/Calendar/CalendarComponents/shared/hooks.js
@@ -0,0 +1,10 @@
+import { useMemo } from 'react';
+
+import utils from './localeUtils';
+import getLanguageText from './localeLanguages';
+
+const useLocaleUtils = locale => useMemo(() => utils(locale), [locale]);
+
+const useLocaleLanguage = locale => useMemo(() => getLanguageText(locale), [locale]);
+
+export { useLocaleUtils, useLocaleLanguage };
diff --git a/src/components/Calendar/CalendarComponents/shared/keyboardNavigation.js b/src/components/Calendar/CalendarComponents/shared/keyboardNavigation.js
new file mode 100644
index 0000000..f72d0ae
--- /dev/null
+++ b/src/components/Calendar/CalendarComponents/shared/keyboardNavigation.js
@@ -0,0 +1,44 @@
+const handleArrowKeys = (e, { allowVerticalArrows }) => {
+ const { activeElement } = document;
+ const getNthChildSafe = (element, index) => (element ? element.children[index] : null);
+ const getStandardItem = item => item && (item.hasAttribute('aria-hidden') ? null : item);
+ const { nextSibling: nextRow, previousSibling: previousRow } = activeElement.parentElement;
+ const nextSibling = getStandardItem(activeElement.nextSibling || getNthChildSafe(nextRow, 0));
+ const previousRowLength = previousRow ? previousRow.children.length - 1 : 0;
+ const previousSibling = getStandardItem(
+ activeElement.previousSibling || getNthChildSafe(previousRow, previousRowLength),
+ );
+ const getVerticalSibling = row =>
+ getNthChildSafe(row, Array.from(activeElement.parentElement.children).indexOf(activeElement));
+ const downSibling = getStandardItem(getVerticalSibling(nextRow));
+ const upSibling = getStandardItem(getVerticalSibling(previousRow));
+ const isDefaultSelectable = activeElement.dataset.isDefaultSelectable === 'true';
+
+ if (!isDefaultSelectable) activeElement.tabIndex = '-1';
+ const focusIfAvailable = element => {
+ e.preventDefault();
+ /* istanbul ignore else */
+ if (element) {
+ element.setAttribute('tabindex', '0');
+ element.focus();
+ }
+ };
+ switch (e.key) {
+ case 'ArrowRight':
+ focusIfAvailable(nextSibling);
+ break;
+ case 'ArrowLeft':
+ focusIfAvailable(previousSibling);
+ break;
+ case 'ArrowDown':
+ /* istanbul ignore else */
+ if (allowVerticalArrows) focusIfAvailable(downSibling);
+ break;
+ case 'ArrowUp':
+ /* istanbul ignore else */
+ if (allowVerticalArrows) focusIfAvailable(upSibling);
+ break;
+ }
+};
+
+export default handleArrowKeys;
diff --git a/src/components/Calendar/CalendarComponents/shared/localeLanguages.js b/src/components/Calendar/CalendarComponents/shared/localeLanguages.js
new file mode 100644
index 0000000..806b1f5
--- /dev/null
+++ b/src/components/Calendar/CalendarComponents/shared/localeLanguages.js
@@ -0,0 +1,85 @@
+import jalaali from 'jalaali-js';
+
+import {
+ GREGORIAN_MONTHS,
+ PERSIAN_MONTHS,
+ GREGORIAN_WEEK_DAYS,
+ PERSIAN_WEEK_DAYS,
+ PERSIAN_NUMBERS,
+} from './constants';
+import { toExtendedDay } from './generalUtils';
+
+const localeLanguages = {
+ en: {
+ months: GREGORIAN_MONTHS,
+ weekDays: GREGORIAN_WEEK_DAYS,
+ weekStartingIndex: 0,
+ getToday(gregorainTodayObject) {
+ return gregorainTodayObject;
+ },
+ toNativeDate(date) {
+ return new Date(date.year, date.month - 1, date.day);
+ },
+ getMonthLength(date) {
+ return new Date(date.year, date.month, 0).getDate();
+ },
+ transformDigit(digit) {
+ return digit;
+ },
+ nextMonth: 'Next Month',
+ previousMonth: 'Previous Month',
+ openMonthSelector: 'Open Month Selector',
+ openYearSelector: 'Open Year Selector',
+ closeMonthSelector: 'Close Month Selector',
+ closeYearSelector: 'Close Year Selector',
+ from: 'from',
+ to: 'to',
+ defaultPlaceholder: 'Select...',
+ digitSeparator: ',',
+ yearLetterSkip: 0,
+ isRtl: false,
+ },
+ fa: {
+ months: PERSIAN_MONTHS,
+ weekDays: PERSIAN_WEEK_DAYS,
+ weekStartingIndex: 1,
+ getToday({ year, month, day }) {
+ const { jy, jm, jd } = jalaali.toJalaali(year, month, day);
+ return { year: jy, month: jm, day: jd };
+ },
+ toNativeDate(date) {
+ const gregorian = jalaali.toGregorian(...toExtendedDay(date));
+ return new Date(gregorian.gy, gregorian.gm - 1, gregorian.gd);
+ },
+ getMonthLength(date) {
+ return jalaali.jalaaliMonthLength(date.year, date.month);
+ },
+ transformDigit(digit) {
+ return digit
+ .toString()
+ .split('')
+ .map(letter => PERSIAN_NUMBERS[Number(letter)])
+ .join('');
+ },
+ nextMonth: 'ماه بعد',
+ previousMonth: 'ماه قبل',
+ openMonthSelector: 'نمایش انتخابگر ماه',
+ openYearSelector: 'نمایش انتخابگر سال',
+ closeMonthSelector: 'بستن انتخابگر ماه',
+ closeYearSelector: 'بستن انتخابگر ماه',
+ from: 'از',
+ to: 'تا',
+ defaultPlaceholder: 'انتخاب...',
+ digitSeparator: '،',
+ yearLetterSkip: -2,
+ isRtl: true,
+ },
+};
+
+const getLocaleDetails = locale => {
+ if (typeof locale === 'string') return localeLanguages[locale];
+ return locale;
+};
+
+export { localeLanguages };
+export default getLocaleDetails;
diff --git a/src/components/Calendar/CalendarComponents/shared/localeUtils.js b/src/components/Calendar/CalendarComponents/shared/localeUtils.js
new file mode 100644
index 0000000..1055f94
--- /dev/null
+++ b/src/components/Calendar/CalendarComponents/shared/localeUtils.js
@@ -0,0 +1,61 @@
+/*
+ These utility functions highly depend on locale of the date picker(Persian or Gregorian)
+*/
+
+import getLocaleDetails from './localeLanguages';
+
+const utils = (locale = 'en') => {
+ const {
+ months: monthsList,
+ getToday: localeGetToday,
+ toNativeDate,
+ getMonthLength,
+ weekStartingIndex,
+ transformDigit: getLanguageDigits,
+ } = typeof locale === 'string' ? getLocaleDetails(locale) : locale;
+
+ const getToday = () => {
+ const todayDate = new Date();
+ const year = todayDate.getFullYear();
+ const month = todayDate.getMonth() + 1;
+ const day = todayDate.getDate();
+ return localeGetToday({ year, month, day });
+ };
+
+ const getMonthName = month => monthsList[month - 1];
+
+ const getMonthNumber = monthName => monthsList.indexOf(monthName) + 1;
+
+ const getMonthFirstWeekday = date => {
+ const gregorianDate = toNativeDate({ ...date, day: 1 });
+ const weekday = gregorianDate.getDay();
+ const dayIndex = weekday + weekStartingIndex;
+ return dayIndex % 7;
+ };
+
+ const isBeforeDate = (day1, day2) => {
+ if (!day1 || !day2) return false;
+ return toNativeDate(day1) < toNativeDate(day2);
+ };
+
+ const checkDayInDayRange = ({ day, from, to }) => {
+ if (!day || !from || !to) return false;
+ const nativeDay = toNativeDate(day);
+ const nativeFrom = toNativeDate(from);
+ const nativeTo = toNativeDate(to);
+ return nativeDay > nativeFrom && nativeDay < nativeTo;
+ };
+
+ return {
+ getToday,
+ getMonthName,
+ getMonthNumber,
+ getMonthLength,
+ getMonthFirstWeekday,
+ isBeforeDate,
+ checkDayInDayRange,
+ getLanguageDigits,
+ };
+};
+
+export default utils;
diff --git a/src/components/Calendar/CalendarComponents/shared/sliderHelpers.js b/src/components/Calendar/CalendarComponents/shared/sliderHelpers.js
new file mode 100644
index 0000000..524e49a
--- /dev/null
+++ b/src/components/Calendar/CalendarComponents/shared/sliderHelpers.js
@@ -0,0 +1,33 @@
+import { getDateAccordingToMonth } from './generalUtils';
+
+const getSlideDate = ({ parent, isInitialActiveChild, activeDate, monthChangeDirection }) => {
+ if (!parent) {
+ return isInitialActiveChild ? activeDate : getDateAccordingToMonth(activeDate, 'NEXT');
+ }
+ const child = parent.children[isInitialActiveChild ? 0 : 1];
+ const isActiveSlide =
+ child.classList.contains('-shown') || child.classList.contains('-shownAnimated'); // check -shownAnimated for Safari bug
+ return isActiveSlide ? activeDate : getDateAccordingToMonth(activeDate, monthChangeDirection);
+};
+
+const animateContent = ({ parent, direction }) => {
+ const wrapperChildren = Array.from(parent.children);
+ const shownItem = wrapperChildren.find(child => child.classList.contains('-shown'));
+ const hiddenItem = wrapperChildren.find(child => child !== shownItem);
+ const baseClass = shownItem.classList[0];
+ const isNextMonth = direction === 'NEXT';
+ const getAnimationClass = value => (value ? '-hiddenNext' : '-hiddenPrevious');
+ hiddenItem.style.transition = 'none';
+ shownItem.style.transition = '';
+ shownItem.className = `${baseClass} ${getAnimationClass(!isNextMonth)}`;
+ hiddenItem.className = `${baseClass} ${getAnimationClass(isNextMonth)}`;
+ hiddenItem.classList.add('-shownAnimated');
+};
+
+const handleSlideAnimationEnd = ({ target }) => {
+ target.classList.remove('-hiddenNext');
+ target.classList.remove('-hiddenPrevious');
+ target.classList.replace('-shownAnimated', '-shown');
+};
+
+export { animateContent, getSlideDate, handleSlideAnimationEnd };
diff --git a/src/components/Calendar/index.css b/src/components/Calendar/index.css
new file mode 100644
index 0000000..80bf162
--- /dev/null
+++ b/src/components/Calendar/index.css
@@ -0,0 +1,817 @@
+.Calendar *{
+ font-family: 'iranSans';
+}
+
+.DatePicker {
+ position: relative;
+ display: inline-block;
+ z-index: 100;
+ }
+
+ .DatePicker__input {
+ background: #fff;
+ border: 1px solid rgba(0, 0, 0, 0.4);
+ padding: 0.6em 1.2em;
+ font-family:'iranSans';
+ text-align: center;
+ font-size: 12px;
+ border-radius: 7px;
+
+ }
+ .DatePicker__input:focus{
+ outline:1px solid #06BACE;
+ color: #06BACE;
+ }
+
+ .DatePicker__input.-rtl {
+ direction: rtl;
+ }
+
+ .DatePicker__input::placeholder {
+ color: #979797;
+ }
+ .DatePicker__input:focus::placeholder{
+ color: #06BACE;
+ }
+
+ .DatePicker__calendarContainer.-top + .DatePicker__calendarArrow {
+ top: auto;
+ bottom: calc(100% + 10px);
+ transform: translateY(-2.5rem) rotate(180deg);
+ animation: fadeArrowFlipped 0.3s forwards;
+ }
+
+ .DatePicker__calendarContainer {
+ position: absolute;
+ top: calc(100% + 20px);
+ left: 50%;
+ transform: translateX(-50%);
+ }
+
+ .DatePicker__calendarContainer.-top {
+ top: auto;
+ bottom: calc(100% + 20px);
+ }
+
+ .Calendar,
+ .Calendar * {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ direction: ltr;
+ }
+
+ .Calendar,
+ .Calendar.-rtl * {
+ direction: rtl;
+ }
+
+ .DatePicker__calendarArrow {
+ position: absolute;
+ width: 0;
+ height: 0;
+ top: calc(100% + 10px);
+ left: 0;
+ right: 0;
+ margin: 0 auto;
+ border-style: solid;
+ z-index: 10;
+ border-width: 0 10px 10px 10px;
+ border-color: transparent transparent #fff transparent;
+
+ }
+
+ .Calendar {
+ --cl-color-black: #444444;
+ --cl-color-disabled: #d4d4d4;
+ --cl-color-error: #ff2929;
+ font-family:'iranSans';
+ font-size: 10px;
+ background: rgba(245, 245, 245, 0.53);
+ border:1px solid #DBDBDB;
+ box-shadow: 0 1em em rgba(0, 0, 0, 0.07);
+ border-radius: 1em;
+ position: relative;
+ user-select: none;
+ /* padding-top: 1.2em; */
+ display: flex;
+ flex-direction: column;
+ width: 90%;
+ z-index: 10;
+ max-width: 90vw;
+ /* min-height: 38.7em; */
+ }
+ .Calendar.dashboard{
+ --cl-color-black: #444444;
+ --cl-color-disabled: #d4d4d4;
+ --cl-color-error: #ff2929;
+ font-family:'iranSans';
+ font-size: 10px;
+ background: rgba(255, 255, 255, 1);
+ border:1px solid #EDF2FB;
+ box-shadow: 0 1em em rgba(0, 0, 0, 0.07);
+ border-radius: 1em;
+ position: relative;
+ user-select: none;
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+
+ z-index: 10;
+ max-width: 90vw;
+ /* min-height: 38.7em; */
+ }
+
+ .DatePicker .Calendar,
+ .DatePicker__calendarArrow {
+ transform: translateY(2.5em);
+ opacity: 0;
+ animation: fadeCalendar 0.3s forwards;
+
+ }
+
+ .DatePicker__calendarContainer.-top .Calendar {
+ transform: translateY(-2.5em);
+ }
+
+ .Calendar.-noFocusOutline *:focus {
+ outline: none !important;
+ }
+
+ .Calendar > :not(.Calendar__footer) button {
+ font-family: inherit;
+ background: transparent;
+ cursor: pointer;
+ -webkit-tap-highlight-color: transparent;
+ outline: none;
+ }
+
+ .Calendar__header {
+ display: flex;
+ color: var(--cl-color-black);
+ padding: 10px ;
+ align-items: center;
+ overflow: hidden;
+ }
+
+
+ .Calendar__monthArrowWrapper:focus {
+ outline: 1px dashed rgba(0, 0, 0, 0.4);
+ outline-offset: 2px;
+ }
+
+ .Calendar__monthArrowWrapper:disabled,
+ .Calendar__monthArrowWrapper.-hidden {
+ opacity: 0;
+ pointer-events: none;
+ }
+
+ .Calendar__monthArrowWrapper.-left {
+ transform: rotate(180deg);
+ }
+ .Calendar.-rtl .Calendar__monthArrowWrapper.-left {
+ transform: rotate(-180deg);
+ }
+
+ .Calendar__monthArrowWrapper.-right {
+ transform: rotate(-0deg);
+
+ }
+ .Calendar.-rtl .Calendar__monthArrowWrapper.-right {
+ transform: rotate(0deg);
+ }
+
+ .Calendar__monthArrowWrapper:active .Calendar__monthArrow {
+ transform: scale(0.7);
+ }
+
+
+ .Calendar__monthYearContainer {
+ flex: 1;
+ position: relative;
+ }
+
+ .Calendar__monthYear {
+ font-size: 20px;
+ font-weight: 500;
+ display: flex;
+ align-items: center;
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ /* left: 50%; */
+ right:0;
+ background-color: green;
+ will-change: transform, opacity;
+ backface-visibility: hidden;
+ transform: translateZ(0);
+ transition: var(--animation-duration);
+ line-height: 1;
+ color:#df1452;
+ }
+ .Calendar__monthYear.dashboard {
+ font-size: 20px;
+ font-weight: 500;
+ display: flex;
+ align-items: center;
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ /* left: 50%; */
+ will-change: transform, opacity;
+ backface-visibility: hidden;
+ transform: translateZ(0);
+ transition: var(--animation-duration);
+ line-height: 1;
+ color:#df1452;
+ }
+
+
+ .Calendar__monthYear.-hiddenNext {
+ opacity: 0;
+ display: none;
+ transform: translateX(50%);
+ }
+
+ .Calendar.-rtl .Calendar__monthYear.-hiddenNext {
+ transform: translateX(-150%);
+ }
+
+ .Calendar__monthYear.-hiddenPrevious {
+ opacity: 0;
+ transform: translateX(-150%);
+ }
+
+ .Calendar.-rtl .Calendar__monthYear.-hiddenPrevious {
+ transform: translateX(50%);
+ }
+
+ .Calendar__monthYear.-shown {
+ opacity: 1;
+ margin-top: auto;
+ margin-bottom: auto;
+ transform: translateX(-50%);
+ }
+
+ .Calendar__monthYear.-shownAnimated {
+ animation: var(--animation-duration) fadeTextToCenter forwards;
+ }
+
+ .Calendar__monthYear > * {
+ padding: 0.2em 0.5em;
+ border: 1px solid transparent;
+ transition: var(--animation-duration);
+ font-size: 1.05em;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ transform: translateX(0) scale(0.95);
+ will-change: transform;
+ border-radius: 5px;
+ }
+
+ .Calendar__monthYear:not(.-shown) > *,
+ .Calendar__monthYear > *.-hidden {
+ cursor: default;
+ pointer-events: none;
+ }
+
+ .Calendar__monthText {
+ margin-left: -0.3em;
+ }
+ .Calendar__yearText:last-child {
+ margin-right: -0.3em;
+ }
+
+ .Calendar__monthYear.-shown > *:hover,
+ .Calendar:not(.-noFocusOutline) .Calendar__monthYear.-shown > *:focus,
+ .Calendar__monthYear > *.-activeBackground {
+ background: #f5f5f5;
+ }
+
+ .Calendar__monthText:hover {
+ transform: translateX(-0.2em) scale(0.95);
+ }
+ .Calendar.-rtl .Calendar__monthText:hover {
+ transform: translateX(0.2em) scale(0.95);
+ }
+
+ .Calendar__yearText:hover {
+ transform: translateX(0.2em) scale(0.95);
+ }
+ .Calendar.-rtl .Calendar__yearText:hover {
+ transform: translateX(-0.2em) scale(0.95);
+ }
+
+ .Calendar__monthYear .Calendar__yearText.-hidden {
+ transform: translateX(50%);
+ opacity: 0;
+ }
+
+ .Calendar.-rtl .Calendar__monthYear .Calendar__yearText.-hidden {
+ transform: translateX(-50%);
+ }
+
+ .Calendar__monthYear .Calendar__monthText.-hidden {
+ transform: translateX(-50%);
+ opacity: 0;
+ }
+
+ .Calendar.-rtl .Calendar__monthYear .Calendar__monthText.-hidden {
+ transform: translateX(50%);
+ }
+
+ .Calendar__monthYear:not(.-shown) > * {
+ pointer-events: none;
+ }
+
+ .Calendar__monthSelectorAnimationWrapper,
+ .Calendar__yearSelectorAnimationWrapper {
+ position: absolute;
+ width: 100%;
+ height: 80%;
+ bottom: 0;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ overflow: hidden;
+ }
+
+ .Calendar__monthSelectorWrapper {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ }
+
+ .Calendar__monthSelector {
+ padding: 0 2.5em;
+ align-content: center;
+ padding-bottom: 2em;
+ }
+
+ .Calendar__monthSelector,
+ .Calendar__yearSelector {
+ display: flex;
+ flex-wrap: wrap;
+ position: relative;
+ z-index: 2;
+ background-color: #fff;
+ transform: translateY(-150%);
+ will-change: transform;
+ transition: 0.6s;
+ height: 100%;
+ }
+
+ .Calendar__yearSelectorWrapper {
+ width: 100%;
+ height: 100%;
+ }
+
+ .Calendar__yearSelectorWrapper::after,
+ .Calendar__yearSelectorWrapper::before {
+ content: '';
+ width: 100%;
+ height: 5em;
+ position: absolute;
+ left: 0;
+ opacity: 0;
+ transition: 0.4s;
+ transition-delay: 0.2s;
+ }
+
+ .Calendar__yearSelectorWrapper::after {
+ background-image: linear-gradient(to bottom, #fff, #fff 10%, rgba(245, 245, 245, 0));
+ top: -0.1em;
+ }
+
+ .Calendar__yearSelectorWrapper::before {
+ background-image: linear-gradient(to top, #fff, #fff 10%, rgba(245, 245, 245, 0));
+ bottom: 0;
+ }
+
+ .Calendar__yearSelectorWrapper.-faded::after,
+ .Calendar__yearSelectorWrapper.-faded::before {
+ opacity: 1;
+ z-index: 3;
+ }
+
+ .Calendar__yearSelector {
+ align-content: flex-start;
+ scrollbar-width: 0;
+ overflow: scroll;
+ position: relative;
+ width: 100%;
+ padding: 5em 2em;
+ -ms-overflow-style: none;
+ }
+
+ .Calendar__yearSelector::-webkit-scrollbar {
+ display: none;
+ }
+
+ .Calendar__yearSelectorItem {
+ width: 25%;
+ display: flex;
+ justify-content: center;
+ }
+
+ .Calendar__yearSelectorItem:not(:nth-child(-n + 4)) {
+ margin-top: 1.5em;
+ }
+
+ .Calendar__yearSelectorText {
+ border: none;
+ font-size: 1.4em;
+ min-width: 85%;
+ padding: 0.2em 0.5em;
+ border-radius: 5px;
+ }
+
+ .Calendar__monthSelector.-open,
+ .Calendar__yearSelector.-open {
+ transform: translateY(0);
+ }
+
+ .Calendar__yearSelectorText:focus,
+ .Calendar__monthSelectorItemText:focus {
+ outline: 1px dashed rgba(0, 0, 0, 0.4);
+ outline-offset: 2px;
+ }
+
+ .Calendar__monthSelectorItem {
+ width: calc(100% / 3);
+ display: flex;
+ justify-content: center;
+ }
+
+ .Calendar__monthSelectorItem:not(:nth-child(-n + 3)) {
+ margin-top: 2em;
+ }
+
+ .Calendar__monthSelectorItemText {
+ border: none;
+ padding: 0.4em 0.4em;
+ border-radius: 8.5px;
+ font-size: 1.3em;
+ min-width: 70%;
+ transition: 0.3s;
+ }
+
+ .Calendar__monthSelectorItem:not(.-active) .Calendar__monthSelectorItemText:not(:disabled):hover,
+ .Calendar__yearSelectorItem:not(.-active) .Calendar__yearSelectorText:not(:disabled):hover {
+ background: #f5f5f5;
+ }
+
+ .Calendar__monthSelectorItemText:disabled,
+ .Calendar__yearSelectorText:disabled {
+ opacity: 0.5;
+ cursor: default;
+ }
+
+ .Calendar__monthSelectorItem.-active .Calendar__monthSelectorItemText,
+ .Calendar__yearSelectorItem.-active .Calendar__yearSelectorText {
+ background-color: #006C94;
+ color: #fff;
+ }
+
+ .Calendar__weekDays {
+ display: flex;
+ justify-content: space-between;
+ color: var(--cl-color-disabled);
+ font-size: 1.2em;
+ /* padding: 0 2.6em; */
+ position: relative;
+ }
+ .Calendar__weekDays.dashboard {
+ display: flex;
+ justify-content: space-between;
+ color: var(--cl-color-disabled);
+ font-size: 10px;
+ margin-top: 10px;
+ /* padding: 10px 15px; */
+ position: relative;
+ /* background-color: #EDF2FB; */
+ }
+
+ .Calendar__weekDay {
+ display: block;
+ width: calc(100% / 7);
+ /* background: #00253A; */
+ text-align: center;
+ text-decoration: none;
+ border: 0px;
+ color: #06BACE;
+ /* margin:0.2em; */
+ white-space: nowrap;
+ }
+ .Calendar__weekDay.dashboard{
+ color:#A2B4CB;
+ }
+ .Calendar__weekDay[title]{
+ text-decoration: none;
+ }
+
+ .Calendar__sectionWrapper {
+ position: relative;
+ min-height: 275px;
+ overflow: hidden;
+ }
+
+ .Calendar__section {
+ display: flex;
+ flex-direction: column;
+
+ position: absolute;
+ color: var(--cl-color-black);
+ top: 0;
+ /* padding-top: 0.5em; */
+ left: 0;
+ width: 100%;
+ will-change: transform, opacity;
+ transform: translateZ(0);
+ backface-visibility: hidden;
+ transition: var(--animation-duration);
+ }
+
+ .Calendar__section.-hiddenPrevious {
+ opacity: 0.5;
+ transform: translateX(-100%);
+ }
+
+ .Calendar.-rtl .Calendar__section.-hiddenPrevious {
+ transform: translateX(100%);
+ }
+
+ .Calendar__section.-hiddenNext {
+ opacity: 0.5;
+ transform: translateX(100%);
+ }
+
+ .Calendar.-rtl .Calendar__section.-hiddenNext {
+ transform: translateX(-100%);
+ }
+
+ .Calendar__section.-shown {
+ opacity: 1;
+ transform: translateX(0);
+ }
+
+ .Calendar__section.-shownAnimated {
+ animation: var(--animation-duration) FadeContentToCenter forwards;
+ }
+
+ .Calendar__weekRow {
+ display: flex;
+ width: 100%;
+ }
+
+ .Calendar__day {
+ width: calc(100% / 7 );
+ text-align: center;
+ padding: calc(0.25em - 1px);
+ font-size: 1.6em;
+ border-radius: 7px;
+ transition: 0.2s;
+ border: 1px solid transparent;
+ margin:3px;
+ color: rgba(0, 0, 0, 0.8);
+ display: flex;
+ align-items: center;
+
+ cursor: pointer;
+ vertical-align: middle;
+ background-color: #F3F3F3;
+ color:#06BACE;
+
+ }
+ .Calendar__day.dashboard {
+ width: calc(100% / 7 - 6px);
+ text-align: center;
+ padding: calc(0.25em - 1px);
+ font-size: 1.6em;
+ border-radius: 7px;
+ transition: 0.2s;
+ border: 1px solid transparent;
+ margin:3px;
+ color: rgba(0, 0, 0, 0.8);
+ display: flex;
+ align-items: center;
+
+ cursor: pointer;
+ vertical-align: middle;
+ background-color: transparent;
+ color:#00253A;
+
+ }
+ .Calendar__day span{
+ padding: -10px;
+ margin-top: -30px;
+ font-size: 28px;
+
+ }
+
+ .Calendar__day:focus {
+ outline: 1px dashed rgba(0, 0, 0, 0.4);
+ outline-offset: 2px;
+ }
+
+ .Calendar__day.-ltr {
+ min-height: 2.6em;
+ font-size: 1.45em;
+ }
+
+ .Calendar__day.-rtl {
+ font-size: 1.55em;
+ height: 40px;
+ }
+
+ .Calendar__day:not(.-blank):not(.-selectedStart):not(.-selectedEnd):not(.-selectedBetween):not(.-selected):hover {
+
+ background-color: rgba(223, 20, 82, 0.06);
+ color: #df1452;
+ border:1px solid #df1452;
+ }
+
+ .Calendar__day.-selected,
+ .Calendar__day.-selectedStart,
+ .Calendar__day.-selectedEnd {
+ background: rgba(223, 20, 82, 0.06);
+ color: #df1452;
+ }
+
+ .Calendar__day.-ltr.-selectedStart {
+ border-radius: 0;
+ border-top-left-radius: 7px;
+ border-bottom-left-radius: 7px;
+ }
+
+ .Calendar__day.-rtl.-selectedStart {
+ border-radius: 0;
+ border-top-right-radius: 7px;
+ border-bottom-right-radius: 7px;
+ }
+
+ .Calendar__day.-selectedBetween {
+ background:rgba(0, 108, 148, 0.07);
+
+ border-radius: 0;
+ }
+
+ .Calendar__day.-ltr.-selectedEnd {
+ border-radius: 0;
+ border-top-right-radius: 7px;
+ border-bottom-right-radius: 7px;
+ }
+
+ .Calendar__day.-rtl.-selectedEnd {
+ border-radius: 0;
+ border-top-left-radius: 7px;
+ border-bottom-left-radius: 7px;
+ }
+
+ .Calendar__day.-weekend:not(.-selected):not(.-blank):not(.-selectedStart):not(.-selectedEnd):not(.-selectedBetween) {
+ color: var(--cl-color-error);
+ }
+
+ .Calendar__day.-weekend.-today:not(.-selectedStart):not(.-selectedEnd):not(.-selectedBetween)::after {
+ background: var(--cl-color-error);
+ }
+
+ .Calendar__day.-disabled {
+ color: var(--cl-color-disabled) !important;
+ background: transparent !important;
+ cursor: default !important;
+ }
+ .Calendar__day.-selected {
+
+ }
+ .Calendar__day.-today:not(.-selectedStart):not(.-selectedEnd):not(.-selectedBetween) {
+ font-weight: 600;
+ color: var(--cl-color-black);
+ color: #000;
+ position: relative;
+ }
+
+ .Calendar__day.-today:not(.-selectedStart):not(.-selectedEnd):not(.-selectedBetween)::after {
+ content: '';
+ position: absolute;
+ bottom: 0.2em;
+ display: block;
+ width: 0.6em;
+ height: 1px;
+ background: #000;
+ left: 50%;
+ opacity: 0.5;
+ transform: translateX(-50%);
+ transition: 0.2s;
+ }
+
+ .Calendar__day.-today:hover:not(.-selectedStart):not(.-selectedEnd):not(.-selectedBetween)::after {
+ opacity: 0;
+ }
+
+ .Calendar__day.-blank {
+ color: transparent;
+ cursor: default;
+ pointer-events: none;
+ }
+
+ .Calendar__footer {
+ position: relative;
+ z-index: 1;
+ }
+ .Calendar__footer .footer__Events{
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ font-size: 12px;
+ font-family: 'IranSans';
+ padding: 3px;
+ }
+ .Calendar__footer .footer__Events.dashboard{
+ display: flex;
+ justify-content: start;
+ width: 100%;
+ align-items: flex-start;
+ font-size: 12px;
+ font-family: 'IranSans';
+ margin-top: 10px;
+ padding: 1em 2em;
+ border-top: 1px solid #EDF2FB;
+
+ }
+
+ .Calendar__footer .footer__Events.dashboard p{
+
+ font-size: 15px;
+ margin:2.5px 0px
+
+ }
+
+
+
+ .Calendar .holiday span{
+ color:#ff2929;
+ }
+ .Calendar .DayNumDiv{
+ display: flex;
+ flex-direction: column;
+ }
+ .Calendar .DayNumDiv span{
+ margin: 0;
+ padding: 0;
+ margin-bottom: -5px;
+ }
+ .Calendar .DayNumDiv .eventDots{
+ margin-top: -10px;
+ font-size: 20px;
+ }
+ .GoToTodayButton{
+ background-color: #006C94;
+ padding: 7.5px;
+ font-size: 12px;
+ color:white;
+ font-family: 'iranSans';
+ border-radius: 50%;
+ float: left;
+ margin: 15px;
+
+ }
+ @keyframes fadeCalendar {
+ from {
+ opacity: 0;
+ }
+
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+ }
+
+ @keyframes fadeArrowFlipped {
+ from {
+ opacity: 0;
+ }
+
+ to {
+ opacity: 1;
+ transform: translateY(0) rotate(180deg);
+ }
+ }
+
+ @keyframes fadeTextToCenter {
+ to {
+ opacity: 1;
+ transform: translateX(-50%);
+ }
+ }
+
+ @keyframes FadeContentToCenter {
+ to {
+ opacity: 1;
+ transform: translateX(0);
+ }
+ }
+
\ No newline at end of file
diff --git a/src/components/Calendar/index.js b/src/components/Calendar/index.js
new file mode 100644
index 0000000..8d6871b
--- /dev/null
+++ b/src/components/Calendar/index.js
@@ -0,0 +1,117 @@
+import React, { useState } from "react";
+import './index.css';
+import Calendar from "./CalendarComponents/Calendar";
+import { utils } from "./CalendarComponents";
+
+import './index.css';
+
+const SimpleCalendar = () => {
+ const [selectedDay, setSelectedDay] = useState(null);
+ const [type, setType] = useState('dashboard');
+ const list = {
+ 'default': setSelectedDay(utils('fa').getToday())}> امروز }
+ locale="fa"
+ events={eventsList}
+
+ />,
+ 'dashboard': ,
+ }
+
+ return (
+
+
+ {/* setSelectedDay(utils('fa').getToday())}> امروز }
+ locale="fa"
+ events={eventsList}
+ type='dashboard'
+ /> */}
+
+
+
+
+
+ );
+};
+
+const eventsList = [
+ {
+ id: 2,
+ description: "تست 2",
+ type: "global",
+ isHoliday: true,
+ date: "2022-01-04T00:00:00.000Z",
+ year: 1400,
+ month: 10,
+ day: 2
+ },
+ {
+ id: 4,
+ description: "تست 4",
+ type: "global",
+ isHoliday: true,
+ date: "2022-01-12T00:00:00.000Z",
+ year: 1400,
+ month: 10,
+ day: 1
+ },
+ {
+ id: 1,
+ description: "تست کاربر 1",
+ type: "userDefined",
+ userId: "5",
+ date: "2022-01-12T00:00:00.000Z",
+ categoryId: 1,
+ year: 1400,
+ month: 10,
+ day: 3,
+ color: 'blue'
+ },
+ {
+ id: 4,
+ description: "تست کاربر 4",
+ type: "userDefined",
+ userId: "5",
+ date: "2022-01-08T00:00:00.000Z",
+ categoryId: 3,
+ year: 1400,
+ month: 11,
+ day: 6
+ },
+ {
+ id: 5,
+ description: "تست کاربر 5",
+ type: "userDefined",
+ userId: "5",
+ date: "2022-01-12T00:00:00.000Z",
+ categoryId: 1,
+ year: 1400,
+ month: 10,
+ day: 3
+ }
+];
+
+export default SimpleCalendar;
\ No newline at end of file
diff --git a/src/components/exam/Carousel/index.css b/src/components/exam/Carousel/index.css
new file mode 100644
index 0000000..04ae80c
--- /dev/null
+++ b/src/components/exam/Carousel/index.css
@@ -0,0 +1,298 @@
+
+
+ .my-exam-list{
+ width: 100%;
+ /* margin-top: 25px; */
+ direction: rtl;
+ }
+
+
+
+ .my-exam-list-content{
+ width: 100%;
+ border: 1px solid #E0E0E0;
+ overflow: hidden;
+ background-color: white;
+ }
+
+ .melc-header{
+ width: 100%;
+ height: 65px;
+ display: flex;
+ align-items: center;
+ border-bottom: 5px solid #F6F6F6;
+ position: relative;
+ }
+
+ .melc-h-tab-name-item{
+ width: fit-content;
+ padding: 0 10px;
+ height: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 17px;
+ font-family: IRANSans;
+ color: #B1B1B1;
+ margin-right: 35px;
+ position: relative;
+ cursor: pointer;
+ }
+
+ .melc-h-tab-name-item-line{
+ width: 100%;
+ height: 5px;
+ background-color: #df1452;
+ position: absolute;
+ right: 0;
+ border-radius: 10px;
+ bottom: -5px;
+ }
+
+ .melc-h-move-btns{
+ position: absolute;
+ left: 27px;
+ height: 100%;
+ display: flex;
+ width: 70px;
+ justify-content: space-between;
+ align-items: center;
+ direction: ltr;
+ font-size: 15px;
+ font-family: IRANSans;
+ color: #df1452;
+ }
+
+ .melc-h-move-btns *{
+ font-size: 30px;
+ color: #df1452;
+ cursor: pointer;
+ }
+
+
+ .melc-content{
+ width: 100%;
+ height: 281px;
+ position: relative;
+ }
+
+ .melc-content-dark-cover{
+ position: absolute;
+ top: 30px;
+ left: -187px;
+ /* height: 100%; */
+ width: 14.42vw;
+ aspect-ratio: 0.989/1;
+ border-radius: 0 12px 30px;
+ background-color: rgb(0, 0, 0);
+ opacity: 0.7;
+ }
+
+ .melc-content-item{
+ /* width: 100%; */
+ /* height: 280px; */
+ margin: 30px 0;
+ /* margin-top: 30px; */
+ margin-right: 35px;
+ display: flex;
+ position: absolute;
+ top: 0;
+ right: 0;
+ transition: all 0.6s ease;
+ }
+
+ .melc-content-item-more{
+ width: 221px;
+ flex-shrink: 0;
+ height: 221px;
+ border-radius: 25px 12px 30px 6px;
+ margin-left: 20px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ text-decoration: none;
+ font-size: 30px;
+ font-family: IRANSans;
+ color: #df1452;
+ border: 2px solid #E0E0E0;
+ cursor: pointer;
+ }
+
+ .melc-content-item-more:hover{
+ background-color: #E0E0E0;
+ /* background-color: rgba(46,129,232, 0.1); */
+ color: white;
+ }
+
+
+ .melc-content-i-item{
+ width: 221px;
+ /* width: 27.34%; */
+ /* width: 14.42vw !important;
+ aspect-ratio: 0.989/1; */
+ flex-shrink: 0;
+ height: 221px;
+ position: relative;
+ border-radius: 25px 12px 30px 6px;
+ margin-left: 20px;
+ overflow: hidden;
+ }
+
+ .melc-c-i-i-bg{
+ width: 100%;
+ height: 100%;
+ }
+
+ .melc-c-i-i-exam-sit{
+ position: absolute;
+ top: 20px;
+ left: 10px;
+ padding: 5px 5px;
+ display: flex;
+ align-items: center;
+ color: #FF0000;
+ background-color: white;
+ border-radius: 5px;
+ }
+
+ .melc-c-i-i-exam-sit-text{
+ margin-right: 1px;
+ font-size: 9px;
+ font-weight: 700;
+ font-family: IRANSans;
+ }
+
+ .melc-c-i-i-cover{
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ top:0;
+ right: 0;
+ background: rgb(0,0,0);
+ background: linear-gradient(0deg, rgba(0,0,0,1) 0%, rgba(0,0,0,0) 100%);
+ }
+
+ .melc-c-i-i-under-cover{
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ top:0;
+ right: 0;
+ transform: scaleY(0);
+ transform-origin: bottom;
+ transition: all 0.5s ease;
+ }
+
+ .melc-c-i-item-info{
+ position: absolute;
+ bottom: 17px;
+ right: 50%;
+ transform: translateX(50%);
+ width: 90%;
+ /* background-color: aquamarine; */
+ }
+
+ .melc-c-i-i-info-title{
+ display: flex;
+ align-items: center;
+ color: white;
+ font-size: 14px;
+ font-family: IRANSans;
+ }
+
+ .melc-c-i-i-info-title img{
+ margin-left: 5px;
+ }
+
+ .melc-c-i-i-info-date-time{
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ }
+
+ .melc-ciiidt-date-container{
+ display: flex;
+ align-items: center;
+ margin-right: 3px;
+ color: white;
+ }
+
+ .melc-clock-icon{
+ font-size: 20px;
+
+ }
+
+ .melc-ciiidt-date{
+ color: white;
+ font-size: 10px;
+ font-family: IRANSansXFaNum-Regular;
+ margin-right: 5px;
+ }
+
+ .melc-ciiidt-time{
+ color: white;
+ font-size: 10px;
+ font-family: IRANSans;
+ margin-left: 5px;
+ }
+
+ .melc-c-i-i-info-line{
+ width: 100%;
+ height: 1px;
+ background-color: white;
+ opacity: 13%;
+ margin-top: 3px;
+ margin-bottom: 3px;
+ }
+
+ .melc-c-i-i-info-descriptin{
+ width: 100%;
+ font-size: 11px;
+ font-family: IRANSans;
+ color: white;
+
+ max-height: 0;
+ transform: translateY(140px);
+ overflow: hidden;
+ text-overflow: ellipsis;
+ transition: all 0.5s ease;
+ /* margin-top: 10px;
+ margin-bottom: 5px; */
+
+ }
+
+ .descript_is_active{
+ /* margin-top: 15px; */
+ /* display: block; */
+ transform: translateY(0);
+ /* overflow: hidden; */
+ display: -webkit-box;
+ -webkit-line-clamp: 4; /* number of lines to show */
+ -webkit-box-orient: vertical;
+ max-height: none;
+ margin-top: 10px;
+ margin-bottom: 5px;
+
+ }
+
+ /* * --------responsive-setting---------------------------------------------------------- */
+ @media screen and (max-width: 1200px){
+ .melc-h-tab-name-item{
+ font-size: 15px;
+ }
+ }
+
+ @media screen and (max-width: 1110px){
+ .melc-h-tab-name-item{
+ font-size: 13px;
+ }
+ }
+
+ @media screen and (max-width: 1070px){
+ .melc-h-tab-name-item{
+ font-size: 12px;
+ }
+ }
+
+
+
\ No newline at end of file
diff --git a/src/components/exam/Carousel/index.js b/src/components/exam/Carousel/index.js
new file mode 100644
index 0000000..da0bfa7
--- /dev/null
+++ b/src/components/exam/Carousel/index.js
@@ -0,0 +1,355 @@
+import "./index.css";
+import { IoIosArrowBack, IoIosArrowForward } from "react-icons/io";
+import { GoPrimitiveDot } from "react-icons/go";
+import calendar_icon from "../../../assets/img/stickynote.svg";
+import { BsClock } from "react-icons/bs";
+import { useEffect, useState } from "react";
+import { useSelector } from "react-redux";
+import { Link } from "react-router-dom";
+import moment from "jalali-moment";
+import { state } from "./state";
+import ScrollContainer from "react-indiana-drag-scroll";
+
+
+const MyExamList = () => {
+
+ //create suitable data list with main data----------------------------------------------------
+ let d = new Date();
+ console.log("today:"+d);
+ let d_day = d.getDay();
+ console.log("today_day:"+d_day);
+ let LastDayWeekDate=d;
+ switch (d_day) {
+ case 1:
+ LastDayWeekDate.setDate(d.getDate() + 4);
+ break;
+ case 2:
+ LastDayWeekDate.setDate(d.getDate() + 3);
+ break;
+ case 3:
+ LastDayWeekDate.setDate(d.getDate() + 2);
+ break;
+ case 4:
+ LastDayWeekDate.setDate(d.getDate() + 1);
+ break;
+ case 6:
+ LastDayWeekDate.setDate(d.getDate() + 6);
+ break;
+ case 7:
+ LastDayWeekDate.setDate(d.getDate() + 5);
+ break;
+ default:
+ LastDayWeekDate=d
+ break;
+ }
+ let my_exam_list_data2 = [
+ {
+ id: 1,
+ tab_name: "همه",
+ isActive: true,
+ tab_content: []
+ },
+ {
+ id: 2,
+ tab_name: "آزمونهای این هفته",
+ isActive: false,
+ tab_content: []
+ },
+ {
+ id: 3,
+ tab_name: "آزمونهای آینده",
+ isActive: false,
+ tab_content: []
+ },
+ {
+ id: 4,
+ tab_name: "آزمونهای در حال برگزاری",
+ isActive: false,
+ tab_content: []
+ },
+ ]
+ for(let b=0;bLastDayWeekDate){
+ TabType = 2;
+ my_exam_list_data2[2].tab_content.push({...state[b],tabType:2,sub_id:3});
+ }
+ let D = new Date();
+ if(D>date && D {
+ // console.log("render---------------");
+ document.querySelector(".melc-content-item").style.right = `0px`;
+ });
+
+ const change_tab = (id) => {
+ let new_data = data.map((item) => {
+ if (item.id === old_tab_id) {
+ item.isActive = false;
+ }
+ if (item.id === id) {
+ item.isActive = true;
+ }
+ return { ...item };
+ });
+ // console.log(new_data);
+ set_data(new_data);
+ set_old_tab_id(id);
+ // console.log(old_tab_id);
+ };
+
+ let i = 0;
+ let max_i;
+ for (let j = 0; j < data.length; j++) {
+ // console.log(data[j].isActive);
+ if (data[j].isActive) {
+ max_i = (data[j].tab_content.length - 3) * -1;
+ // console.log(max_i);
+ }
+ }
+
+ // const state = useSelector((state) => state.default);
+
+ if (state.openNav === "open") {
+ max_i--;
+ if (window.innerWidth < 1360) {
+ let tab_name_item = document.querySelectorAll(".melc-h-tab-name-item");
+ for (let p = 0; p < tab_name_item.length; p++) {
+ tab_name_item[p].style.fontSize = "15px";
+ }
+ }
+ if (window.innerWidth < 1305) {
+ let tab_name_item = document.querySelectorAll(".melc-h-tab-name-item");
+ for (let p = 0; p < tab_name_item.length; p++) {
+ tab_name_item[p].style.fontSize = "13px";
+ }
+ }
+ if (window.innerWidth < 1212) {
+ let tab_name_item = document.querySelectorAll(".melc-h-tab-name-item");
+ for (let p = 0; p < tab_name_item.length; p++) {
+ tab_name_item[p].style.fontSize = "11px";
+ }
+ }
+ }
+ if (window.innerWidth < 1536) {
+ max_i--;
+ }
+ if (window.innerWidth < 1170) {
+ max_i--;
+ }
+
+ const move_left = () => {
+ if (i > max_i) {
+ i--;
+ let movment = i * 245;
+ document.querySelector(".melc-content-item").style.right = `${movment}px`;
+ }
+ };
+
+ const move_right = () => {
+ if (i < 0) {
+ i++;
+ let movment = i * 245;
+ document.querySelector(".melc-content-item").style.right = `${movment}px`;
+ }
+ };
+ let s = 0;
+ const item_active_hover = (id, sub_id) => {
+ // console.log(id,sub_id);
+ // s = 0;
+ let ss = 0;
+ for (let k = 0; k < data.length; k++) {
+ s = 0;
+ for (let v = 0; v < data[k].tab_content.length; v++) {
+ // console.log(data[k].tab_content[v])
+ s++;
+ if (
+ data[k].tab_content[v].id === id &&
+ data[k].tab_content[v].sub_id === sub_id
+ ) {
+ ss = 1;
+ break;
+ }
+ }
+ if (ss) {
+ break;
+ }
+ }
+ // console.log(s);
+ document.querySelectorAll(".melc-c-i-i-under-cover")[
+ s - 1
+ ].style.transform = "scaleY(1)";
+ document
+ .querySelectorAll(".melc-c-i-i-info-descriptin")
+ [s - 1].classList.add("descript_is_active");
+ // document.querySelectorAll(".melc-c-i-i-info-descriptin")[s-1].style.transform="scaleY(1)";
+ // console.log(e.target.previousElementSibling);
+ //این روش پایدار نیست
+ // if(e.target.previousElementSibling !=null){
+ // e.target.previousElementSibling.style.transform="scaleY(1)";
+ // }
+ };
+
+ const item_deactive_hover = (id, sub_id) => {
+ if (s > 0) {
+ document.querySelectorAll(".melc-c-i-i-under-cover")[
+ s - 1
+ ].style.transform = "scaleY(0)";
+ document
+ .querySelectorAll(".melc-c-i-i-info-descriptin")
+ [s - 1].classList.remove("descript_is_active");
+ }
+ // if(e.target.previousElementSibling !=null){
+ // e.target.previousElementSibling.style.transform="scaleY(0)";
+ // }
+ };
+
+ moment.locale("en");
+
+ return (
+
+
+
+
لیست آزمون های من
+
+ {data.map((item, i) => (
+
change_tab(item.id)}
+ >
+ {item.tab_name}
+ {item.isActive && (
+
+ )}
+
+ ))}
+
+
+
+
+
+
+ {data.map((item) => (
+
+ {item.isActive && (
+
+ {item.isActive &&
+ item.tab_content.map((item) => (
+
+ item_active_hover(item.id, item.sub_id)
+ }
+ onMouseLeave={() =>
+ item_deactive_hover(item.id, item.sub_id)
+ }
+ >
+
+ {item.exam_started && (
+
+ )}
+
+
+
+
+
+ {item.name}
+
+
+
+
+
+
+ {moment(item.date, 'YYYY/MM/DD').format('jYYYY/jM/jD')}
+
+
+
+ ساعت {item.time}
+
+
+
+ {item.descripton}
+
+
+
+ ))}
+
+ مشاهده بیشتر
+
+
+ )}
+
+ ))}
+
+
+
+ );
+};
+
+export default MyExamList;
diff --git a/src/components/exam/Carousel/state.js b/src/components/exam/Carousel/state.js
new file mode 100644
index 0000000..383261f
--- /dev/null
+++ b/src/components/exam/Carousel/state.js
@@ -0,0 +1,470 @@
+export const state = [
+ {
+ id:1,
+ id2:1,
+ img:'https://www.timeforkids.com/wp-content/uploads/2021/01/K1_CMS_0129_1.jpg',
+ name:"آزمون نجوم نظری",
+ // price:458.200,
+ masterPrice:450200,
+ price:405000,
+ badge:"10%",
+ date:"2021-10-26T12:00:00.180Z",
+ endDate:"2021-10-27T12:00:00.180Z",
+ level:"کارشناسی ارشد",
+ type:1, //c فردی ، گروهی
+ time_type:"future", //c دسته بندی زمانی آزمونها برای قرار دادن در داشبرد :"future","live","thisWeek"
+ filter: "collegiate", //c فیلتر کردن آزمون ها با کلیدهای فیلتر در فروشگاه و
+ count:100,
+ exam_started:true,
+ capacity:120,
+ exam_filter:"collegiate", //حذف شود
+ negattiveMode:true, //c نمره منفی
+ types:"تشریحی و تستی", //c نوع سولات
+ guideFileId:"#",
+ text:"از فصل دوم تا چهارم", //c توضیحی کوتاه که در صفحه آزمون استفاده میشود
+ exam_timer:60, //مدت زمان آزمون بر حسب دقیقه
+ // creator:{ //اطلاعات ایجاد کننده آزمون
+ // avatar:avatar1,
+ // name:"موسسه فرهنگی مصباح نور"
+ // },
+ descripton:"لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد", //c اطلاعاتی که در صفحه خرید آزمون استفاده میشود.
+ time:"21:30",
+ html:[
+ "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد",
+ "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد",
+ "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد"
+ ], //اطلاعاتی دیگری که در صفحه خرید آزمون استفاده میشود
+ // video:video1, //ویدیویی درباره آزمون که در صفحه خرید استفاده میشود
+ // video_cover:video_cover1,
+ files:[ //فایل های مورد نیاز برای آمادگی آزمون که در صفحه خرید استفاده میشود
+ [
+ {
+ id:1,
+ text:"دریافت فایل پی دی اف درسهای بخش چهارم و پنجم",
+ path:"#"
+ }
+ ],
+ [
+ {
+ id:1,
+ text:"دریافت فایل ویدیویی درسهای بخش چهارم و پنجم",
+ path:"#"
+ },
+ {
+ id:2,
+ text:"دریافت نرم افزار پخش ویدیو",
+ path:"#"
+ }
+ ]
+ ]
+ },
+ {
+ id:2,
+ id2:2,
+ img:'https://img9.irna.ir/old/Image/1397/13970106/82871315/N82871315-72258180.jpg',
+ name:"آزمون جغرافیای جهان",
+ // price:458.200,
+ masterPrice:340000,
+ price:306000,
+ badge:"10%",
+ date:"2021-10-18T12:00:00.180Z",
+ endDate:"2021-10-19T12:00:00.180Z",
+ level:"پایه دهم",
+ type:2,
+ time_type:"thisWeek",
+ filter: "discounted",
+ exam_filter:"live",
+ count:100,
+ capacity:120,
+ negattiveMode:true,
+ types:"تشریحی و تستی",
+ guideFileId:"#",
+ text:"از فصل سوم تا پنجم",
+ exam_timer:60,
+ // creator:{
+ // avatar:avatar1,
+ // name:"موسسه فرهنگی مصباح نور"
+ // },
+ descripton:"لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد",
+ time:"21:30",
+ html:[
+ "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد",
+ "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد",
+ "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد"
+ ],
+ // video:video1,
+ // video_cover:video_cover1,
+ files:[
+ [
+ {
+ id:1,
+ text:"دریافت فایل پی دی اف درسهای بخش چهارم و پنجم",
+ path:"#"
+ }
+ ],
+ [
+ {
+ id:1,
+ text:"دریافت فایل ویدیویی درسهای بخش چهارم و پنجم",
+ path:"#"
+ },
+ {
+ id:2,
+ text:"دریافت نرم افزار پخش ویدیو",
+ path:"#"
+ }
+ ]
+ ]
+ },
+ {
+ id:3,
+ id2:3,
+ img:'https://images.ctfassets.net/cnu0m8re1exe/7bvBF6E4WXVLLIsH88lXcC/5a3b7483a82fb30248e7d1c7856be6ec/20-things-color.jpg',
+ name:"آزمون رنگشناسی",
+ // price:458.200,
+ masterPrice:100000,
+ price:90000,
+ badge:"10%",
+ date:"2021-10-15T12:00:00.180Z",
+ endDate:"2021-10-17T12:00:00.180Z",
+ level:"کارشناسی",
+ type:1,
+ time_type:"future",
+ filter: "discounted",
+ count:100,
+ capacity:120,
+ exam_filter:"live",
+ negattiveMode:true,
+ types:"تشریحی و تستی",
+ guideFileId:"#",
+ text:"از فصل سوم تا پنجم",
+ exam_timer:60,
+ // creator:{
+ // avatar:avatar1,
+ // name:"موسسه فرهنگی مصباح نور"
+ // },
+ descripton:"لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد",
+ time:"21:30",
+ html:[
+ "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد",
+ "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد",
+ "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد"
+ ],
+ // video:video1,
+ // video_cover:video_cover1,
+ files:[
+ [
+ {
+ id:1,
+ text:"دریافت فایل پی دی اف درسهای بخش چهارم و پنجم",
+ path:"#"
+ }
+ ],
+ [
+ {
+ id:1,
+ text:"دریافت فایل ویدیویی درسهای بخش چهارم و پنجم",
+ path:"#"
+ },
+ {
+ id:2,
+ text:"دریافت نرم افزار پخش ویدیو",
+ path:"#"
+ }
+ ]
+ ]
+ },
+ {
+ id:4,
+ id2:4,
+ img:'https://www.verywellmind.com/thmb/0-wI_ZBZiPEJVTvTPz2U7laZp1Y=/1333x1000/smart/filters:no_upscale()/depression-counseling-4769574_v4-a665f8461b0241079601241700d36487.png',
+ name:"آزمون روان درمانی اگزیستانسیال",
+ // price:458.200,
+ masterPrice:200000,
+ price:180000,
+ discount:"10%",
+ date:"2021-10-25T12:00:00.180Z",
+ endDate:"2021-10-26T12:00:00.180Z",
+ level:"پایه 1 الی 12",
+ type:1,
+ time_type:"live",
+ filter: "none",
+ count:100,
+ capacity:120,
+ exam_filter:"live",
+ negattiveMode:false,
+ types:"تشریحی و تستی",
+ guideFileId:"#",
+ text:"از فصل سوم تا پنجم",
+ exam_timer:60,
+ // creator:{
+ // avatar:avatar1,
+ // name:"موسسه فرهنگی مصباح نور"
+ // },
+ descripton:"لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد",
+ time:"21:30",
+ html:[
+ "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد",
+ "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد",
+ "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد"
+ ],
+ // video:video1,
+ // video_cover:video_cover1,
+ files:[
+ [
+ {
+ id:1,
+ text:"دریافت فایل پی دی اف درسهای بخش چهارم و پنجم",
+ path:"#"
+ }
+ ],
+ [
+ {
+ id:1,
+ text:"دریافت فایل ویدیویی درسهای بخش چهارم و پنجم",
+ path:"#"
+ },
+ {
+ id:2,
+ text:"دریافت نرم افزار پخش ویدیو",
+ path:"#"
+ }
+ ]
+ ]
+ },
+ {
+ id:5,
+ id2:5,
+ img:'https://townsquare.media/site/295/files/2022/01/attachment-GNR-Slash.jpg',
+ name:"آزمون موسیقیشناسی",
+ // price:458.200,
+ masterPrice:200000,
+ price:"",
+ badge:"",
+ date:"2021-10-26T12:00:00.180Z",
+ endDate:"2021-10-27T12:00:00.180Z",
+ level:"پایه 5 الی 12",
+ time_type:"live",
+ type:1,
+ filter: "none",
+ count:100,
+ capacity:120,
+ exam_filter:"live",
+ negattiveMode:true,
+ types:"تشریحی و تستی",
+ guideFileId:"#",
+ text:"از فصل سوم تا پنجم",
+ exam_timer:60,
+ user_num:100,
+ // creator:{
+ // avatar:avatar1,
+ // name:"موسسه فرهنگی مصباح نور"
+ // },
+ descripton:"لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد",
+ time:"21:30",
+ html:[
+ "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد",
+ "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد",
+ "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد"
+ ],
+ // video:video1,
+ // video_cover:video_cover1,
+ files:[
+ [
+ {
+ id:1,
+ text:"دریافت فایل پی دی اف درسهای بخش چهارم و پنجم",
+ path:"#"
+ }
+ ],
+ [
+ {
+ id:1,
+ text:"دریافت فایل ویدیویی درسهای بخش چهارم و پنجم",
+ path:"#"
+ },
+ {
+ id:2,
+ text:"دریافت نرم افزار پخش ویدیو",
+ path:"#"
+ }
+ ]
+ ]
+ },
+ {
+ id:6,
+ id2:6,
+ img:'https://leverageedu.com/blog/wp-content/uploads/2020/04/basic-chemistry.png',
+ name:"آزمون شیمی یازدهم",
+ // price:458.200,
+ masterPrice:200000,
+ price:180000,
+ badge:"10%",
+ date:"2021-10-28T12:00:00.180Z",
+ endDate:"2021-10-28T12:00:00.180Z",
+ level:"پایه 11",
+ type:1,
+ time_type:"thisWeek",
+ filter: "none",
+ count:100,
+ capacity:120,
+ exam_filter:"collegiate",
+ negattiveMode:true,
+ types:"تشریحی و تستی",
+ guideFileId:"#",
+ guide_file_link:"#",
+ text:"از فصل سوم تا پنجم",
+ exam_timer:60,
+ // creator:{
+ // avatar:avatar1,
+ // name:"موسسه فرهنگی مصباح نور"
+ // },
+ descripton:"لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد",
+ time:"21:30",
+ html:[
+ "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد",
+ "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد",
+ "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد"
+ ],
+ // video:video1,
+ // video_cover:video_cover1,
+ files:[
+ [
+ {
+ id:1,
+ text:"دریافت فایل پی دی اف درسهای بخش چهارم و پنجم",
+ path:"#"
+ }
+ ],
+ [
+ {
+ id:1,
+ text:"دریافت فایل ویدیویی درسهای بخش چهارم و پنجم",
+ path:"#"
+ },
+ {
+ id:2,
+ text:"دریافت نرم افزار پخش ویدیو",
+ path:"#"
+ }
+ ]
+ ]
+ },
+ {
+ id:7,
+ id2:7,
+ img:'https://parade.com/wp-content/uploads/2018/10/GordonRamsay_KitchenMaster-FTR.jpg',
+ name:"آزمون آشپزی ملل",
+ // price:458.200,
+ masterPrice:200000,
+ price:"",
+ discount:"",
+ date:"2021-11-05T12:00:00.180Z",
+ endDate:"2021-11-06T12:00:00.180Z",
+ level:"عمومی",
+ type:2,
+ time_type:"thisWeek",
+ filter: "none",
+ count:100,
+ capacity:120,
+ exam_filter:"collegiate",
+ negattiveMode:true,
+ types:"تشریحی و تستی",
+ guideFileId:"#",
+ text:"از فصل سوم تا پنجم",
+ exam_timer:60,
+ // creator:{
+ // avatar:avatar1,
+ // name:"موسسه فرهنگی مصباح نور"
+ // },
+ descripton:"لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد",
+ time:"21:30",
+ html:[
+ "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد",
+ "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد",
+ "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد"
+ ],
+ // video:video1,
+ // video_cover:video_cover1,
+ files:[
+ [
+ {
+ id:1,
+ text:"دریافت فایل پی دی اف درسهای بخش چهارم و پنجم",
+ path:"#"
+ }
+ ],
+ [
+ {
+ id:1,
+ text:"دریافت فایل ویدیویی درسهای بخش چهارم و پنجم",
+ path:"#"
+ },
+ {
+ id:2,
+ text:"دریافت نرم افزار پخش ویدیو",
+ path:"#"
+ }
+ ]
+ ]
+ },
+ {
+ id:8,
+ id2:8,
+ img:'https://img9.irna.ir/old/Image/1397/13970106/82871315/N82871315-72258180.jpg',
+ name:"آزمون گسسته",
+ // price:458.200,
+ masterPrice:200000,
+ price:0,
+ badge:"100%",
+ date:"2021-11-17T12:00:00.180Z",
+ endDate:"2021-11-18T12:00:00.180Z",
+ level:"پایه 10",
+ type:1,
+ time_type:"future",
+ filter: "free",
+ count:100,
+ capacity:120,
+ exam_filter:"collegiate",
+ negattiveMode:true,
+ types:"تشریحی و تستی",
+ guideFileId:"#",
+ text:"از فصل سوم تا پنجم",
+ exam_timer:60,
+ user_num:100,
+ // creator:{
+ // avatar:avatar1,
+ // name:"موسسه فرهنگی مصباح نور"
+ // },
+ descripton:"لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد",
+ time:"21:30",
+ html:[
+ "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد",
+ "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد",
+ "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد"
+ ],
+ // video:video1,
+ // video_cover:video_cover1,
+ files:[
+ [
+ {
+ id:1,
+ text:"دریافت فایل پی دی اف درسهای بخش چهارم و پنجم",
+ path:"#"
+ }
+ ],
+ [
+ {
+ id:1,
+ text:"دریافت فایل ویدیویی درسهای بخش چهارم و پنجم",
+ path:"#"
+ },
+ {
+ id:2,
+ text:"دریافت نرم افزار پخش ویدیو",
+ path:"#"
+ }
+ ]
+ ]
+ }
+ ]
\ No newline at end of file
diff --git a/src/components/exam/carousel-item/index.js b/src/components/exam/carousel-item/index.js
new file mode 100644
index 0000000..1478266
--- /dev/null
+++ b/src/components/exam/carousel-item/index.js
@@ -0,0 +1,22 @@
+import React from "react";
+
+
+const img = 'https://img9.irna.ir/old/Image/1397/13970106/82871315/N82871315-72258180.jpg';
+
+const ExamCarouselItem = ({exam}) => {
+ return(
+
+
+ {
+ exam?.inAction &&
+ }
+
+
+ );
+};
+
+export default ExamCarouselItem;
\ No newline at end of file
diff --git a/src/components/exam/resault/index.css b/src/components/exam/resault/index.css
new file mode 100644
index 0000000..576724e
--- /dev/null
+++ b/src/components/exam/resault/index.css
@@ -0,0 +1,202 @@
+
+
+ .exam-result{
+ width: 100%;
+ height: 450px;
+ direction: rtl;
+ /* box-shadow: 0 0 21px -5px #ADADAD; */
+ border: 1px solid #E0E0E0;
+ padding-top: 15px;
+ position: relative;
+ }
+
+
+ .exam-result-title{
+ width: 90%;
+ margin: 0 auto;
+ margin-top: 5px;
+ font-size: 19px;
+ /* font-family: IRANSansBold; */
+ font-family: IRANSansX-Bold;
+ color: #2E81E8;
+ }
+
+ .exam-result-table{
+ width: 90%;
+ height: 78%;
+ margin: 0 auto;
+ margin-top: 18px;
+ /* overflow-y: scroll; */
+ }
+
+ /* .exam-result-table::-webkit-scrollbar{
+ width: 0px;
+ }
+
+ .exam-result:hover .exam-result-table::-webkit-scrollbar{
+ width: 2px !important;
+ }
+ .exam-result-table::-webkit-scrollbar-thumb{
+ background-color: rgb(129, 128, 128);
+ }
+
+ .exam-result-table::-webkit-scrollbar-track{
+ background-color: rgb(197, 196, 196);
+ } */
+
+ .exam-result-table-titles{
+ width: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ border: 1px solid rgba(224, 224, 224,0.38);
+ }
+ .ertt-item{
+ text-align: center;
+ font-size: 11px;
+ /* font-family: IRANSans; */
+ font-family: IRANSansX-Regular;
+ color: #A2B4CB;
+ }
+
+ .ertt-item:nth-child(1){
+ width: 42%;
+ }
+ .ertt-item:nth-child(2){
+ width: 33%
+ }
+ .ertt-item:nth-child(3){
+ width: 25%;
+ }
+
+ .exam-result-table-data{
+ width: 100%;
+ height: 97%;
+ overflow-y: scroll;
+ }
+
+ .exam-result-table-data::-webkit-scrollbar{
+ width: 0px;
+ }
+
+ .exam-result:hover .exam-result-table-data::-webkit-scrollbar{
+ width: 2px !important;
+ }
+ .exam-result-table-data::-webkit-scrollbar-thumb{
+ background-color: rgb(129, 128, 128);
+ }
+
+ .exam-result-table-data::-webkit-scrollbar-track{
+ background-color: rgb(214, 213, 213);
+ }
+
+ .ertd-item{
+ width: 100%;
+ }
+
+ .ertd-item-name{
+ font-size: 11px;
+ color: #A5B6CD;
+ /* font-family: IRANSans; */
+ font-family: IRANSansX-Regular;
+ margin-top: 7px;
+ }
+
+ .ertdi-item{
+ width: 100%;
+ /* height: 31px; */
+ height: 30px;
+ display: flex;
+ padding: 3px 4px;
+ align-items: center;
+ justify-content: center;
+ margin-top: 7px;
+
+ /* background-color: #F5FFF6; */
+ }
+
+ .ertdi-item-name{
+ width: 42%;
+ height: 100%;
+ /* display: flex; */
+ align-items: center;
+ /* justify-content: center; */
+ /* text-align: center; */
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis !important;
+ /* color: #2FB100; */
+ font-size: 12px;
+ /* font-family: IRANSans; */
+ font-family: IRANSansX-Regular;
+ }
+ .ertdi-item-date{
+ width: 33%;
+ height: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ /* color: #2FB100; */
+ font-size: 12px;
+ /* font-family: IRANSans; */
+ /* font-family: IRANSansX-Regular; */
+ font-family: IRANSansXFaNum-Regular;
+ }
+ .ertdi-item-result{
+ width: 25%;
+ height: 100%;
+ /* display: flex;
+ align-items: center;
+ justify-content: center; */
+ /* color: #2FB100; */
+ text-align: center;
+ font-size: 12px;
+ /* font-family: IRANSans; */
+ font-family: IRANSansX-Regular;
+ }
+
+ .ertd-item-line{
+ width: 100%;
+ height: 1px;
+ background-color: #E0E0E0;
+ margin-top: 15px;
+ opacity: 29%;
+ }
+
+ .exam-result-footer{
+ width: 90%;
+ margin: 0 auto;
+ direction: ltr;
+ margin-top: 15px;
+ }
+
+ .erf-btn{
+ display: flex;
+ width: 100%;
+ align-items: center;
+ font-size: 11px;
+ /* font-family: IRANSans; */
+ font-family: IRANSansX-Regular;
+ color: #ACBCD1;
+ margin-left: -3px;
+ box-sizing: content-box !important;
+ padding: 5px 0;
+ cursor: pointer;
+ /* left: ; */
+ }
+ .erf-btn-arrow-icon{
+ font-size: 18px;
+ }
+
+ .erf-btn:hover{
+ color: #2E81E8;
+ }
+
+ /* --------responsive-setting---------------------------------------------------------- */
+
+
+ @media screen and (max-width: 1508px){
+ .ertdi-item *{
+ font-size: 11px;
+ }
+ }
\ No newline at end of file
diff --git a/src/components/exam/resault/index.js b/src/components/exam/resault/index.js
new file mode 100644
index 0000000..dc74f50
--- /dev/null
+++ b/src/components/exam/resault/index.js
@@ -0,0 +1,163 @@
+import "./index.css";
+import { VscChevronLeft } from "react-icons/vsc";
+
+let ert_data = [
+ {
+ id: 1,
+ name: "نتایج نهایی",
+ line: true,
+ exams: [
+ {
+ id: 1,
+ name: "آزمون راهنمای و رانندگی ",
+ date: "1400/03/29",
+ result: "قبول",
+ isPassed: 1,
+ },
+ {
+ id: 2,
+ name: "آزمون راهنمای و رانندگی ",
+ date: "1400/03/29",
+ result: "قبول",
+ isPassed: 1,
+ },
+ {
+ id: 3,
+ name: "آزمون جامعه شناسی تحلیلی",
+ date: "1400/03/29",
+ result: "رد",
+ isPassed: 2,
+ },
+ {
+ id: 4,
+ name: "آزمون راهنمای و رانندگی ",
+ date: "1400/03/29",
+ result: "قبول",
+ isPassed: 1,
+ },
+ ],
+ },
+ {
+ id: 2,
+ name: "نتایج موقت",
+ line: true,
+ exams: [
+ {
+ id: 1,
+ name: "آزمون راهنمای و رانندگی ",
+ date: "1400/03/29",
+ result: "قبول",
+ isPassed: 1,
+ },
+ {
+ id: 2,
+ name: "آزمون راهنمای و رانندگی ",
+ date: "1400/03/29",
+ result: "قبول",
+ isPassed: 1,
+ },
+ ],
+ },
+ {
+ id: 3,
+ name: "نتایج قرعهکشی",
+ line: false,
+ exams: [
+ {
+ id: 1,
+ name: "آزمون راهنمای و رانندگی ",
+ date: "1400/03/29",
+ result: "در حال برگزاری",
+ isPassed: 3,
+ },
+ {
+ id: 2,
+ name: "آزمون راهنمای و رانندگی ",
+ date: "1400/03/29",
+ result: "در حال برگزاری",
+ isPassed: 3,
+ },
+ ],
+ },
+];
+
+const ExamResults = () => {
+ return (
+
+
نتایج آزمونها
+
+
+
موضوع آزمون
+
تاریخ برگزاری
+
نتیجه
+
+
+ {ert_data.map((item) => (
+
+
{item.name}
+ {item.exams.map((item) => (
+
+
+ {item.name}
+
+
+ {item.date}
+
+
+ {item.result}
+
+
+ ))}
+ {item.line &&
}
+
+ ))}
+
+
+
+
+
+ مشاهده لیست نتایج
+
+
+
+ );
+};
+
+export default ExamResults;
diff --git a/src/components/header/Header.js b/src/components/header/Header.js
index f0ee8de..cd41116 100644
--- a/src/components/header/Header.js
+++ b/src/components/header/Header.js
@@ -54,7 +54,7 @@ const Header = ({
کوروش زراندوز
- صندوقدار
+ پایه ششم
diff --git a/src/components/nav/Nav.js b/src/components/nav/Nav.js
index 4696a1d..624591e 100644
--- a/src/components/nav/Nav.js
+++ b/src/components/nav/Nav.js
@@ -134,7 +134,7 @@ const Nav = ({
{/* ------------ */}
chaneNav(1)}
>
diff --git a/src/view/dashboard/Dashboard.js b/src/view/dashboard/Dashboard.js
index f9b9100..eb74944 100644
--- a/src/view/dashboard/Dashboard.js
+++ b/src/view/dashboard/Dashboard.js
@@ -1,4 +1,6 @@
import { useState } from "react";
+import ExamCarousel from "../../components/exam/Carousel";
+import ExamResults from "../../components/exam/resault";
import UserFullInfo from "../dashboard2/UserFullInfo";
import CashOffice from "./CashOffice";
import LastActivity from "./LastActivity";
@@ -6,6 +8,7 @@ import Monitoring from "./Monitoring";
import People from "./People";
import Register from "./Register";
import Urgent from "./Urgent";
+import SimpleCalendar from '../../components/Calendar'
const Dashboard = ({
@@ -29,22 +32,30 @@ const Dashboard = ({
setSelectId(null);
};
return (
-
-
-
+
+ {/*
+ /> */}
+
+
+
+
+
+
+
-
+
+
+
+
+
-
-
-
- {ActiveUserFullInfo && (
+ {/* {ActiveUserFullInfo && (
- )}
+ )} */}
{register &&
}
diff --git a/src/view/dashboard/LastActivity.js b/src/view/dashboard/LastActivity.js
index e80c039..26227c6 100644
--- a/src/view/dashboard/LastActivity.js
+++ b/src/view/dashboard/LastActivity.js
@@ -7,7 +7,7 @@ const LastActivity = () => {
{
id: 1,
date: "1400/11/11",
- name: "پژمان نوروزی",
+ name: "آزمون آنلاین درس علوم تجربی",
nationalId: "0013578098",
activity: "شارژ حساب",
amount: 100000,
@@ -16,7 +16,7 @@ const LastActivity = () => {
{
id: 2,
date: "1400/11/11",
- name: "ایلیا رئیسی",
+ name: "آزمون آنلاین درس علوم اجتماعی",
nationalId: "0016577044",
activity: "شارژ حساب",
amount: 90000,
@@ -25,7 +25,7 @@ const LastActivity = () => {
{
id: 3,
date: "1400/11/11",
- name: "غزل رحیمی",
+ name: "آزمون آنلاین خیاطی (ریز دوزی)",
nationalId: "0093578123",
activity: "شارژ حساب",
amount: 80000,
@@ -34,7 +34,7 @@ const LastActivity = () => {
{
id: 4,
date: "1400/11/11",
- name: "آریا عظیمی",
+ name: "آزمون حضوری آداب معاشرت",
nationalId: "0061234098",
activity: "شارژ حساب",
amount: 100000,
@@ -43,7 +43,7 @@ const LastActivity = () => {
{
id: 5,
date: "1400/11/10",
- name: "علی رجبی",
+ name: "آزمون آنلاین انضباط دوم دبیرستان",
nationalId: "0213577799",
activity: "شارژ حساب",
amount: 70000,
@@ -52,7 +52,7 @@ const LastActivity = () => {
{
id: 6,
date: "1400/11/10",
- name: "سارا دانش",
+ name: "آزمون حضوری دوره ی چگونه یوتیوبر شویم",
nationalId: "0350077708",
activity: "شارژ حساب",
amount: 70000,
@@ -61,7 +61,7 @@ const LastActivity = () => {
{
id: 7,
date: "1400/11/10",
- name: "امیررضا نیکوسرشت دانشپژوه تستی",
+ name: "آزمون آنلاین fl studio",
nationalId: "0350089964",
activity: "استرداد وجه",
amount: 70000,
@@ -72,89 +72,68 @@ const LastActivity = () => {
-
-
- آخرین فعالیتها
+
+
+ لیست آزمون های من
-
مشاهده بیشتر
-
+ */}
-
-
- ردیف
+
+
+
+ عنوان
-
- تاریخ
+
+ تاریخ ثبت نام
-
- نام و نام خانوادگی
+
+ مبلغ پرداختی
-
- کد ملی
-
-
- نوع فعالیت
-
-
- مبلغ
-
-
- نتیجه
+
+ دریافت قرارداد
+
{data.map((item, index) => (
-
- {index + 1}
-
+
- {item.date}
-
-
{item.name}
- {item.nationalId}
+ {item.date}
- {item.activity}
+ {item.amount} ریال
+
- {item.amount} تومان
-
-
- {item.situation ? "موفق" : "ناموفق"}
+ {
+ item.situation ?
آماده قابل دریافت
:
غیر قابل دریافت
+}
+
))}
diff --git a/src/view/messages/Messages.js b/src/view/messages/Messages.js
index 8ef82b6..1660b68 100644
--- a/src/view/messages/Messages.js
+++ b/src/view/messages/Messages.js
@@ -95,7 +95,7 @@ const Messages=()=>{
@@ -110,7 +110,7 @@ const Messages=()=>{
diff --git a/yarn.lock b/yarn.lock
index f48498d..596da92 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5436,6 +5436,11 @@
"filelist" "^1.0.1"
"minimatch" "^3.0.4"
+"jalaali-js@^1.2.3":
+ "integrity" "sha512-irl0pXL59Xl0Oz6jyOiJed/NxrVeS6fSx6a8atQOH/LsPWPZwBCxwe5XVEIqjnwt69FRxvnCCwQn5dTMxwbazQ=="
+ "resolved" "https://registry.npmjs.org/jalaali-js/-/jalaali-js-1.2.3.tgz"
+ "version" "1.2.3"
+
"jalali-moment@^3.3.10":
"integrity" "sha512-tdSaRs9cjWjOIaWhcsGFZMhZQhfgok5J0TwqFpBIZPudZxxa6yjUPoLCOwuvbAtRpiZn7k/mvazAJh+vEN5suw=="
"resolved" "https://registry.npmjs.org/jalali-moment/-/jalali-moment-3.3.11.tgz"