Various improvements
This commit is contained in:
parent
c94edf655f
commit
7c771dd971
20 changed files with 243 additions and 183 deletions
|
|
@ -40,7 +40,7 @@ function SessionList(props: Props) {
|
|||
<div className="flex items-center justify-center flex-col">
|
||||
<AnimatedSVG name={ICONS.NO_LIVE_SESSIONS} size={60} />
|
||||
<div className="mt-4" />
|
||||
<div className="text-center">No live sessions found</div>
|
||||
<div className="text-center text-lg font-medium">No live sessions found</div>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import styles from './title.module.css';
|
|||
|
||||
const Title = ({ title, sub }) => (
|
||||
<div className={ styles.title } >
|
||||
<h4>{ title }</h4>
|
||||
<h4 className='cap-first'>{ title }</h4>
|
||||
<span>{ sub }</span>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ function AddCardSelectionModal(props: Props) {
|
|||
<Col span={12}>
|
||||
<div className="flex flex-col items-center justify-center hover:bg-indigo-50 border rounded-lg shadow-sm cursor-pointer gap-3" style={{height: '80px'}} onClick={() => onClick(false)}>
|
||||
<Plus style={{fontSize: '24px', color: '#394EFF'}}/>
|
||||
<Typography.Text strong>Create New Card</Typography.Text>
|
||||
<Typography.Text strong>Create New</Typography.Text>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import React from 'react';
|
||||
import { Icon } from 'UI';
|
||||
import { Tag } from 'antd';
|
||||
import { checkForRecent } from 'App/date';
|
||||
import { withSiteId, alertEdit } from 'App/routes';
|
||||
import { numberWithCommas } from 'App/utils';
|
||||
|
|
@ -116,8 +117,10 @@ function AlertListItem(props: Props) {
|
|||
</div>
|
||||
</div>
|
||||
<div className="col-span-2">
|
||||
<div className="flex items-center uppercase">
|
||||
<span>{alert.detectionMethod}</span>
|
||||
<div className="flex items-center">
|
||||
<Tag className='rounded-full bg-indigo-50 cap-first text-base' bordered={false}>
|
||||
{alert.detectionMethod}
|
||||
</Tag>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-span-2 text-right">
|
||||
|
|
@ -129,38 +132,38 @@ function AlertListItem(props: Props) {
|
|||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="color-gray-medium px-2 pb-2">
|
||||
<div className="text-sm w-2/3 px-2 pb-2 ">
|
||||
{'When the '}
|
||||
<span className="font-semibold" style={{ fontFamily: 'Menlo, Monaco, Consolas' }}>
|
||||
<span className="font-medium font-mono" >
|
||||
{alert.detectionMethod}
|
||||
</span>
|
||||
{' of '}
|
||||
<span className="font-semibold" style={{ fontFamily: 'Menlo, Monaco, Consolas' }}>
|
||||
<span className="font-medium font-mono" >
|
||||
{triggerOptions ? formTriggerName() : alert.seriesName}
|
||||
</span>
|
||||
{' is '}
|
||||
<span className="font-semibold" style={{ fontFamily: 'Menlo, Monaco, Consolas' }}>
|
||||
<span className="font-medium font-mono" >
|
||||
{alert.query.operator}
|
||||
{numberWithCommas(alert.query.right)}
|
||||
{alert.change === 'percent' ? '%' : alert.metric?.unit}
|
||||
</span>
|
||||
{' over the past '}
|
||||
<span className="font-semibold" style={{ fontFamily: 'Menlo, Monaco, Consolas' }}>
|
||||
<span className="font-medium font-mono">
|
||||
{getThreshold(alert.currentPeriod)}
|
||||
</span>
|
||||
{alert.detectionMethod === 'change' ? (
|
||||
<>
|
||||
{' compared to the previous '}
|
||||
<span className="font-semibold" style={{ fontFamily: 'Menlo, Monaco, Consolas ' }}>
|
||||
<span className="font-medium font-mono" >
|
||||
{getThreshold(alert.previousPeriod)}
|
||||
</span>
|
||||
</>
|
||||
) : null}
|
||||
{', notify me on '}
|
||||
{', notify via '}
|
||||
<span>{getNotifyChannel(alert, webhooks)}</span>.
|
||||
</div>
|
||||
{alert.description ? (
|
||||
<div className="color-gray-medium px-2 pb-2">{alert.description}</div>
|
||||
<div className="px-2 pb-2">{alert.description}</div>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ function AlertsList({ siteId }: Props) {
|
|||
title={
|
||||
<div className='flex flex-col items-center justify-center'>
|
||||
<AnimatedSVG name={ICONS.NO_ALERTS} size={60} />
|
||||
<div className='text-center mt-4'>
|
||||
<div className='text-center mt-4 text-lg font-medium'>
|
||||
{alertsSearch !== '' ? 'No matching results' : 'You haven\'t created any alerts yet'}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -59,7 +59,7 @@ function AlertsList({ siteId }: Props) {
|
|||
</div>
|
||||
|
||||
<div className='w-full flex items-center justify-between pt-4 px-6'>
|
||||
<div className='text-disabled-text'>
|
||||
<div className=''>
|
||||
Showing <span className='font-semibold'>{Math.min(list.length, pageSize)}</span> out of{' '}
|
||||
<span className='font-semibold'>{list.length}</span> Alerts
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
import React from 'react';
|
||||
import { useStore } from 'App/mstore';
|
||||
import WidgetWrapper from '../WidgetWrapper';
|
||||
import { NoContent, Loader, Icon } from 'UI';
|
||||
import { useObserver } from 'mobx-react-lite';
|
||||
import Widget from 'App/mstore/types/widget';
|
||||
import MetricTypeList from '../MetricTypeList';
|
||||
import WidgetWrapperNew from 'Components/Dashboard/components/WidgetWrapper/WidgetWrapperNew';
|
||||
import { Empty } from 'antd';
|
||||
import { NoContent, Loader } from 'UI';
|
||||
import { useObserver } from 'mobx-react-lite';
|
||||
import AnimatedSVG, { ICONS } from 'Shared/AnimatedSVG/AnimatedSVG';
|
||||
|
||||
interface Props {
|
||||
siteId: string;
|
||||
|
|
@ -23,48 +21,50 @@ function DashboardWidgetGrid(props: Props) {
|
|||
const list = useObserver(() => dashboard?.widgets);
|
||||
|
||||
return useObserver(() => (
|
||||
// @ts-ignore
|
||||
list?.length === 0 ? <Empty description="No cards in this dashboard" /> : (
|
||||
<Loader loading={loading}>
|
||||
<NoContent
|
||||
show={list?.length === 0}
|
||||
icon="no-metrics-chart"
|
||||
title={
|
||||
<div className="bg-white rounded-lg">
|
||||
<div className="border-b p-5">
|
||||
<div className="text-2xl font-normal">
|
||||
There are no cards in this dashboard
|
||||
<Loader loading={loading}>
|
||||
{
|
||||
list?.length === 0 ? (
|
||||
<div className="bg-white rounded-lg shadow-sm p-5">
|
||||
<NoContent
|
||||
show={true}
|
||||
icon="no-metrics-chart"
|
||||
title={
|
||||
<div className="text-center">
|
||||
<div className='mb-4'>
|
||||
<AnimatedSVG name={ICONS.NO_RESULTS} size={60} />
|
||||
</div>
|
||||
<div className="text-xl font-medium mb-2">
|
||||
There are no cards in this dashboard
|
||||
</div>
|
||||
<div className="text-base font-normal">
|
||||
Create a card by clicking the "Add Card" button to visualize insights here.
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-base font-normal">
|
||||
Create a card from any of the below types or pick an existing one from your library.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div className="grid gap-4 grid-cols-4 items-start pb-10" id={props.id}>
|
||||
{
|
||||
list?.map((item: any, index: any) => (
|
||||
<React.Fragment key={item.widgetId}>
|
||||
<WidgetWrapperNew
|
||||
index={index}
|
||||
widget={item}
|
||||
moveListItem={(dragIndex: any, hoverIndex: any) =>
|
||||
dashboard?.swapWidgetPosition(dragIndex, hoverIndex)
|
||||
}
|
||||
dashboardId={dashboardId}
|
||||
siteId={siteId}
|
||||
grid="other"
|
||||
showMenu={true}
|
||||
isSaved={true}
|
||||
/>
|
||||
</React.Fragment>
|
||||
))
|
||||
}
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</NoContent>
|
||||
</Loader>
|
||||
)
|
||||
) : (
|
||||
<div className="grid gap-4 grid-cols-4 items-start pb-10" id={props.id}>
|
||||
{list?.map((item: any, index: any) => (
|
||||
<React.Fragment key={item.widgetId}>
|
||||
<WidgetWrapperNew
|
||||
index={index}
|
||||
widget={item}
|
||||
moveListItem={(dragIndex: any, hoverIndex: any) =>
|
||||
dashboard?.swapWidgetPosition(dragIndex, hoverIndex)
|
||||
}
|
||||
dashboardId={dashboardId}
|
||||
siteId={siteId}
|
||||
grid="other"
|
||||
showMenu={true}
|
||||
isSaved={true}
|
||||
/>
|
||||
</React.Fragment>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</Loader>
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ function MetricsList({
|
|||
title={
|
||||
<div className="flex flex-col items-center justify-center">
|
||||
<AnimatedSVG name={ICONS.NO_CARDS} size={60} />
|
||||
<div className="text-center mt-4">
|
||||
<div className="text-center mt-4 text-lg font-medium">
|
||||
{metricsSearch !== '' ? 'No matching results' : 'You haven\'t created any cards yet'}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ function FFlagsList({ siteId }: { siteId: string }) {
|
|||
title={
|
||||
<div className={'flex flex-col items-center justify-center'}>
|
||||
<AnimatedSVG name={ICONS.NO_FFLAGS} size={60} />
|
||||
<div className="text-center text-gray-600 mt-4">
|
||||
<div className="text-center mt-4 text-lg font-medium">
|
||||
{featureFlagsStore.sort.query === ''
|
||||
? "You haven't created any feature flags yet"
|
||||
: 'No matching results'}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { Button } from 'antd';
|
||||
import { Button, Tooltip } from 'antd';
|
||||
import { toggleZoom } from 'Duck/components/player';
|
||||
import { PlayerContext } from 'Components/Session/playerContext';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
|
|
@ -33,9 +33,11 @@ function TimelineZoomButton({ enabled, toggleZoom }: Props) {
|
|||
}
|
||||
}, [])
|
||||
return (
|
||||
<Tooltip title="Select a portion of the timeline to view the x-ray and activity for that specific selction." placement='top'>
|
||||
<Button onClick={onClickHandler} size={'small'} className={'flex items-center font-semibold'}>
|
||||
Timeline Zoom {enabled ? 'On' : 'Off'}
|
||||
Focus Mode: {enabled ? 'On' : 'Off'}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ function ParticipantOverviewItem({
|
|||
addedNum?: string;
|
||||
}) {
|
||||
return (
|
||||
<div className={'rounded border p-2 flex-1'}>
|
||||
<div className={'rounded-lg border p-2 flex-1'}>
|
||||
<div className={'flex items-center gap-2 mb-2'}>{titleRow}</div>
|
||||
<div className={'flex items-baseline gap-2'}>
|
||||
{firstNum ? <Typography.Title level={4}>{firstNum}</Typography.Title> : null}
|
||||
|
|
|
|||
|
|
@ -1,54 +1,78 @@
|
|||
import { useStore } from 'App/mstore';
|
||||
import React from 'react';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { Typography, Switch, Button, Space, Tooltip } from 'antd';
|
||||
import { Typography, Switch, Button, Space, Tooltip, Alert } from 'antd';
|
||||
import { ExportOutlined } from '@ant-design/icons';
|
||||
|
||||
const SidePanel = observer(({ onSave, onPreview, taskLen, isStartingPointValid }: any) => {
|
||||
interface SidePanelProps {
|
||||
onSave: () => void;
|
||||
onPreview: () => void;
|
||||
taskLen: number;
|
||||
isStartingPointValid: boolean;
|
||||
}
|
||||
|
||||
const SidePanel: React.FC<SidePanelProps> = ({ onSave, onPreview, taskLen, isStartingPointValid }) => {
|
||||
const { uxtestingStore } = useStore();
|
||||
|
||||
const canPublishOrPreview = taskLen > 0 && isStartingPointValid;
|
||||
|
||||
return (
|
||||
<div className={'flex flex-col gap-2 col-span-1'}>
|
||||
<div className={'p-4 bg-white rounded border flex flex-col gap-2'}>
|
||||
<div className={'p-4 bg-white rounded-lg shadow-sm flex flex-col gap-2'}>
|
||||
<Typography.Text strong>Participant Requirements</Typography.Text>
|
||||
<div className={'flex justify-between'}>
|
||||
<Typography.Text>Mic</Typography.Text>
|
||||
<Switch
|
||||
checked={uxtestingStore.instance!.requireMic}
|
||||
defaultChecked={uxtestingStore.instance!.requireMic}
|
||||
onChange={(checked) => uxtestingStore.instance!.setProperty('requireMic', checked)}
|
||||
checkedChildren="Yes"
|
||||
unCheckedChildren="No"
|
||||
/>
|
||||
</div>
|
||||
<div className={'flex justify-between'}>
|
||||
<Typography.Text>Camera</Typography.Text>
|
||||
<Switch
|
||||
checked={uxtestingStore.instance!.requireCamera}
|
||||
defaultChecked={uxtestingStore.instance!.requireCamera}
|
||||
onChange={(checked) => uxtestingStore.instance!.setProperty('requireCamera', checked)}
|
||||
checkedChildren="Yes"
|
||||
unCheckedChildren="No"
|
||||
/>
|
||||
</div>
|
||||
<div className={'text-disabled-text text-sm'}>
|
||||
Enable camera and mic options to watch participants' reactions and hear their comments for better insights into their experience.
|
||||
<div className={'text-sm py-2'}>
|
||||
Enable the camera and mic to observe participants' reactions and hear their comments for better insights.
|
||||
</div>
|
||||
{uxtestingStore.instance && (
|
||||
<>
|
||||
<div className={'flex justify-between'}>
|
||||
<Typography.Text>Mic</Typography.Text>
|
||||
<Switch
|
||||
checked={uxtestingStore.instance.requireMic}
|
||||
onChange={(checked) => uxtestingStore.instance?.setProperty('requireMic', checked)}
|
||||
checkedChildren="Required"
|
||||
unCheckedChildren="Not Required"
|
||||
/>
|
||||
</div>
|
||||
<div className={'flex justify-between'}>
|
||||
<Typography.Text>Camera</Typography.Text>
|
||||
<Switch
|
||||
checked={uxtestingStore.instance.requireCamera}
|
||||
onChange={(checked) => uxtestingStore.instance?.setProperty('requireCamera', checked)}
|
||||
checkedChildren="Required"
|
||||
unCheckedChildren="Not Required"
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<Tooltip title={taskLen === 0 ? 'Define the starting point and the tasks to proceed.' : ''}>
|
||||
<Button type={'primary'} ghost onClick={onPreview} disabled={taskLen === 0 || !isStartingPointValid}>
|
||||
{!canPublishOrPreview && (
|
||||
<Alert
|
||||
message="This test isn't published yet. You need to specify a title and tasks to publish it."
|
||||
type="warning"
|
||||
showIcon
|
||||
className="mt-4 border-0 rounded-lg items-baseline mb-3 text-sm"
|
||||
closable
|
||||
/>
|
||||
)}
|
||||
|
||||
<Tooltip title={!canPublishOrPreview ? 'Define the starting point and the tasks to preview.' : ''}>
|
||||
<Button type={'primary'} ghost onClick={onPreview} disabled={!canPublishOrPreview}>
|
||||
<Space align={'center'}>
|
||||
Save Draft & Preview <ExportOutlined rev={undefined} />
|
||||
Save Draft & Preview <ExportOutlined />
|
||||
</Space>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip title={taskLen === 0 ? 'Define the starting point and the tasks to proceed.' : ''}>
|
||||
<Button type={'primary'} onClick={onSave} disabled={taskLen === 0 || !isStartingPointValid}>
|
||||
<Tooltip title={!canPublishOrPreview ? 'Define the starting point and the tasks to publish.' : ''}>
|
||||
<Button type={'primary'} onClick={onSave} disabled={!canPublishOrPreview}>
|
||||
Publish Test
|
||||
</Button>
|
||||
</Tooltip>
|
||||
|
||||
|
||||
</div>
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
export default SidePanel;
|
||||
export default observer(SidePanel);
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ function StepsModal({
|
|||
checkedChildren="Yes"
|
||||
unCheckedChildren="No"
|
||||
/>
|
||||
<div className={'text-disabled-text mb-4 mt-1'}>
|
||||
<div className={'text-sm mb-4 mt-1'}>
|
||||
Enabling this option will show a text field for participants to type
|
||||
their answer.
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import {
|
|||
import { useParams, useHistory, Prompt } from 'react-router-dom';
|
||||
import Breadcrumb from 'Shared/Breadcrumb';
|
||||
import { EditOutlined, DeleteOutlined, MoreOutlined } from '@ant-design/icons';
|
||||
import {Power, Info, ListTodo} from 'lucide-react';
|
||||
import { useModal } from 'App/components/Modal';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useStore } from 'App/mstore';
|
||||
|
|
@ -194,7 +195,7 @@ function TestEdit() {
|
|||
</Modal>
|
||||
<div className={'grid grid-cols-4 gap-2'}>
|
||||
<div className={'flex w-full flex-col gap-2 col-span-3'}>
|
||||
<div className={'flex items-start p-4 rounded bg-white border justify-between'}>
|
||||
<div className={'flex items-start p-4 rounded-lg bg-white shadow-sm justify-between'}>
|
||||
<div>
|
||||
<Typography.Title level={4}>{uxtestingStore.instance.title}</Typography.Title>
|
||||
<Typography.Text>{uxtestingStore.instance.description}</Typography.Text>
|
||||
|
|
@ -206,32 +207,40 @@ function TestEdit() {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div className={'p-4 rounded bg-white border flex flex-col gap-2'}>
|
||||
<Typography.Title level={5}>🏁 Starting point</Typography.Title>
|
||||
<Input
|
||||
style={{ width: 400 }}
|
||||
type={'url'}
|
||||
disabled={isPublished}
|
||||
placeholder={'https://mywebsite.com/example-page'}
|
||||
value={uxtestingStore.instance!.startingPath}
|
||||
onChange={(e) => {
|
||||
setHasChanged(true);
|
||||
if (!e.target.value.startsWith('https://')) {
|
||||
e.target.value = 'https://';
|
||||
}
|
||||
uxtestingStore.instance!.setProperty('startingPath', e.target.value);
|
||||
}}
|
||||
/>
|
||||
{uxtestingStore.instance!.startingPath === 'https://' || isStartingPointValid ? (
|
||||
<Typography.Text>The test starts at this URL, but not everyone visiting the link will see it. After publishing, you'll get a Distribution URL to share with selected participants.</Typography.Text>
|
||||
) : (
|
||||
<Typography.Text color={'red'}>Starting point URL is invalid.</Typography.Text>
|
||||
)}
|
||||
</div>
|
||||
<div className={'p-4 rounded-lg bg-white shadow-sm flex flex-col gap-2'}>
|
||||
<Typography.Title level={5} className='flex gap-2 items-center'>
|
||||
<Power size={16} /> Starting point
|
||||
</Typography.Title>
|
||||
<Input
|
||||
style={{ width: 400 }}
|
||||
type={'url'}
|
||||
disabled={isPublished}
|
||||
placeholder={'yoursite.com/example-page'}
|
||||
value={uxtestingStore.instance!.startingPath.replace('https://', '')}
|
||||
addonBefore="https://"
|
||||
onChange={(e) => {
|
||||
setHasChanged(true);
|
||||
let value = e.target.value;
|
||||
if (value.startsWith('https://')) {
|
||||
value = value.replace('https://', '');
|
||||
}
|
||||
uxtestingStore.instance!.setProperty('startingPath', 'https://' + value);
|
||||
}}
|
||||
/>
|
||||
{uxtestingStore.instance!.startingPath === 'https://' || isStartingPointValid ? (
|
||||
<Typography.Text className='text-sm'>
|
||||
The test will start on this page. A special link from this will be created for you to share with participants only.
|
||||
</Typography.Text>
|
||||
) : (
|
||||
<Typography.Text className='text-sm text-red-600'>Invalid starting point.</Typography.Text>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className={'p-4 rounded bg-white border flex flex-col gap-2'}>
|
||||
<Typography.Title level={5}>
|
||||
📖 Introduction and Guidelines for Participants
|
||||
|
||||
|
||||
<div className={'p-4 rounded-lg bg-white shadow-sm flex flex-col gap-2'}>
|
||||
<Typography.Title level={5} className='flex gap-2 items-center'>
|
||||
<Info size={16} /> Introduction and Guidelines for Participants
|
||||
</Typography.Title>
|
||||
<Typography.Text></Typography.Text>
|
||||
{isOverviewEditing ? (
|
||||
|
|
@ -276,15 +285,15 @@ function TestEdit() {
|
|||
</Button>
|
||||
</>
|
||||
) : (
|
||||
<Button type={'primary'} ghost onClick={() => setIsOverviewEditing(true)}>
|
||||
{uxtestingStore.instance?.guidelines?.length ? 'Edit' : 'Add'}
|
||||
<Button type={'link'} onClick={() => setIsOverviewEditing(true)} className='px-0'>
|
||||
{uxtestingStore.instance?.guidelines?.length ? 'Edit' : 'Specify Guidelines'}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={'p-4 rounded bg-white border flex flex-col gap-2'}>
|
||||
<Typography.Title level={5}>📋 Tasks</Typography.Title>
|
||||
<div className={'p-4 rounded-lg bg-white shadow-sm flex flex-col gap-2'}>
|
||||
<Typography.Title level={5} className='flex gap-2 items-center'><ListTodo size={16} /> Tasks</Typography.Title>
|
||||
{uxtestingStore.instance!.tasks.map((task, index) => (
|
||||
<Step
|
||||
ind={index}
|
||||
|
|
@ -359,7 +368,7 @@ function TestEdit() {
|
|||
</div>
|
||||
|
||||
<div className={'p-4 rounded bg-white border flex flex-col gap-2'}>
|
||||
<Typography.Title level={5}>🎉 Conclusion Message</Typography.Title>
|
||||
<Typography.Title level={5}>🎉 Conclusion</Typography.Title>
|
||||
<div>
|
||||
{isConclusionEditing ? (
|
||||
<Input.TextArea
|
||||
|
|
@ -398,7 +407,7 @@ function TestEdit() {
|
|||
</Button>
|
||||
</>
|
||||
) : (
|
||||
<Button type={'primary'} ghost onClick={() => setIsConclusionEditing(true)}>
|
||||
<Button type={'link'} className='px-0' onClick={() => setIsConclusionEditing(true)}>
|
||||
Edit
|
||||
</Button>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ import { getPdf2 } from 'Components/AssistStats/pdfGenerator';
|
|||
import { useModal } from 'Components/Modal';
|
||||
import LiveTestsModal from 'Components/UsabilityTesting/LiveTestsModal';
|
||||
import React from 'react';
|
||||
import { Button, Typography, Select, Space, Popover, Dropdown } from 'antd';
|
||||
import { Button, Typography, Select, Space, Popover, Dropdown, Tooltip } from 'antd';
|
||||
import { InfoCircleOutlined } from '@ant-design/icons';
|
||||
import { withSiteId, usabilityTesting, usabilityTestingEdit } from 'App/routes';
|
||||
import { useParams, useHistory } from 'react-router-dom';
|
||||
import Breadcrumb from 'Shared/Breadcrumb';
|
||||
|
|
@ -106,7 +107,7 @@ function TestOverview() {
|
|||
}, [testId, siteId]);
|
||||
|
||||
if (!uxtestingStore.instance) {
|
||||
return <Loader loading={uxtestingStore.isLoading}>No data.</Loader>;
|
||||
return <Loader loading={uxtestingStore.isLoading}>No Data</Loader>;
|
||||
} else {
|
||||
document.title = `Usability Tests | ${uxtestingStore.instance.title}`;
|
||||
}
|
||||
|
|
@ -128,8 +129,10 @@ function TestOverview() {
|
|||
}
|
||||
]}
|
||||
/>
|
||||
<div className={'rounded border bg-white'}>
|
||||
<div className={'rounded-lg shadow-sm bg-white'}>
|
||||
|
||||
<Title testId={testId} siteId={siteId} />
|
||||
|
||||
{uxtestingStore.instance.liveCount ? (
|
||||
<div className={'p-4 flex items-center gap-2'}>
|
||||
<div className={'relative h-4 w-4'}>
|
||||
|
|
@ -158,10 +161,12 @@ function TestOverview() {
|
|||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
<ParticipantOverview />
|
||||
|
||||
<TaskSummary />
|
||||
|
||||
<div className={'mt-2 rounded border p-4 bg-white flex gap-2 items-center'}>
|
||||
<div className={'mt-2 rounded-lg shadow-sm p-4 bg-white flex flex-col gap-2'}>
|
||||
<Typography.Title style={{ marginBottom: 0 }} level={5}>
|
||||
Open-ended task responses
|
||||
</Typography.Title>
|
||||
|
|
@ -178,11 +183,13 @@ function TestOverview() {
|
|||
</Space>
|
||||
</Button>
|
||||
) : (
|
||||
<Typography.Text>0 at the moment.</Typography.Text>
|
||||
<div className='text-base flex gap-2 mx-auto py-5'>
|
||||
<InfoCircleOutlined /> No Data
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className={'mt-2 rounded border p-4 bg-white flex gap-1 items-start flex-col'}>
|
||||
<div className={'mt-2 rounded-lg shadow-sm p-4 bg-white flex gap-1 items-start flex-col'}>
|
||||
<Typography.Title style={{ marginBottom: 0 }} level={5}>
|
||||
Sessions
|
||||
</Typography.Title>
|
||||
|
|
@ -190,7 +197,12 @@ function TestOverview() {
|
|||
{/*<div className={'flex gap-1 link'}>clear selection</div>*/}
|
||||
<div className={'flex flex-col w-full'}>
|
||||
<Loader loading={uxtestingStore.isLoading}>
|
||||
<NoContent show={uxtestingStore.testSessions.list.length == 0} title='No data'>
|
||||
<NoContent show={uxtestingStore.testSessions.list.length == 0}
|
||||
title={
|
||||
<div className='text-base flex gap-2'>
|
||||
<InfoCircleOutlined /> No Data
|
||||
</div>
|
||||
}>
|
||||
{uxtestingStore.testSessions.list.map((session) => (
|
||||
// @ts-ignore
|
||||
<SessionItem session={session} query={'?uxt=true'} />
|
||||
|
|
@ -231,7 +243,7 @@ const ParticipantOverview = observer(() => {
|
|||
const { uxtestingStore } = useStore();
|
||||
|
||||
return (
|
||||
<div className={'p-4 rounded border bg-white mt-2'}>
|
||||
<div className={'p-4 rounded-lg shadow-sm bg-white mt-2'}>
|
||||
<Typography.Title level={5}>Participant Overview</Typography.Title>
|
||||
{uxtestingStore.testStats ? (
|
||||
<div className={'flex gap-4'}>
|
||||
|
|
@ -316,7 +328,7 @@ const TaskSummary = observer(() => {
|
|||
: uxtestingStore.taskStats;
|
||||
|
||||
return (
|
||||
<div className={'mt-2 rounded border p-4 bg-white'}>
|
||||
<div className={'mt-2 rounded-lg shadow-sm p-4 bg-white'}>
|
||||
<div className={'flex justify-between items-center mb-2'}>
|
||||
<Typography.Title level={5}>Task Summary</Typography.Title>
|
||||
|
||||
|
|
@ -337,7 +349,12 @@ const TaskSummary = observer(() => {
|
|||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
{!uxtestingStore.taskStats.length ? <NoContent show title={'No data'} /> : null}
|
||||
{!uxtestingStore.taskStats.length ? <NoContent show title=
|
||||
{
|
||||
<div className='text-base flex gap-2'>
|
||||
<InfoCircleOutlined /> No Data
|
||||
</div>
|
||||
} /> : null}
|
||||
{shownTasks.map((tst, index) => (
|
||||
<Stage
|
||||
stage={{ ...tst, isActive: true, skipped: tst.skipped || totalAttempts - tst.completed }}
|
||||
|
|
@ -363,16 +380,16 @@ const Title = observer(({ testId, siteId }: any) => {
|
|||
uxtestingStore.updateTestStatus(value);
|
||||
switch (value) {
|
||||
case 'in-progress':
|
||||
toast.success('The usability test is now live and accessible to participants.');
|
||||
toast.success('The test is now live. Use the distribution link to share it with participants.');
|
||||
break;
|
||||
case 'paused':
|
||||
toast.success(
|
||||
'Usability test is on \'Hold\'—participant activity paused. Switch it to “ongoing” to resume activity.'
|
||||
'The test is on \'Hold\'—participant activity paused. Toggle back to “ongoing” to resume activity.'
|
||||
);
|
||||
break;
|
||||
case 'closed':
|
||||
toast.success(
|
||||
'The usability test has been marked as completed. All participant interactions are now finalized.'
|
||||
'The test is complete and closed.'
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
|
@ -434,9 +451,10 @@ const Title = observer(({ testId, siteId }: any) => {
|
|||
return (
|
||||
<div className={'p-4 border-b'}>
|
||||
<div className={'flex items-center gap-2'}>
|
||||
<Typography.Title level={4}>{uxtestingStore.instance!.title}</Typography.Title>
|
||||
<Typography.Title level={4} className='cap-first'>{uxtestingStore.instance!.title}</Typography.Title>
|
||||
<div className={'ml-auto'} />
|
||||
<Select
|
||||
className='utStatusToggler'
|
||||
value={uxtestingStore.instance!.status}
|
||||
style={{ width: 150 }}
|
||||
onChange={handleChange}
|
||||
|
|
@ -447,35 +465,36 @@ const Title = observer(({ testId, siteId }: any) => {
|
|||
</Space>
|
||||
)}
|
||||
/>
|
||||
<Button
|
||||
{/* <Button
|
||||
disabled={uxtestingStore.instance!.status === 'closed'}
|
||||
type={'primary'}
|
||||
ghost
|
||||
onClick={redirectToEdit}
|
||||
>
|
||||
<Space align={'center'}>
|
||||
{uxtestingStore.instance!.tasks.length} Tasks <EditOutlined rev={undefined} />{' '}
|
||||
</Space>
|
||||
</Button>
|
||||
</Button> */}
|
||||
{isActive ?
|
||||
<Popover
|
||||
trigger={'click'}
|
||||
title={'Participants Link'}
|
||||
trigger={'hover'}
|
||||
placement="bottomRight"
|
||||
className='rounded-lg'
|
||||
content={
|
||||
<div style={{ width: '220px' }}>
|
||||
<div className={'text-disabled-text text-sm'}>
|
||||
Distribute following link via email or other methods to share the survey with test
|
||||
participants.
|
||||
<div style={{ width: '300px' }}>
|
||||
<div className={'text-base font-medium'}>
|
||||
Distribute the following link with test participants via email or other methods.
|
||||
</div>
|
||||
<div
|
||||
style={{ background: '#E4F6F6' }}
|
||||
className={'p-2 rounded border shadow break-all my-2'}
|
||||
className={'p-2 rounded-lg break-all my-2 text-lg'}
|
||||
>
|
||||
{`${uxtestingStore.instance!.startingPath}?oruxt=${
|
||||
uxtestingStore.instance!.testId
|
||||
}`}
|
||||
</div>
|
||||
<CopyButton
|
||||
variant={'outline'}
|
||||
variant={'text-primary'}
|
||||
content={`${uxtestingStore.instance!.startingPath}?oruxt=${
|
||||
uxtestingStore.instance!.testId
|
||||
}`}
|
||||
|
|
@ -483,12 +502,14 @@ const Title = observer(({ testId, siteId }: any) => {
|
|||
</div>
|
||||
}
|
||||
>
|
||||
<Button type={'primary'} ghost>
|
||||
|
||||
<Button type={'primary'} >
|
||||
<Space align={'center'}>
|
||||
Distribute
|
||||
Distribute Test
|
||||
<ShareAltOutlined rev={undefined} />
|
||||
</Space>
|
||||
</Button>
|
||||
|
||||
</Popover>
|
||||
: null}
|
||||
<Dropdown
|
||||
|
|
@ -503,7 +524,7 @@ const Title = observer(({ testId, siteId }: any) => {
|
|||
<Button icon={<MoreOutlined rev={undefined} />}></Button>
|
||||
</Dropdown>
|
||||
</div>
|
||||
<div className={'whitespace-pre-wrap mt-2'}>{truncatedDescr}</div>
|
||||
<div className={'whitespace-pre-wrap mt-2 cap-first'}>{truncatedDescr}</div>
|
||||
{uxtestingStore.instance?.description && uxtestingStore.instance.description.length > 250 ? (
|
||||
<div className={'link'} onClick={() => setTruncate(!truncate)}>
|
||||
{truncate ? 'Show more' : 'Show less'}
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ function TestsTable() {
|
|||
{uxtestingStore.searchQuery === '' ? (
|
||||
<AnimatedSVG name={ICONS.NO_UXT} size={172} />
|
||||
) : null}
|
||||
<div className={'text-xl font-semibold mt-4'}>
|
||||
<div className={'text-lg font-medium mt-4'}>
|
||||
{uxtestingStore.searchQuery === ''
|
||||
? 'Uncover real user insights through usability tests.'
|
||||
: 'No results matching your search'}
|
||||
|
|
@ -215,11 +215,11 @@ function Row({ test, siteId }: { test: UxTListEntry; siteId: string }) {
|
|||
<Icon name={'list-ul'} color={'tealx'} size={20} />
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ maxWidth: 550 }}>
|
||||
<div style={{ maxWidth: 550 }} className='cap-first'>
|
||||
<Link className="link !p-0" to={test.status === 'preview' ? editLink : link}>
|
||||
{test.title}
|
||||
</Link>
|
||||
<div className={'text-disabled-text whitespace-nowrap text-ellipsis overflow-hidden'}>
|
||||
<div className={'w-11/12 text-sm whitespace-nowrap text-ellipsis overflow-hidden'}>
|
||||
{test.description}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -230,7 +230,7 @@ function Row({ test, siteId }: { test: UxTListEntry; siteId: string }) {
|
|||
{checkForRecent(getDateFromMill(test.updatedAt)!, 'LLL dd, yyyy, hh:mm a')}
|
||||
</Cell>
|
||||
<Cell size={1}>
|
||||
<Tag color={colors[test.status]}>{statusMap[test.status]}</Tag>
|
||||
<Tag className='text-base rounded-lg' bordered={false} color={colors[test.status]}>{statusMap[test.status]}</Tag>
|
||||
</Cell>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ function LiveSessionList(props: Props) {
|
|||
<div className="flex items-center justify-center flex-col">
|
||||
<AnimatedSVG name={ICONS.NO_LIVE_SESSIONS} size={60} />
|
||||
<div className="mt-4" />
|
||||
<div className="text-center">No live sessions found</div>
|
||||
<div className="text-center text-lg font-medium">No live sessions found</div>
|
||||
</div>
|
||||
}
|
||||
subtext={
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ function NotesList({ members }: { members: Array<Record<string, any>> }) {
|
|||
<div className="flex flex-col items-center justify-center">
|
||||
{/* <Icon name="no-dashboard" size={80} color="figmaColors-accent-secondary" /> */}
|
||||
<AnimatedSVG name={ICONS.NO_NOTES} size={60} />
|
||||
<div className="text-center mt-4">No notes yet</div>
|
||||
<div className="text-center mt-4 text-lg font-medium">No notes yet</div>
|
||||
</div>
|
||||
}
|
||||
subtext={
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ function SessionList(props: Props) {
|
|||
<AnimatedSVG name={NO_CONTENT.icon} size={60} />
|
||||
</span>
|
||||
<div className='mt-4' />
|
||||
<div className='text-center relative'>
|
||||
<div className='text-center relative text-lg font-medium'>
|
||||
{NO_CONTENT.message }
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -416,3 +416,8 @@ p {
|
|||
display: none;
|
||||
}
|
||||
|
||||
.utStatusToggler .ant-select-selector{
|
||||
border-radius: .5rem;
|
||||
box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,20 +1,16 @@
|
|||
<svg width="173" height="112" viewBox="0 0 173 112" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="1.5" y="1.61172" width="170" height="109" rx="5" stroke="black" stroke-opacity="0.6" stroke-width="2"/>
|
||||
<path d="M145.243 20.9749C144.648 21.5697 143.841 21.9039 143 21.9039C142.159 21.9039 141.352 21.5697 140.757 20.9749C140.162 20.3801 139.828 19.5733 139.828 18.732C139.828 17.8908 140.162 17.084 140.757 16.4892C141.352 15.8943 142.159 15.5602 143 15.5602C143.841 15.5602 144.648 15.8943 145.243 16.4892C145.838 17.084 146.172 17.8908 146.172 18.732C146.172 19.5733 145.838 20.3801 145.243 20.9749Z" fill="#434343" stroke="black"/>
|
||||
<path d="M128.188 12.0492C127.408 12.0492 126.661 12.3587 126.11 12.9096C125.559 13.4605 125.25 14.2077 125.25 14.9867V26.7367C125.25 27.5158 125.559 28.263 126.11 28.8139C126.661 29.3647 127.408 29.6742 128.188 29.6742H157.812C158.592 29.6742 159.339 29.3647 159.89 28.8139C160.441 28.263 160.75 27.5158 160.75 26.7367V14.9867C160.75 14.2077 160.441 13.4605 159.89 12.9096C159.339 12.3587 158.592 12.0492 157.812 12.0492H128.188ZM150.047 28.2055C149.382 26.3402 147.462 23.7992 143 23.7992C138.539 23.7992 136.618 26.3402 135.953 28.2055H128.188C127.798 28.2055 127.424 28.0507 127.149 27.7753C126.873 27.4998 126.719 27.1263 126.719 26.7367V14.9867C126.719 14.5972 126.873 14.2236 127.149 13.9482C127.424 13.6727 127.798 13.518 128.188 13.518H157.812C158.202 13.518 158.576 13.6727 158.851 13.9482C159.127 14.2236 159.281 14.5972 159.281 14.9867V26.7367C159.281 27.1263 159.127 27.4998 158.851 27.7753C158.576 28.0507 158.202 28.2055 157.812 28.2055H150.047Z" fill="#434343"/>
|
||||
<rect x="125" y="36.1117" width="36" height="19" rx="2.5" fill="#42AE5E" fill-opacity="0.1"/>
|
||||
<rect x="125" y="36.1117" width="36" height="19" rx="2.5" stroke="black"/>
|
||||
<path d="M148.854 41.2577C148.901 41.3042 148.938 41.3593 148.963 41.4201C148.988 41.4808 149.001 41.546 149.001 41.6117C149.001 41.6775 148.988 41.7426 148.963 41.8034C148.938 41.8641 148.901 41.9193 148.854 41.9657L141.854 48.9657C141.808 49.0123 141.753 49.0492 141.692 49.0744C141.631 49.0996 141.566 49.1126 141.5 49.1126C141.434 49.1126 141.369 49.0996 141.309 49.0744C141.248 49.0492 141.193 49.0123 141.146 48.9657L137.646 45.4657C137.552 45.3718 137.5 45.2445 137.5 45.1117C137.5 44.9789 137.552 44.8516 137.646 44.7577C137.74 44.6638 137.867 44.6111 138 44.6111C138.133 44.6111 138.26 44.6638 138.354 44.7577L141.5 47.9047L148.146 41.2577C148.193 41.2112 148.248 41.1742 148.309 41.149C148.369 41.1238 148.434 41.1108 148.5 41.1108C148.566 41.1108 148.631 41.1238 148.692 41.149C148.753 41.1742 148.808 41.2112 148.854 41.2577Z" fill="#42AE5E"/>
|
||||
<rect x="125" y="59.1117" width="36" height="19" rx="2.5" fill="#42AE5E" fill-opacity="0.1"/>
|
||||
<rect x="125" y="59.1117" width="36" height="19" rx="2.5" stroke="black"/>
|
||||
<path d="M148.854 64.2577C148.901 64.3042 148.938 64.3593 148.963 64.4201C148.988 64.4808 149.001 64.546 149.001 64.6117C149.001 64.6775 148.988 64.7426 148.963 64.8034C148.938 64.8641 148.901 64.9193 148.854 64.9657L141.854 71.9657C141.808 72.0123 141.753 72.0492 141.692 72.0744C141.631 72.0996 141.566 72.1126 141.5 72.1126C141.434 72.1126 141.369 72.0996 141.309 72.0744C141.248 72.0492 141.193 72.0123 141.146 71.9657L137.646 68.4657C137.552 68.3718 137.5 68.2445 137.5 68.1117C137.5 67.9789 137.552 67.8516 137.646 67.7577C137.74 67.6638 137.867 67.6111 138 67.6111C138.133 67.6111 138.26 67.6638 138.354 67.7577L141.5 70.9047L148.146 64.2577C148.193 64.2112 148.248 64.1742 148.309 64.149C148.369 64.1238 148.434 64.1108 148.5 64.1108C148.566 64.1108 148.631 64.1238 148.692 64.149C148.753 64.1742 148.808 64.2112 148.854 64.2577Z" fill="#42AE5E"/>
|
||||
<rect x="125" y="82.1117" width="36" height="19" rx="2.5" fill="#CC0000" fill-opacity="0.1"/>
|
||||
<rect x="125" y="82.1117" width="36" height="19" rx="2.5" stroke="black"/>
|
||||
<path d="M139.646 88.2577C139.692 88.2112 139.748 88.1742 139.808 88.149C139.869 88.1238 139.934 88.1108 140 88.1108C140.066 88.1108 140.131 88.1238 140.192 88.149C140.252 88.1742 140.307 88.2112 140.354 88.2577L143 90.9047L145.646 88.2577C145.692 88.2112 145.748 88.1744 145.808 88.1492C145.869 88.124 145.934 88.1111 146 88.1111C146.066 88.1111 146.131 88.124 146.192 88.1492C146.252 88.1744 146.307 88.2112 146.354 88.2577C146.4 88.3042 146.437 88.3594 146.462 88.4201C146.488 88.4809 146.501 88.546 146.501 88.6117C146.501 88.6775 146.488 88.7426 146.462 88.8033C146.437 88.864 146.4 88.9192 146.354 88.9657L143.707 91.6117L146.354 94.2577C146.4 94.3042 146.437 94.3594 146.462 94.4201C146.488 94.4809 146.501 94.546 146.501 94.6117C146.501 94.6775 146.488 94.7426 146.462 94.8033C146.437 94.864 146.4 94.9192 146.354 94.9657C146.307 95.0122 146.252 95.0491 146.192 95.0742C146.131 95.0994 146.066 95.1123 146 95.1123C145.934 95.1123 145.869 95.0994 145.808 95.0742C145.748 95.0491 145.692 95.0122 145.646 94.9657L143 92.3187L140.354 94.9657C140.307 95.0122 140.252 95.0491 140.192 95.0742C140.131 95.0994 140.066 95.1123 140 95.1123C139.934 95.1123 139.869 95.0994 139.808 95.0742C139.748 95.0491 139.692 95.0122 139.646 94.9657C139.599 94.9192 139.563 94.864 139.537 94.8033C139.512 94.7426 139.499 94.6775 139.499 94.6117C139.499 94.546 139.512 94.4809 139.537 94.4201C139.563 94.3594 139.599 94.3042 139.646 94.2577L142.293 91.6117L139.646 88.9657C139.599 88.9193 139.562 88.8641 139.537 88.8034C139.512 88.7426 139.499 88.6775 139.499 88.6117C139.499 88.546 139.512 88.4808 139.537 88.4201C139.562 88.3593 139.599 88.3042 139.646 88.2577Z" fill="#CC0000"/>
|
||||
<g opacity="0.5">
|
||||
<rect x="12.5" y="10.6117" width="104" height="58" rx="4" fill="#DDDDDD"/>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="1.5 1.61 170 109">
|
||||
<path d="M166.5 1.61169H6.5C3.73858 1.61169 1.5 3.85027 1.5 6.61169V105.612C1.5 108.373 3.73858 110.612 6.5 110.612H166.5C169.261 110.612 171.5 108.373 171.5 105.612V6.61169C171.5 3.85027 169.261 1.61169 166.5 1.61169Z" fill="#E2E4F6"/>
|
||||
<path d="M158.5 10.6117H127.5C126.119 10.6117 125 11.731 125 13.1117V27.1117C125 28.4924 126.119 29.6117 127.5 29.6117H158.5C159.881 29.6117 161 28.4924 161 27.1117V13.1117C161 11.731 159.881 10.6117 158.5 10.6117Z" fill="white"/>
|
||||
<path d="M143 21.5191C144.597 21.5191 145.892 20.2243 145.892 18.6271C145.892 17.0299 144.597 15.7352 143 15.7352C141.403 15.7352 140.108 17.0299 140.108 18.6271C140.108 20.2243 141.403 21.5191 143 21.5191Z" stroke="#A6ADED" stroke-width="1.15678" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M147.627 26.1462C147.627 24.919 147.14 23.7421 146.272 22.8744C145.404 22.0066 144.227 21.5191 143 21.5191C141.773 21.5191 140.596 22.0066 139.728 22.8744C138.86 23.7421 138.373 24.919 138.373 26.1462" stroke="#A6ADED" stroke-width="1.15678" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M158.5 34.6117H127.5C126.119 34.6117 125 35.731 125 37.1117V51.1117C125 52.4924 126.119 53.6117 127.5 53.6117H158.5C159.881 53.6117 161 52.4924 161 51.1117V37.1117C161 35.731 159.881 34.6117 158.5 34.6117Z" fill="#E3F7E8"/>
|
||||
<path d="M148.854 39.7577C148.901 39.8042 148.938 39.8593 148.963 39.9201C148.988 39.9808 149.001 40.046 149.001 40.1117C149.001 40.1775 148.988 40.2426 148.963 40.3034C148.938 40.3641 148.901 40.4193 148.854 40.4657L141.854 47.4657C141.808 47.5123 141.753 47.5492 141.692 47.5744C141.631 47.5996 141.566 47.6126 141.5 47.6126C141.434 47.6126 141.369 47.5996 141.309 47.5744C141.248 47.5492 141.193 47.5123 141.146 47.4657L137.646 43.9657C137.552 43.8718 137.5 43.7445 137.5 43.6117C137.5 43.4789 137.552 43.3516 137.646 43.2577C137.74 43.1638 137.867 43.1111 138 43.1111C138.133 43.1111 138.26 43.1638 138.354 43.2577L141.5 46.4047L148.146 39.7577C148.193 39.7112 148.248 39.6742 148.309 39.649C148.369 39.6238 148.434 39.6108 148.5 39.6108C148.566 39.6108 148.631 39.6238 148.692 39.649C148.753 39.6742 148.808 39.7112 148.854 39.7577Z" fill="#42AE5E"/>
|
||||
<path d="M158.5 58.6117H127.5C126.119 58.6117 125 59.731 125 61.1117V75.1117C125 76.4924 126.119 77.6117 127.5 77.6117H158.5C159.881 77.6117 161 76.4924 161 75.1117V61.1117C161 59.731 159.881 58.6117 158.5 58.6117Z" fill="#E3F7E8"/>
|
||||
<path d="M148.854 63.7577C148.901 63.8042 148.938 63.8593 148.963 63.9201C148.988 63.9808 149.001 64.046 149.001 64.1117C149.001 64.1775 148.988 64.2426 148.963 64.3034C148.938 64.3641 148.901 64.4193 148.854 64.4657L141.854 71.4657C141.808 71.5123 141.753 71.5492 141.692 71.5744C141.631 71.5996 141.566 71.6126 141.5 71.6126C141.434 71.6126 141.369 71.5996 141.309 71.5744C141.248 71.5492 141.193 71.5123 141.146 71.4657L137.646 67.9657C137.552 67.8718 137.5 67.7445 137.5 67.6117C137.5 67.4789 137.552 67.3516 137.646 67.2577C137.74 67.1638 137.867 67.1111 138 67.1111C138.133 67.1111 138.26 67.1638 138.354 67.2577L141.5 70.4047L148.146 63.7577C148.193 63.7112 148.248 63.6742 148.309 63.649C148.369 63.6238 148.434 63.6108 148.5 63.6108C148.566 63.6108 148.631 63.6238 148.692 63.649C148.753 63.6742 148.808 63.7112 148.854 63.7577Z" fill="#42AE5E"/>
|
||||
<path d="M158.5 82.6117H127.5C126.119 82.6117 125 83.731 125 85.1117V99.1117C125 100.492 126.119 101.612 127.5 101.612H158.5C159.881 101.612 161 100.492 161 99.1117V85.1117C161 83.731 159.881 82.6117 158.5 82.6117Z" fill="#FCECEC"/>
|
||||
<path d="M139.646 88.7577C139.692 88.7112 139.748 88.6742 139.808 88.649C139.869 88.6238 139.934 88.6108 140 88.6108C140.066 88.6108 140.131 88.6238 140.192 88.649C140.252 88.6742 140.307 88.7112 140.354 88.7577L143 91.4047L145.646 88.7577C145.692 88.7112 145.748 88.6744 145.808 88.6492C145.869 88.624 145.934 88.6111 146 88.6111C146.066 88.6111 146.131 88.624 146.192 88.6492C146.252 88.6744 146.307 88.7112 146.354 88.7577C146.4 88.8042 146.437 88.8594 146.462 88.9201C146.488 88.9809 146.501 89.046 146.501 89.1117C146.501 89.1775 146.488 89.2426 146.462 89.3033C146.437 89.364 146.4 89.4192 146.354 89.4657L143.707 92.1117L146.354 94.7577C146.4 94.8042 146.437 94.8594 146.462 94.9201C146.488 94.9809 146.501 95.046 146.501 95.1117C146.501 95.1775 146.488 95.2426 146.462 95.3033C146.437 95.364 146.4 95.4192 146.354 95.4657C146.307 95.5122 146.252 95.5491 146.192 95.5742C146.131 95.5994 146.066 95.6123 146 95.6123C145.934 95.6123 145.869 95.5994 145.808 95.5742C145.748 95.5491 145.692 95.5122 145.646 95.4657L143 92.8187L140.354 95.4657C140.307 95.5122 140.252 95.5491 140.192 95.5742C140.131 95.5994 140.066 95.6123 140 95.6123C139.934 95.6123 139.869 95.5994 139.808 95.5742C139.748 95.5491 139.692 95.5122 139.646 95.4657C139.599 95.4192 139.563 95.364 139.537 95.3033C139.512 95.2426 139.499 95.1775 139.499 95.1117C139.499 95.046 139.512 94.9809 139.537 94.9201C139.563 94.8594 139.599 94.8042 139.646 94.7577L142.293 92.1117L139.646 89.4657C139.599 89.4193 139.562 89.3641 139.537 89.3034C139.512 89.2426 139.499 89.1775 139.499 89.1117C139.499 89.046 139.512 88.9808 139.537 88.9201C139.562 88.8593 139.599 88.8042 139.646 88.7577Z" fill="#CC0000"/>
|
||||
<path opacity="0.6" d="M112.5 10.6117H16.5C14.2909 10.6117 12.5 12.4026 12.5 14.6117V64.6117C12.5 66.8208 14.2909 68.6117 16.5 68.6117H112.5C114.709 68.6117 116.5 66.8208 116.5 64.6117V14.6117C116.5 12.4026 114.709 10.6117 112.5 10.6117Z" fill="white"/>
|
||||
<g opacity="0.56">
|
||||
<path opacity="0.7" d="M112.5 71.6117H16.5C14.2909 71.6117 12.5 73.4026 12.5 75.6117V98.6117C12.5 100.821 14.2909 102.612 16.5 102.612H112.5C114.709 102.612 116.5 100.821 116.5 98.6117V75.6117C116.5 73.4026 114.709 71.6117 112.5 71.6117Z" fill="white"/>
|
||||
</g>
|
||||
<g opacity="0.2">
|
||||
<rect x="12.5" y="71.6117" width="104" height="31" rx="4" fill="#DDDDDD"/>
|
||||
</g>
|
||||
</svg>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
Loading…
Add table
Reference in a new issue