diff --git a/frontend/webapp/containers/main/actions/choose-action-body/index.tsx b/frontend/webapp/containers/main/actions/choose-action-body/index.tsx index 12550a740..5ce4e78c3 100644 --- a/frontend/webapp/containers/main/actions/choose-action-body/index.tsx +++ b/frontend/webapp/containers/main/actions/choose-action-body/index.tsx @@ -3,7 +3,7 @@ import styled from 'styled-components'; import { type ActionInput } from '@/types'; import ActionCustomFields from './custom-fields'; import { type ActionOption } from '../choose-action-modal/action-options'; -import { DocsButton, Input, Text, TextArea, Toggle, MonitoringCheckboxes, SectionTitle } from '@/reuseable-components'; +import { DocsButton, Input, Text, TextArea, MonitoringCheckboxes, SectionTitle, ToggleButtons } from '@/reuseable-components'; const FieldWrapper = styled.div` width: 100%; @@ -27,34 +27,19 @@ const ChooseActionBody: React.FC = ({ isUpdate, action {isUpdate && ( Status - handleFormChange('disable', !bool)} - /> + handleFormChange('disable', !bool)} /> )} - {!isUpdate && ( - } /> - )} + {!isUpdate && } />} - handleFormChange('signals', value)} - /> + handleFormChange('signals', value)} /> {!isUpdate && ( - handleFormChange('name', value)} - /> + handleFormChange('name', value)} /> )} diff --git a/frontend/webapp/containers/main/instrumentation-rules/choose-rule-body/index.tsx b/frontend/webapp/containers/main/instrumentation-rules/choose-rule-body/index.tsx index d4e29eb1d..0e2070eb1 100644 --- a/frontend/webapp/containers/main/instrumentation-rules/choose-rule-body/index.tsx +++ b/frontend/webapp/containers/main/instrumentation-rules/choose-rule-body/index.tsx @@ -3,7 +3,7 @@ import styled from 'styled-components'; import RuleCustomFields from './custom-fields'; import type { InstrumentationRuleInput } from '@/types'; import type { RuleOption } from '../add-rule-modal/rule-options'; -import { DocsButton, Input, Text, TextArea, Toggle, SectionTitle } from '@/reuseable-components'; +import { DocsButton, Input, Text, TextArea, SectionTitle, ToggleButtons } from '@/reuseable-components'; const FieldWrapper = styled.div` width: 100%; @@ -27,11 +27,7 @@ const ChooseRuleBody: React.FC = ({ isUpdate, rule, formData, handleFormC {isUpdate && ( Status - handleFormChange('disabled', !bool)} - /> + handleFormChange('disabled', !bool)} /> )} @@ -39,12 +35,7 @@ const ChooseRuleBody: React.FC = ({ isUpdate, rule, formData, handleFormC {!isUpdate && ( - handleFormChange('ruleName', value)} - /> + handleFormChange('ruleName', value)} /> )} diff --git a/frontend/webapp/public/icons/common/circled-check.svg b/frontend/webapp/public/icons/common/circled-check.svg new file mode 100644 index 000000000..b5db32751 --- /dev/null +++ b/frontend/webapp/public/icons/common/circled-check.svg @@ -0,0 +1,8 @@ + + + \ No newline at end of file diff --git a/frontend/webapp/public/icons/common/circled-cross.svg b/frontend/webapp/public/icons/common/circled-cross.svg new file mode 100644 index 000000000..72ed2097e --- /dev/null +++ b/frontend/webapp/public/icons/common/circled-cross.svg @@ -0,0 +1,8 @@ + + + \ No newline at end of file diff --git a/frontend/webapp/reuseable-components/index.ts b/frontend/webapp/reuseable-components/index.ts index b8e7357ee..34ee3e82b 100644 --- a/frontend/webapp/reuseable-components/index.ts +++ b/frontend/webapp/reuseable-components/index.ts @@ -8,6 +8,7 @@ export * from './dropdown'; export * from './divider'; export * from './counter'; export * from './toggle'; +export * from './toggle-buttons'; export * from './checkbox'; export * from './modal'; export * from './modal/warning-modal'; diff --git a/frontend/webapp/reuseable-components/toggle-buttons/index.tsx b/frontend/webapp/reuseable-components/toggle-buttons/index.tsx new file mode 100644 index 000000000..b051a6ef3 --- /dev/null +++ b/frontend/webapp/reuseable-components/toggle-buttons/index.tsx @@ -0,0 +1,97 @@ +import Image from 'next/image'; +import { Tooltip } from '../tooltip'; +import styled from 'styled-components'; +import React, { useEffect, useState } from 'react'; + +interface ToggleProps { + activeText?: string; + inactiveText?: string; + tooltip?: string; + initialValue?: boolean; + onChange?: (value: boolean) => void; + disabled?: boolean; +} + +const Container = styled.div` + width: 100%; + display: flex; + align-items: center; +`; + +const BaseButton = styled.button` + width: 100%; + padding: 12px; + gap: 4px; + display: flex; + align-items: center; + justify-content: center; + border: 1px solid ${({ theme }) => theme.colors.border}; + color: ${({ theme }) => theme.colors.secondary}; + font-family: ${({ theme }) => theme.font_family.secondary}; + font-size: 14px; + text-decoration: underline; + text-transform: uppercase; + cursor: ${({ disabled }) => (disabled ? 'not-allowed' : 'pointer')}; + opacity: ${({ disabled }) => (disabled ? 0.6 : 1)}; +`; + +const ActiveButton = styled(BaseButton)` + border-radius: 32px 0 0 32px; + background-color: ${({ theme }) => theme.colors.blank_background}; + &.colored { + background-color: ${({ theme }) => theme.colors.dark_green}; + } + &:hover { + border-color: ${({ theme }) => theme.colors.secondary}; + } + transition: background-color 0.3s; +`; + +const InactiveButton = styled(BaseButton)` + border-radius: 0 32px 32px 0; + background-color: ${({ theme }) => theme.colors.blank_background}; + &.colored { + background-color: ${({ theme }) => theme.colors.darker_red}; + } + &:hover { + border-color: ${({ theme }) => theme.colors.secondary}; + } + transition: background-color 0.3s; +`; + +const ToggleButtons: React.FC = ({ activeText = 'Active', inactiveText = 'Inactive', tooltip, initialValue = false, onChange, disabled }) => { + const [isActive, setIsActive] = useState(initialValue); + useEffect(() => setIsActive(initialValue), [initialValue]); + + const handleToggle = (forcedBool?: boolean) => { + if (disabled) return; + + let newValue = initialValue; + + setIsActive((prev) => { + newValue = typeof forcedBool === 'boolean' ? forcedBool : !prev; + return newValue; + }); + + if (onChange) onChange(newValue); + }; + + return ( + + + handleToggle(true)} disabled={disabled}> + + {activeText} + + handleToggle(false)} disabled={disabled}> + + {inactiveText} + + + + {tooltip && } + + ); +}; + +export { ToggleButtons }; diff --git a/frontend/webapp/reuseable-components/toggle/index.tsx b/frontend/webapp/reuseable-components/toggle/index.tsx index fa1cc5b0f..719fbfc8a 100644 --- a/frontend/webapp/reuseable-components/toggle/index.tsx +++ b/frontend/webapp/reuseable-components/toggle/index.tsx @@ -46,19 +46,19 @@ const ToggleSwitch = styled.div<{ isActive: boolean; disabled?: boolean }>` const Toggle: React.FC = ({ title, tooltip, initialValue = false, onChange, disabled }) => { const [isActive, setIsActive] = useState(initialValue); - - useEffect(() => { - setIsActive(initialValue); - }, [initialValue]); + useEffect(() => setIsActive(initialValue), [initialValue]); const handleToggle = () => { - if (!disabled) { - const newValue = !isActive; - setIsActive(newValue); - if (onChange) { - onChange(newValue); - } - } + if (disabled) return; + + let newValue = initialValue; + + setIsActive((prev) => { + newValue = !prev; + return newValue; + }); + + if (onChange) onChange(newValue); }; return ( @@ -66,8 +66,9 @@ const Toggle: React.FC = ({ title, tooltip, initialValue = false, o {title} - {tooltip && } + + {tooltip && } ); }; diff --git a/frontend/webapp/styles/theme.ts b/frontend/webapp/styles/theme.ts index cdd988e2a..715f46ec3 100644 --- a/frontend/webapp/styles/theme.ts +++ b/frontend/webapp/styles/theme.ts @@ -15,7 +15,8 @@ const colors = { blank_background: '#11111100', dark_red: '#802828', - dark_green: '#2d4323', + darker_red: '#611F1F', + dark_green: '#2D4323', warning: '#472300', error: '#431919',