diff --git a/src/styles/variables.scss b/src/styles/variables.scss
index 1c0f034..15702a3 100644
--- a/src/styles/variables.scss
+++ b/src/styles/variables.scss
@@ -23,6 +23,7 @@
--color-second: #ED675F;
--color-black: #12131B;
+ --color-white: #FFFFFF;
--color-grey: #CBCBCD;
--color-border: #E2E9F0;
--color-button: #1A73E8;
diff --git a/src/ts/components/Achievement/styles/index.module.scss b/src/ts/components/Achievement/styles/index.module.scss
index 69b132d..dced402 100644
--- a/src/ts/components/Achievement/styles/index.module.scss
+++ b/src/ts/components/Achievement/styles/index.module.scss
@@ -16,7 +16,7 @@
border: 1px solid var(--color-border);
border-radius: 6px;
- background-color: #FFFFFF;
+ background-color: var(--color-white);
}
.achievement:last-child {
@@ -50,7 +50,7 @@
border-radius: 40px;
letter-spacing: 2px;
- color: white;
+ color: var(--color-white);
background-color: var(--color-border);
border-color: var(--color-border);
}
@@ -60,7 +60,7 @@
width: 56px;
height: 56px;
margin: 4px auto;
- fill: #FFFFFF;
+ fill: var(--color-white);
}
.achievement_title,
diff --git a/src/ts/components/Banner/index.module.scss b/src/ts/components/Banner/index.module.scss
index 012ddc2..f7ae70b 100644
--- a/src/ts/components/Banner/index.module.scss
+++ b/src/ts/components/Banner/index.module.scss
@@ -18,7 +18,7 @@
text-decoration: none;
border-radius: var(--border-radius-s);
- color: #FFFFFF;
+ color: var(--color-white);
background-color: #A7B6FE;
//background: linear-gradient(135deg, rgba(64,117,252,1) 0%, rgba(172,179,246,1) 100%);
diff --git a/src/ts/components/CardWithIcon/index.module.scss b/src/ts/components/CardWithIcon/index.module.scss
index 9b2676b..77a4b8c 100644
--- a/src/ts/components/CardWithIcon/index.module.scss
+++ b/src/ts/components/CardWithIcon/index.module.scss
@@ -14,7 +14,7 @@
border-radius: 8px;
border: 1px solid var(--color-border);
- background-color: #FFFFFF;
+ background-color: var(--color-white);
background-repeat: repeat;
background-size: auto 100%;
diff --git a/src/ts/components/Cards/styles/index.module.scss b/src/ts/components/Cards/styles/index.module.scss
index f42d7c7..01f6bd9 100644
--- a/src/ts/components/Cards/styles/index.module.scss
+++ b/src/ts/components/Cards/styles/index.module.scss
@@ -10,7 +10,7 @@
page-break-inside: avoid;
box-sizing: border-box;
vertical-align: top;
- background-color: white;
+ background-color: var(--color-white);
&_wrapper {
width: calc(100% + 24px);
diff --git a/src/ts/components/CityBuilder/style/banner.module.scss b/src/ts/components/CityBuilder/style/banner.module.scss
index b7ec4d9..7edc6ea 100644
--- a/src/ts/components/CityBuilder/style/banner.module.scss
+++ b/src/ts/components/CityBuilder/style/banner.module.scss
@@ -31,6 +31,6 @@
&_text {
margin: var(--space-s) auto;
- color: white;
+ color: var(--color-white);
}
}
diff --git a/src/ts/components/DataLoader/styles/scroll.module.scss b/src/ts/components/DataLoader/styles/scroll.module.scss
index fe79729..6f35feb 100644
--- a/src/ts/components/DataLoader/styles/scroll.module.scss
+++ b/src/ts/components/DataLoader/styles/scroll.module.scss
@@ -4,7 +4,7 @@
.infinite_scroll_border_bottom {
position: sticky;
z-index: 3;
- background-color: white;
+ background-color: var(--color-white);
}
.infinite_scroll_border_top {
diff --git a/src/ts/components/DropZone/index.module.scss b/src/ts/components/DropZone/index.module.scss
index 2339e7d..7d521d3 100644
--- a/src/ts/components/DropZone/index.module.scss
+++ b/src/ts/components/DropZone/index.module.scss
@@ -11,7 +11,7 @@
width: 100vw;
height: 100vh;
z-index: 3;
- background-color: white;
+ background-color: var(--color-white);
&_icon {
display: block;
diff --git a/src/ts/components/Extension/styles/index.module.scss b/src/ts/components/Extension/styles/index.module.scss
index c40d975..0a2837d 100644
--- a/src/ts/components/Extension/styles/index.module.scss
+++ b/src/ts/components/Extension/styles/index.module.scss
@@ -7,7 +7,7 @@
padding: 24px;
vertical-align: top;
border-radius: var(--border-radius-l);
- background-color: white;
+ background-color: var(--color-white);
&_icon {
display: block;
diff --git a/src/ts/components/GameBanner/index.module.scss b/src/ts/components/GameBanner/index.module.scss
index 06c2d81..6ce56ba 100644
--- a/src/ts/components/GameBanner/index.module.scss
+++ b/src/ts/components/GameBanner/index.module.scss
@@ -28,6 +28,6 @@
&_text {
margin: var(--space-s) auto;
- color: white;
+ color: var(--color-white);
}
}
diff --git a/src/ts/components/GetList/styles/index.module.scss b/src/ts/components/GetList/styles/index.module.scss
index d301a42..dad58a9 100644
--- a/src/ts/components/GetList/styles/index.module.scss
+++ b/src/ts/components/GetList/styles/index.module.scss
@@ -24,7 +24,7 @@
border: 1px solid var(--color-border);
border-radius: var(--border-radius-s);
- background-color: white;
+ background-color: var(--color-white);
}
&_title {
@@ -40,7 +40,7 @@
border-radius: var(--border-radius-s);
border: 1px solid var(--color-border);
- background-color: white;
+ background-color: var(--color-white);
&:before {
position: absolute;
@@ -57,7 +57,7 @@
box-sizing: border-box;
transform: rotateZ(45deg);
- background-color: white;
+ background-color: var(--color-white);
border-right: 1px solid var(--color-border);
border-bottom: 1px solid var(--color-border);
}
diff --git a/src/ts/components/HoursChart/index.module.scss b/src/ts/components/HoursChart/index.module.scss
index 3a8f55e..f4bc94a 100644
--- a/src/ts/components/HoursChart/index.module.scss
+++ b/src/ts/components/HoursChart/index.module.scss
@@ -59,7 +59,7 @@
}
&_hour {
- color: white;
+ color: var(--color-white);
border-radius: 6px;
border: 1px solid #FFFFFF;
background-color: var(--color-first);
diff --git a/src/ts/components/HoursChart/styles/legend.module.scss b/src/ts/components/HoursChart/styles/legend.module.scss
index 8d2957c..f8d6213 100644
--- a/src/ts/components/HoursChart/styles/legend.module.scss
+++ b/src/ts/components/HoursChart/styles/legend.module.scss
@@ -42,7 +42,7 @@
&_count {
color: var(--color-black);
border: 1px solid var(--color-grey);
- background-color: #FFFFFF;
+ background-color: var(--color-white);
}
&_title {
diff --git a/src/ts/components/LineChart/styles/index.module.scss b/src/ts/components/LineChart/styles/index.module.scss
index f25e3d7..32f2cee 100644
--- a/src/ts/components/LineChart/styles/index.module.scss
+++ b/src/ts/components/LineChart/styles/index.module.scss
@@ -26,7 +26,7 @@
overflow: hidden;
line-height: var(--line_chart-height);
text-align: left;
- color: #FFFFFF;
+ color: var(--color-white);
background-color: #D0D1D2;
-webkit-print-color-adjust: exact;
}
diff --git a/src/ts/components/Locker/index.module.scss b/src/ts/components/Locker/index.module.scss
index 1c9e8b5..e924865 100644
--- a/src/ts/components/Locker/index.module.scss
+++ b/src/ts/components/Locker/index.module.scss
@@ -21,7 +21,7 @@
}
&_center {
- fill: white;
+ fill: var(--color-white);
stroke: none;
stroke-width: 0;
}
diff --git a/src/ts/components/ModalWindow/styles/index.module.scss b/src/ts/components/ModalWindow/styles/index.module.scss
index ea2b950..f1c85b5 100644
--- a/src/ts/components/ModalWindow/styles/index.module.scss
+++ b/src/ts/components/ModalWindow/styles/index.module.scss
@@ -6,7 +6,7 @@
margin: 0 auto;
box-sizing: border-box;
box-shadow: 0 0 5px gray;
- background-color: #FFFFFF;
+ background-color: var(--color-white);
border-radius: 8px;
}
@@ -111,16 +111,16 @@
@keyframes modal_window_halo {
from {
transform: rotateZ(0deg);
- opacity: 0;
+ opacity: 0.4;
}
11% {
- opacity: 0.4;
+ opacity: 0.7;
}
89% {
- opacity: 0.4;
+ opacity: 0.7;
}
to {
transform: rotateZ(360deg);
- opacity: 0;
+ opacity: 0.4;
}
}
diff --git a/src/ts/components/Notifications/components/Message.tsx b/src/ts/components/Notifications/components/Message.tsx
index 9f723ed..0ca27ef 100644
--- a/src/ts/components/Notifications/components/Message.tsx
+++ b/src/ts/components/Notifications/components/Message.tsx
@@ -15,8 +15,19 @@ function Card({ message }: ICardProps) {
info: style.notifications_item_info,
}[message.type || 'success'] || style.notifications_item_info;
+ const icon = {
+ error: './assets/notifications/alert.svg',
+ warning: './assets/notifications/warning.svg',
+ success: './assets/notifications/info.svg',
+ info: './assets/notifications/info.svg',
+ }[message.type || 'info'] || './assets/notifications/info.svg';
+
return (
+
{message.title && (
{message.title}
diff --git a/src/ts/components/Notifications/styles/index.module.scss b/src/ts/components/Notifications/styles/index.module.scss
index bafc992..2db0744 100644
--- a/src/ts/components/Notifications/styles/index.module.scss
+++ b/src/ts/components/Notifications/styles/index.module.scss
@@ -8,30 +8,41 @@
display: inline-block;
&_item {
+ position: relative;
+
display: block;
width: 300px;
- padding: 24px;
+ padding: var(--space-xxl) var(--space-xxl) var(--space-xxl) 56px;
margin: 0 12px 12px;
box-sizing: border-box;
box-shadow: 2px 2px 3px var(--color-grey);
- border: 1px solid var(--color-border);
- border-left: 8px solid var(--color-border);
+ border: none;
border-radius: var(--border-radius-s);
- background-color: white;
+ background-color: var(--color-white);
animation: notification_item 3s linear 0.5s forwards;
+ &_icon {
+ position: absolute;
+ top: 16px;
+ left: 12px;
+
+ display: block;
+ width: 32px;
+ height: 32px;
+ }
+
&_error {
- border-color: var(--color-12);
+ background-color: var(--color-12);
}
&_warning {
- border-color: var(--color-32);
+ background-color: var(--color-32);
}
&_success {
- border-color: var(--color-13);
+ background-color: #35D081;
}
&_info {
@@ -44,7 +55,7 @@
font-weight: 100;
padding: 0;
text-align: left;
- color: var(--color-black);
+ color: var(--color-white);
animation: notification_title 3s linear 0.5s forwards;
}
@@ -62,12 +73,12 @@
80% {
overflow: hidden;
height: auto;
- padding: 24px;
+ padding: var(--space-xxl) var(--space-xxl) var(--space-xxl) 56px;
opacity: 1;
}
to {
height: 0;
- padding: 0 24px;
+ padding: 0 var(--space-xxl) 0 64px;
opacity: 0;
}
}
diff --git a/src/ts/components/Page/index.module.scss b/src/ts/components/Page/index.module.scss
index 52efff0..b6b7c76 100644
--- a/src/ts/components/Page/index.module.scss
+++ b/src/ts/components/Page/index.module.scss
@@ -20,7 +20,7 @@
break-inside: auto;
border-radius: 8px;
border: 1px solid var(--color-border);
- background-color: #FFFFFF;
+ background-color: var(--color-white);
}
&_icons {
@@ -56,7 +56,7 @@
vertical-align: top;
border-radius: 8px;
border: 1px solid var(--color-border);
- background-color: #FFFFFF;
+ background-color: var(--color-white);
}
.main_wrapper_item + .main_wrapper_item {
diff --git a/src/ts/components/PieChart/components/Legend.tsx b/src/ts/components/PieChart/components/Legend.tsx
new file mode 100644
index 0000000..a3e1d55
--- /dev/null
+++ b/src/ts/components/PieChart/components/Legend.tsx
@@ -0,0 +1,46 @@
+import React from 'react';
+import { useTranslation } from 'react-i18next';
+
+import { IOptions, ISubLine } from 'ts/components/LineChart/interfaces';
+
+import style from '../index.module.scss';
+
+interface ILegendProps {
+ parts: ISubLine[];
+ options: IOptions;
+}
+
+function Legend({
+ parts,
+ options,
+}: ILegendProps): React.ReactElement | null {
+ const { t } = useTranslation();
+
+ const lines = parts.map((item: ISubLine) => {
+ return (
+
+
+
+ {`${item.width}%`}
+
+
+ {t(item.title)}
+
+
+ );
+ });
+
+ return (
+
+ {lines}
+
+ );
+}
+
+export default Legend;
diff --git a/src/ts/components/PieChart/index.module.scss b/src/ts/components/PieChart/index.module.scss
new file mode 100644
index 0000000..f8bd64d
--- /dev/null
+++ b/src/ts/components/PieChart/index.module.scss
@@ -0,0 +1,64 @@
+@import 'src/styles/variables';
+
+.pie_chart {
+ display: block;
+ margin: 0 auto var(--space-xxl);
+ padding: var(--space-xxl);
+
+ border: 1px solid var(--color-border);
+ border-radius: var(--border-radius-m);
+ background-color: var(--color-white);
+
+ &_data {
+ display: block;
+ white-space: nowrap;
+ }
+
+ &_icon,
+ &_legend {
+ display: inline-block;
+ width: 50%;
+ height: 100%;
+ vertical-align: middle;
+ }
+
+ &_icon {
+ width: 160px;
+ }
+
+ &_legend {
+ min-width: 160px;
+ padding-left: var(--space-xxl);
+ }
+
+ &_line {
+ position: relative;
+ display: block;
+ padding: 0 0 var(--space-xxs) 26px;
+ }
+
+ &_color {
+ position: absolute;
+ top: 4px;
+ left: 0;
+
+ display: inline-block;
+ width: var(--space-m);
+ height: var(--space-m);
+
+ background-color: #D0D1D2;
+ }
+
+ &_percent,
+ &_text {
+ display: inline-block;
+ line-height: 1.3;
+ white-space: normal;
+ text-decoration: none;
+ color: var(--color-black);
+ }
+
+ &_percent {
+ width: 40px;
+ }
+}
diff --git a/src/ts/components/PieChart/index.tsx b/src/ts/components/PieChart/index.tsx
new file mode 100644
index 0000000..3e131ef
--- /dev/null
+++ b/src/ts/components/PieChart/index.tsx
@@ -0,0 +1,68 @@
+import React from 'react';
+
+import IHashMap from 'ts/interfaces/HashMap';
+import { IOptions } from 'ts/components/LineChart/interfaces';
+import getSubLines from 'ts/components/LineChart/helpers/getSubLines';
+import PieSVG from 'ts/components/PieSVG';
+import Title from 'ts/components/Title';
+
+import Legend from './components/Legend';
+import style from './index.module.scss';
+
+interface IPieChartProps {
+ title?: string;
+ options: IOptions;
+ value?: number;
+ details?: IHashMap
;
+ center?: number;
+ className?: string;
+}
+
+function getDefaultDetails(value: number, max: number) {
+ return {
+ a: value,
+ b: max - value,
+ };
+}
+
+function PieChart({
+ title,
+ options,
+ value,
+ details,
+ center,
+ className,
+}: IPieChartProps): React.ReactElement | null {
+ if (value === 0) return null;
+
+ const formattedDetails = details || getDefaultDetails(value || 100, options.max || 100);
+ const parts = getSubLines(formattedDetails, options);
+
+ return (
+
+ );
+}
+
+PieChart.defaultProps = {
+ value: undefined,
+ details: undefined,
+ className: '',
+ title: '',
+};
+
+export default PieChart;
diff --git a/src/ts/components/PieSVG/helpers/index.ts b/src/ts/components/PieSVG/helpers/index.ts
new file mode 100644
index 0000000..9d1f7ed
--- /dev/null
+++ b/src/ts/components/PieSVG/helpers/index.ts
@@ -0,0 +1,29 @@
+function polarToCartesian(x: number, y: number, r: number, degrees: number) {
+ const radians = degrees * Math.PI / 180;
+ return [
+ x + (r * Math.cos(radians)),
+ y + (r * Math.sin(radians)),
+ ];
+}
+
+export function getSegmentPath(
+ x: number,
+ y: number,
+ r0: number,
+ r1: number,
+ d0: number,
+ d1: number,
+) {
+ const arc = Math.abs(d0 - d1) > 180 ? 1 : 0;
+ const point = (radius: number, degree: number) =>
+ polarToCartesian(x, y, radius, degree)
+ .map(n => n.toPrecision(5))
+ .join(',');
+ return [
+ `M${point(r0, d0)}`,
+ `A${r0},${r0},0,${arc},1,${point(r0, d1)}`,
+ `L${point(r1, d1)}`,
+ `A${r1},${r1},0,${arc},0,${point(r1, d0)}`,
+ 'Z',
+ ].join('');
+}
diff --git a/src/ts/components/PieSVG/index.module.scss b/src/ts/components/PieSVG/index.module.scss
new file mode 100644
index 0000000..0e5955e
--- /dev/null
+++ b/src/ts/components/PieSVG/index.module.scss
@@ -0,0 +1,12 @@
+@import 'src/styles/variables';
+
+.pie_svg {
+ display: inline-block;
+ height: 100%;
+
+ &_sector {
+ fill: #D0D1D2;
+ stroke: none;
+ stroke-width: 0;
+ }
+}
diff --git a/src/ts/components/PieSVG/index.tsx b/src/ts/components/PieSVG/index.tsx
new file mode 100644
index 0000000..54c678f
--- /dev/null
+++ b/src/ts/components/PieSVG/index.tsx
@@ -0,0 +1,60 @@
+import React from 'react';
+
+import { IOptions, ISubLine } from 'ts/components/LineChart/interfaces';
+import { getSegmentPath } from './helpers';
+import style from './index.module.scss';
+
+interface IPieSVGProps {
+ options: IOptions;
+ parts: ISubLine[];
+ center?: number;
+}
+
+const ROTATE = -90;
+
+function PieSVG({
+ options,
+ parts,
+ center,
+}: IPieSVGProps): React.ReactElement | null {
+ const centerRadius = 49 * ((center || 72) / 100);
+
+ let prev = 0;
+ const paths = parts.map((item: ISubLine) => {
+ const fill = options.color.get(item.title).first;
+ const angle = 360 * item.width / 100;
+ const next = Math.min(prev + angle, 360);
+ const d = getSegmentPath(50, 50, centerRadius, 50, prev + ROTATE, next + ROTATE);
+ prev += angle;
+
+ return (
+
+
+ {`${item.title} ${item.description || ''}`}
+
+
+ );
+ });
+
+ return (
+
+ );
+}
+
+PieSVG.defaultProps = {
+ className: '',
+};
+
+export default PieSVG;
diff --git a/src/ts/components/Quize/components/Answer.tsx b/src/ts/components/Quize/components/Answer.tsx
index ac88900..5a25a9a 100644
--- a/src/ts/components/Quize/components/Answer.tsx
+++ b/src/ts/components/Quize/components/Answer.tsx
@@ -3,11 +3,6 @@ import React from 'react';
import IAnswer from '../interfaces/Answer';
import style from '../styles/answer.module.scss';
-const IS_WRAPPER_MODE = {
- error: true,
- small: true,
-};
-
interface IAnswerProps {
answer: IAnswer;
mode: string;
@@ -19,28 +14,27 @@ function Answer({
mode,
onClick,
}: IAnswerProps): React.ReactElement | null {
- const className = [style.quize_answer];
- if (mode === 'selected') className.push(style.quize_answer_selected);
- if (mode === 'correct') className.push(style.quize_answer_correct);
- if (mode === 'error') className.push(style.quize_answer_error);
- if (mode === 'small') className.push(style.quize_answer_small);
+ const className = [style.quize_answer_wrapper];
+ const textClasName = [style.quize_answer_text];
- const wrapperClass = [style.quize_answer_wrapper];
- if (IS_WRAPPER_MODE[mode]) wrapperClass.push(style.quize_answer_wrapper_small);
+ if (mode === 'small' || mode === 'error') className.push(style.quize_answer_wrapper_small);
+ if (mode === 'selected') textClasName.push(style.quize_answer_text_selected);
+ if (mode === 'correct') textClasName.push(style.quize_answer_text_correct);
+ if (mode === 'error') textClasName.push(style.quize_answer_text_error);
return (
-
+
diff --git a/src/ts/components/Quize/components/Question.tsx b/src/ts/components/Quize/components/Question.tsx
index 09dcad6..6a161a6 100644
--- a/src/ts/components/Quize/components/Question.tsx
+++ b/src/ts/components/Quize/components/Question.tsx
@@ -4,7 +4,6 @@ import UiKitButton from 'ts/components/UiKit/components/Button';
import IQuestion from '../interfaces/Question';
import IAnswer from '../interfaces/Answer';
-import Progress from './Progress';
import Answer from './Answer';
import stylePage from '../styles/question.module.scss';
@@ -20,13 +19,11 @@ function getModes(answers: IAnswer[], selected: IAnswer | null) {
interface IQuestionProps {
question: IQuestion;
- progress: number;
onClick: Function;
}
function Question({
question,
- progress,
onClick,
}: IQuestionProps): React.ReactElement | null {
const [selected, setSelected] = useState
(null);
@@ -71,7 +68,6 @@ function Question({
return (
-