From 9d8487ad6e9e881b05879f49cc2558e8825dda3d Mon Sep 17 00:00:00 2001 From: Jaanus Sellin Date: Fri, 22 Dec 2023 15:09:02 +0200 Subject: [PATCH] feat: feedback skeleton ui (#5727) This adds component, which will allow to draw feedback component based on incoming data. --- .../common/FilterDateItem/FilterDateItem.tsx | 2 +- .../feedbackNew/FeedbackComponent.tsx | 90 +++++++++++++++++++ .../component/feedbackNew/FeedbackContext.ts | 34 +++++++ .../feedbackNew/FeedbackProvider.tsx | 36 ++++++++ .../src/component/feedbackNew/useFeedback.tsx | 10 +++ frontend/src/index.tsx | 19 ++-- 6 files changed, 182 insertions(+), 9 deletions(-) create mode 100644 frontend/src/component/feedbackNew/FeedbackComponent.tsx create mode 100644 frontend/src/component/feedbackNew/FeedbackContext.ts create mode 100644 frontend/src/component/feedbackNew/FeedbackProvider.tsx create mode 100644 frontend/src/component/feedbackNew/useFeedback.tsx diff --git a/frontend/src/component/common/FilterDateItem/FilterDateItem.tsx b/frontend/src/component/common/FilterDateItem/FilterDateItem.tsx index 83120e2c68..1b2263f7a4 100644 --- a/frontend/src/component/common/FilterDateItem/FilterDateItem.tsx +++ b/frontend/src/component/common/FilterDateItem/FilterDateItem.tsx @@ -84,7 +84,7 @@ export const FilterDateItem: FC = ({ const formattedValue = selectedDate ? format(selectedDate, 'yyyy-MM-dd') : ''; - onChange({ operator, values: [formattedValue] ?? [] }); + onChange({ operator, values: [formattedValue] }); }} /> diff --git a/frontend/src/component/feedbackNew/FeedbackComponent.tsx b/frontend/src/component/feedbackNew/FeedbackComponent.tsx new file mode 100644 index 0000000000..80b321d474 --- /dev/null +++ b/frontend/src/component/feedbackNew/FeedbackComponent.tsx @@ -0,0 +1,90 @@ +import { Box, styled } from '@mui/material'; +import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; +import { useFeedback } from './useFeedback'; + +export const StyledContainer = styled('div')(({ theme }) => ({ + position: 'fixed', + top: 0, + right: 0, + width: '496px', + height: '100vh', + opacity: 1, + backgroundColor: theme.palette.primary.main, + zIndex: theme.zIndex.sticky, + + '&::before': { + content: '""', + position: 'fixed', + top: 0, + right: '496px', + width: '100vw', + height: '100vh', + backgroundColor: 'rgba(32, 32, 33, 0.40)', + }, +})); + +export const StyledContent = styled('div')(({ theme }) => ({ + display: 'flex', + padding: theme.spacing(6), + flexDirection: 'column', + height: '100vh', + justifyContent: 'center', + alignItems: 'center', + gap: theme.spacing(8.5), + alignSelf: 'stretch', +})); + +export const StyledTitle = styled(Box)(({ theme }) => ({ + color: '#fff', + fontSize: theme.spacing(3), + fontWeight: 400, + lineHeight: theme.spacing(2.5), +})); + +export const StyledForm = styled(Box)(({ theme }) => ({ + display: 'flex', + width: '400px', + padding: theme.spacing(3), + flexDirection: 'column', + gap: theme.spacing(3), + alignItems: 'flex-start', + border: `1px solid ${theme.palette.divider}`, + borderRadius: theme.spacing(1.5), + borderColor: 'rgba(0, 0, 0, 0.12)', + backgroundColor: '#fff', + boxShadow: '0px 4px 4px 0px rgba(0, 0, 0, 0.12)', +})); + +export const FormTitle = styled(Box)(({ theme }) => ({ + color: theme.palette.text.primary, + fontSize: theme.spacing(2), + lineHeight: theme.spacing(2.75), + fontWeight: theme.typography.fontWeightBold, +})); + +export const FeedbackComponent = () => { + const { feedbackData, showFeedback, closeFeedback } = useFeedback(); + + if (!feedbackData) return null; + + return ( + + + Help us to improve Unleash + + + How easy wasy it to configure the strategy? + + + + + + } + /> + ); +}; diff --git a/frontend/src/component/feedbackNew/FeedbackContext.ts b/frontend/src/component/feedbackNew/FeedbackContext.ts new file mode 100644 index 0000000000..5b8e7c9dfe --- /dev/null +++ b/frontend/src/component/feedbackNew/FeedbackContext.ts @@ -0,0 +1,34 @@ +import { createContext } from 'react'; +import { ProvideFeedbackSchema } from '../../openapi'; + +interface IFeedbackContext { + feedbackData: ProvideFeedbackSchema; + openFeedback: (data: ProvideFeedbackSchema) => void; + closeFeedback: () => void; + showFeedback: boolean; + setShowFeedback: (visible: boolean) => void; +} + +export const DEFAULT_FEEDBACK_DATA = { + category: 'general', +}; + +const setShowFeedback = () => { + throw new Error('setShowFeedback called outside FeedbackContext'); +}; + +const openFeedback = () => { + throw new Error('openFeedback called outside FeedbackContext'); +}; + +const closeFeedback = () => { + throw new Error('closeFeedback called outside FeedbackContext'); +}; + +export const FeedbackContext = createContext({ + feedbackData: DEFAULT_FEEDBACK_DATA, + showFeedback: true, + setShowFeedback: setShowFeedback, + openFeedback: openFeedback, + closeFeedback: closeFeedback, +}); diff --git a/frontend/src/component/feedbackNew/FeedbackProvider.tsx b/frontend/src/component/feedbackNew/FeedbackProvider.tsx new file mode 100644 index 0000000000..d06a2a7037 --- /dev/null +++ b/frontend/src/component/feedbackNew/FeedbackProvider.tsx @@ -0,0 +1,36 @@ +import { FeedbackComponent } from './FeedbackComponent'; +import { DEFAULT_FEEDBACK_DATA, FeedbackContext } from './FeedbackContext'; +import { FC, useState } from 'react'; +import { ProvideFeedbackSchema } from '../../openapi'; + +export const FeedbackProvider: FC = ({ children }) => { + const [feedbackData, setFeedbackData] = useState( + DEFAULT_FEEDBACK_DATA, + ); + + const [showFeedback, setShowFeedback] = useState(false); + const openFeedback = (data: ProvideFeedbackSchema) => { + setFeedbackData(data); + setShowFeedback(true); + }; + + const closeFeedback = () => { + setFeedbackData(DEFAULT_FEEDBACK_DATA); + setShowFeedback(false); + }; + + return ( + + {children} + + + ); +}; diff --git a/frontend/src/component/feedbackNew/useFeedback.tsx b/frontend/src/component/feedbackNew/useFeedback.tsx new file mode 100644 index 0000000000..baf26a9740 --- /dev/null +++ b/frontend/src/component/feedbackNew/useFeedback.tsx @@ -0,0 +1,10 @@ +import { FeedbackContext } from './FeedbackContext'; +import { useContext } from 'react'; + +export const useFeedback = () => { + const context = useContext(FeedbackContext); + if (!context) { + throw new Error('useFeedback must be used within a FeedbackProvider'); + } + return context; +}; diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index 165d396075..777af87ebe 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -16,6 +16,7 @@ import { AnnouncerProvider } from 'component/common/Announcer/AnnouncerProvider/ import { InstanceStatus } from 'component/common/InstanceStatus/InstanceStatus'; import { UIProviderContainer } from 'component/providers/UIProvider/UIProviderContainer'; import { StickyProvider } from 'component/common/Sticky/StickyProvider'; +import { FeedbackProvider } from './component/feedbackNew/FeedbackProvider'; window.global ||= window; @@ -26,14 +27,16 @@ ReactDOM.render( - - - - - - - - + + + + + + + + + +