Skip to content

Commit

Permalink
move widget customization into customization panel
Browse files Browse the repository at this point in the history
  • Loading branch information
liyiy committed Dec 12, 2023
1 parent 1543f27 commit cc37737
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 153 deletions.
202 changes: 124 additions & 78 deletions frontend/src/scenes/surveys/SurveyAppearance.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import './SurveyAppearance.scss'

import { LemonButton, LemonCheckbox, LemonInput, Link } from '@posthog/lemon-ui'
import { LemonButton, LemonCheckbox, LemonInput, LemonSelect, Link } from '@posthog/lemon-ui'
import { useValues } from 'kea'
import { PayGateMini } from 'lib/components/PayGateMini/PayGateMini'
import React, { useEffect, useRef, useState } from 'react'
Expand Down Expand Up @@ -46,6 +46,8 @@ interface CustomizationProps {
onAppearanceChange: (appearance: SurveyAppearanceType) => void
}

interface WidgetCustomizationProps extends Omit<CustomizationProps, 'surveyQuestionItem'> {}

interface ButtonProps {
link?: string | null
type?: SurveyQuestionType
Expand Down Expand Up @@ -134,93 +136,137 @@ export function SurveyAppearance({
export function Customization({ appearance, surveyQuestionItem, onAppearanceChange }: CustomizationProps): JSX.Element {
const { whitelabelAvailable, surveysStylingAvailable } = useValues(surveysLogic)
return (
<div className="flex flex-col">
{!surveysStylingAvailable && (
<PayGateMini feature={AvailableFeature.SURVEYS_STYLING}>
<></>
</PayGateMini>
)}
<div className="mt-2">Background color</div>
<LemonInput
value={appearance?.backgroundColor}
onChange={(backgroundColor) => onAppearanceChange({ ...appearance, backgroundColor })}
disabled={!surveysStylingAvailable}
/>
<div className="mt-2">Border color</div>
<LemonInput
value={appearance?.borderColor || defaultSurveyAppearance.borderColor}
onChange={(borderColor) => onAppearanceChange({ ...appearance, borderColor })}
disabled={!surveysStylingAvailable}
/>
<>
<div className="mt-2">Position</div>
<div className="flex gap-1">
{['left', 'center', 'right'].map((position) => {
return (
<LemonButton
key={position}
type="tertiary"
onClick={() => onAppearanceChange({ ...appearance, position })}
active={appearance.position === position}
disabledReason={
surveysStylingAvailable
? null
: 'Subscribe to surveys to customize survey position.'
}
>
{position}
</LemonButton>
)
})}
</div>
</>
{surveyQuestionItem.type === SurveyQuestionType.Rating && (
<>
<div className="flex flex-col">
{!surveysStylingAvailable && (
<PayGateMini feature={AvailableFeature.SURVEYS_STYLING}>
<></>
</PayGateMini>
)}
<div className="mt-2">Background color</div>
<LemonInput
value={appearance?.backgroundColor}
onChange={(backgroundColor) => onAppearanceChange({ ...appearance, backgroundColor })}
disabled={!surveysStylingAvailable}
/>
<div className="mt-2">Border color</div>
<LemonInput
value={appearance?.borderColor || defaultSurveyAppearance.borderColor}
onChange={(borderColor) => onAppearanceChange({ ...appearance, borderColor })}
disabled={!surveysStylingAvailable}
/>
<>
<div className="mt-2">Rating button color</div>
<LemonInput
value={appearance?.ratingButtonColor}
onChange={(ratingButtonColor) => onAppearanceChange({ ...appearance, ratingButtonColor })}
disabled={!surveysStylingAvailable}
<div className="mt-2">Position</div>
<div className="flex gap-1">
{['left', 'center', 'right'].map((position) => {
return (
<LemonButton
key={position}
type="tertiary"
onClick={() => onAppearanceChange({ ...appearance, position })}
active={appearance.position === position}
disabledReason={
surveysStylingAvailable
? null
: 'Subscribe to surveys to customize survey position.'
}
>
{position}
</LemonButton>
)
})}
</div>
</>
{surveyQuestionItem.type === SurveyQuestionType.Rating && (
<>
<div className="mt-2">Rating button color</div>
<LemonInput
value={appearance?.ratingButtonColor}
onChange={(ratingButtonColor) => onAppearanceChange({ ...appearance, ratingButtonColor })}
disabled={!surveysStylingAvailable}
/>
<div className="mt-2">Rating button active color</div>
<LemonInput
value={appearance?.ratingButtonActiveColor}
onChange={(ratingButtonActiveColor) =>
onAppearanceChange({ ...appearance, ratingButtonActiveColor })
}
disabled={!surveysStylingAvailable}
/>
</>
)}
<div className="mt-2">Button color</div>
<LemonInput
value={appearance?.submitButtonColor}
onChange={(submitButtonColor) => onAppearanceChange({ ...appearance, submitButtonColor })}
disabled={!surveysStylingAvailable}
/>
{surveyQuestionItem.type === SurveyQuestionType.Open && (
<>
<div className="mt-2">Placeholder</div>
<LemonInput
value={appearance?.placeholder || defaultSurveyAppearance.placeholder}
onChange={(placeholder) => onAppearanceChange({ ...appearance, placeholder })}
disabled={!surveysStylingAvailable}
/>
</>
)}
<div className="mt-2">
<LemonCheckbox
label={
<div className="flex items-center">
<span>Hide PostHog branding</span>
</div>
}
onChange={(checked) => onAppearanceChange({ ...appearance, whiteLabel: checked })}
checked={appearance?.whiteLabel}
disabledReason={
!whitelabelAvailable ? 'Upgrade to any paid plan to hide PostHog branding' : null
}
/>
<div className="mt-2">Rating button active color</div>
</div>
</div>
</>
)
}

export function WidgetCustomization({ appearance, onAppearanceChange }: WidgetCustomizationProps): JSX.Element {
return (
<>
<div className="mt-2">Widget type</div>
<LemonSelect
value={appearance.widgetType}
onChange={(widgetType) => onAppearanceChange({ ...appearance, widgetType })}
options={[
{ label: 'Embedded tab', value: 'tab' },
{ label: 'Custom', value: 'selector' },
]}
/>
{appearance.widgetType === 'selector' ? (
<>
<div className="mt-2">Widget selector</div>
<LemonInput
value={appearance?.ratingButtonActiveColor}
onChange={(ratingButtonActiveColor) =>
onAppearanceChange({ ...appearance, ratingButtonActiveColor })
}
disabled={!surveysStylingAvailable}
value={appearance.widgetSelector}
onChange={(widgetSelector) => onAppearanceChange({ ...appearance, widgetSelector })}
placeholder="ex: .feedback-button"
/>
</>
)}
<div className="mt-2">Button color</div>
<LemonInput
value={appearance?.submitButtonColor}
onChange={(submitButtonColor) => onAppearanceChange({ ...appearance, submitButtonColor })}
disabled={!surveysStylingAvailable}
/>
{surveyQuestionItem.type === SurveyQuestionType.Open && (
) : (
<>
<div className="mt-2">Placeholder</div>
<div className="mt-2">Widget label</div>
<LemonInput
value={appearance.widgetLabel}
onChange={(widgetLabel) => onAppearanceChange({ ...appearance, widgetLabel })}
/>
<div className="mt-2">Widget color</div>
<LemonInput
value={appearance?.placeholder || defaultSurveyAppearance.placeholder}
onChange={(placeholder) => onAppearanceChange({ ...appearance, placeholder })}
disabled={!surveysStylingAvailable}
value={appearance.widgetColor}
onChange={(widgetColor) => onAppearanceChange({ ...appearance, widgetColor })}
placeholder="#e0a045"
/>
</>
)}
<div className="mt-2">
<LemonCheckbox
label={
<div className="flex items-center">
<span>Hide PostHog branding</span>
</div>
}
onChange={(checked) => onAppearanceChange({ ...appearance, whiteLabel: checked })}
checked={appearance?.whiteLabel}
disabledReason={!whitelabelAvailable ? 'Upgrade to any paid plan to hide PostHog branding' : null}
/>
</div>
</div>
</>
)
}

Expand Down
98 changes: 23 additions & 75 deletions frontend/src/scenes/surveys/SurveyEdit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { LinkSurveyQuestion, RatingSurveyQuestion, SurveyQuestion, SurveyType, S

import { defaultSurveyAppearance, defaultSurveyFieldValues, SurveyUrlMatchTypeLabels } from './constants'
import { SurveyAPIEditor } from './SurveyAPIEditor'
import { Customization, SurveyAppearance } from './SurveyAppearance'
import { Customization, SurveyAppearance, WidgetCustomization } from './SurveyAppearance'
import { HTMLEditor, PresentationTypeCard } from './SurveyAppearanceUtils'
import { SurveyEditQuestionGroup, SurveyEditQuestionHeader } from './SurveyEditQuestionRow'
import { SurveyFormAppearance } from './SurveyFormAppearance'
Expand Down Expand Up @@ -144,73 +144,6 @@ export default function SurveyEdit(): JSX.Element {
</Field>
),
},
...(survey.type === SurveyType.Widget
? [
{
key: SurveyEditSection.Widget,
header: 'Widget',
content: (
<>
<PureField label="Widget type">
<LemonSelect
value={survey.appearance.widgetType}
onChange={(val) =>
setSurveyValue('appearance', {
...survey.appearance,
widgetType: val,
})
}
options={[
{ label: 'Tab', value: 'tab' },
{ label: 'Custom widget', value: 'selector' },
]}
/>
</PureField>
{survey.appearance.widgetType === 'selector' ? (
<PureField label="Custom selector" className="mt-4">
<LemonInput
value={survey.appearance.widgetSelector}
onChange={(widgetSelector) =>
setSurveyValue('appearance', {
...survey.appearance,
widgetSelector,
})
}
placeholder="ex: .feedback-button"
/>
</PureField>
) : (
<>
<PureField label="Label" className="mt-4">
<LemonInput
value={survey.appearance.widgetLabel}
onChange={(widgetLabel) =>
setSurveyValue('appearance', {
...survey.appearance,
widgetLabel,
})
}
/>
</PureField>
<PureField label="Background color" className="mt-4">
<LemonInput
value={survey.appearance.widgetColor}
onChange={(widgetColor) =>
setSurveyValue('appearance', {
...survey.appearance,
widgetColor,
})
}
placeholder="ex: #000000"
/>
</PureField>
</>
)}
</>
),
},
]
: []),
{
key: SurveyEditSection.Steps,
header: 'Steps',
Expand Down Expand Up @@ -413,13 +346,28 @@ export default function SurveyEdit(): JSX.Element {
content: (
<Field name="appearance" label="">
{({ value, onChange }) => (
<Customization
appearance={value || defaultSurveyAppearance}
surveyQuestionItem={survey.questions[0]}
onAppearanceChange={(appearance) => {
onChange(appearance)
}}
/>
<>
{survey.type === SurveyType.Widget && (
<>
<div className="font-bold">Widget customization</div>
<WidgetCustomization
appearance={value || defaultSurveyAppearance}
onAppearanceChange={(appearance) => {
onChange(appearance)
}}
/>
<LemonDivider className="mt-4" />
<div className="font-bold">Survey customization</div>
</>
)}
<Customization
appearance={value || defaultSurveyAppearance}
surveyQuestionItem={survey.questions[0]}
onAppearanceChange={(appearance) => {
onChange(appearance)
}}
/>
</>
)}
</Field>
),
Expand Down

0 comments on commit cc37737

Please sign in to comment.