Skip to content

Commit

Permalink
Merge pull request #64 from squidit/feature/sq-66871-front-fazer-um-a…
Browse files Browse the repository at this point in the history
…juste-na-validacao-do-modal-de-custo-por-conteudo

SQ-66871 [front] fazer um ajuste na validação do modal de custo por conteúdo
  • Loading branch information
htamagnus authored Nov 11, 2024
2 parents c3b6a36 + 5afa36e commit 08c6e27
Show file tree
Hide file tree
Showing 30 changed files with 2,410 additions and 3,309 deletions.
4,768 changes: 1,459 additions & 3,309 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,7 @@ export * from './sq-toggle-checkbox'
export * from './sq-toggle-checkbox-group'
export * from './sq-vertical-bar-chart'
export * from './sq-chart-line'
export * from './sq-modal-profile-cache'
export * from './sq-modal-footer'
export * from './sq-card-profile'
export * from './sq-form-profile-cache'
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
'use client'

import SqCardProfile from '../sq-card-profile.component'
import { socialNetworkMock } from '../../../mocks/sq-social-networks.mock'

const SqCardProfileExample: React.FC = () => {
const type = 'instagram'

return (
<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '200px',
}}
>
<SqCardProfile socialNetworkObject={socialNetworkMock} type={type} />
</div>
)
}

export default SqCardProfileExample
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Meta, StoryObj } from '@storybook/react'
import SqCardProfileExample from './sq-card-profile.component.example'

const meta: Meta<typeof SqCardProfileExample> = {
title: 'Components/SqCardProfile',
parameters: {
docs: {
description: {
component:
'The SqCardProfile component displays profile information for a specific social network. It shows the profile picture, username, and social network icon. Additionally, it includes a section for updating values with an icon and description.',
},
},
},
component: SqCardProfileExample,
tags: ['autodocs'],
}

export default meta
type Story = StoryObj<typeof SqCardProfileExample>

export const Default: Story = {
args: {
labelPin: 'Pin',
percentage: false,
pinValue: 50,
total: 100,
value: 75,
},
argTypes: {
colorBar: {
control: {
type: 'color',
},
},
},
}
1 change: 1 addition & 0 deletions src/components/sq-card-profile/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as SqCardProfile } from './sq-card-profile.component'
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
.card-profile {
border: 1px solid var(--border_color);

.header-card {
.first-block {
img {
max-width: 30px;
width: 100%;
border-radius: 50%;
}
}

.social-icon {
max-width: 25px;
width: 100%;
max-height: 25px;
height: 100%;
}
}

.main-card {
background-color: var(--background);
}
}

42 changes: 42 additions & 0 deletions src/components/sq-card-profile/sq-card-profile.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { useTranslation } from 'react-i18next'

import { useMemo } from 'react'
import './sq-card-profile.component.scoped.scss'
import { SocialNetworksAvailables } from '@/src/interfaces/sq-profile-cache.interface'
import { Instagram, TikTok, Twitter, Youtube } from '@/src/interfaces'

interface Props {
socialNetworkObject: Instagram | Youtube | Twitter | TikTok
type: SocialNetworksAvailables
}

export default ({ socialNetworkObject, type }: Props) => {
const { t } = useTranslation('sqModalProfileCache')
const socialNetwork = useMemo(() => (type === 'facebook' ? 'instagram' : type), [type])

return (
<div className="card-profile mt-3">
<header className="header-card display-flex justify-content-space-between align-items-center p-3">
<div className="first-block display-flex align-items-center">
<figure className="display-flex">
<img className="mr-2" src={socialNetworkObject?.picture} alt="Profile" />
</figure>
<span className="username text-bold big">{socialNetworkObject?.username}</span>
</div>
<div
className="social-icon display-flex justify-content-center align-items-center p-2 rounded"
style={{ backgroundColor: `var(--${socialNetwork})` }}
>
<i className={`fa-brands fa-${socialNetwork} white small`}></i>
</div>
</header>
<main className="main-card p-3">
<div className="title display-flex align-items-center py-2">
<i className="fa-solid fa-diamond-exclamation gold mr-2 big"></i>
<h6 className="m-0">{t('updateValues')}</h6>
</div>
<p className="description">{t('description')}</p>
</main>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
'use client'

import { useState } from 'react'
import SqFormProfileCache from '../sq-form-profile-cache.component'

const SqFormProfileCacheExample: React.FC = () => {
const fieldsCache = ['posts', 'reels', 'stories']

const [state, setState] = useState<Record<string, string>>({
field1: '',
field2: '',
})

const onSubmit = () => {
alert(state)
}

const onChange = (field: string, value: string) => {
setState((prevState) => ({ ...prevState, [field]: value }))
}

return (
<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '200px',
}}
>
<SqFormProfileCache fieldsCache={fieldsCache} onSubmit={onSubmit} onChange={onChange} state={state} />
</div>
)
}

export default SqFormProfileCacheExample
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Meta, StoryObj } from '@storybook/react'
import SqFormProfileCacheExample from './sq-form-profile-cache.component.example'

const meta: Meta<typeof SqFormProfileCacheExample> = {
title: 'Components/SqFormProfileCache',
parameters: {
docs: {
description: {
component:
'The SqFormProfileCache component is a form used to update cache values for different social network fields. It displays input fields for each cache field, allowing users to enter values. The component also applies a money mask to the input values.',
},
},
},
component: SqFormProfileCacheExample,
tags: ['autodocs'],
}

export default meta
type Story = StoryObj<typeof SqFormProfileCacheExample>

export const Default: Story = {
args: {
labelPin: 'Pin',
percentage: false,
pinValue: 50,
total: 100,
value: 75,
},
argTypes: {
colorBar: {
control: {
type: 'color',
},
},
},
}
1 change: 1 addition & 0 deletions src/components/sq-form-profile-cache/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as SqFormProfileCache } from './sq-form-profile-cache.component'
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import { SqInput } from '../inputs/sq-input'
import { CacheField } from '@/src/interfaces/sq-profile-cache.interface'

interface Props {
fieldsCache: CacheField[]
onSubmit: () => void
onChange: (field: CacheField, value: string) => void
state: Record<CacheField, string>
}

export default ({ fieldsCache, onSubmit, onChange, state }: Props) => {
const { t } = useTranslation('sqModalProfileCache')

const moneyMask = (value: string) => {
if (!value || value === '') {
return '0,00'
}

value = value?.replace('.', '')?.replace(',', '')?.replace(/\D/g, '')

const options = { minimumFractionDigits: 2 }
const result = new Intl.NumberFormat('pt-BR', options).format(parseFloat(value) / 100)

return result
}

const handleChange = useCallback(
(field: CacheField, value: string) => {
if (onChange && typeof onChange === 'function') {
onChange(field, value)
}
},
[onChange],
)

return (
<form
className="form-profile-cache mt-5"
onSubmit={(e) => {
e.preventDefault()
onSubmit()
}}
>
{fieldsCache?.map((field, i) => (
<SqInput
key={`${field}-${i}`}
label={t(`labels.${field}`, { count: 1 })}
leftLabel={'R$'}
value={moneyMask(state[field])}
onChange={(value: string) => handleChange(field, value)}
/>
))}
</form>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
'use client'

import SqModalFooter from '../sq-modal-footer.component'

const SqModalFooterExample: React.FC = () => {
const handleClose = () => {
alert('Modal closed')
}

const handleSubmit = () => {
alert('Form submitted')
}

const hasValueFilled = true
const hasChangedValues = true

return (
<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '100px',
}}
>
<SqModalFooter hasValueFilled={hasValueFilled} hasChangedValues={hasChangedValues} onClose={handleClose} onSubmit={handleSubmit} />
</div>
)
}

export default SqModalFooterExample
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Meta, StoryObj } from '@storybook/react'
import { fn } from '@storybook/test'
import SqModalFooterExample from './sq-modal-footer.component.example'

const meta: Meta<typeof SqModalFooterExample> = {
title: 'Components/SqModalFooter',
component: SqModalFooterExample,
parameters: {
docs: {
description: {
component:
'The SqModalFooter component is a footer for modals that includes buttons for canceling and submitting changes. It handles the state of the buttons based on whether values have been filled and changed.',
},
},
},
tags: ['autodocs'],
}

export default meta
type Story = StoryObj<typeof SqModalFooterExample>

export const Default: Story = {
args: {
children: 'Content',
header: 'Title',
onOpenChange: fn(),
},
}
1 change: 1 addition & 0 deletions src/components/sq-modal-footer/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as SqModalFooter } from './sq-modal-footer.component'
3 changes: 3 additions & 0 deletions src/components/sq-modal-footer/sq-modal-footer.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
footer {
width: 100%;
}
45 changes: 45 additions & 0 deletions src/components/sq-modal-footer/sq-modal-footer.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { useCallback } from 'react'
import { useTranslation } from 'react-i18next'

import { SqButton } from '../buttons/sq-button'
import './sq-modal-footer.component.scss'

interface Props {
hasValueFilled: boolean
hasChangedValues: boolean
onClose: () => void
onSubmit?: () => void
}

export default ({ onClose, hasChangedValues, hasValueFilled, onSubmit }: Props) => {
const { t } = useTranslation('sqModalProfileCache')

const handleSubmit = useCallback(() => {
if (onSubmit && typeof onSubmit === 'function') {
onSubmit()
}
}, [onSubmit])

const handleClose = useCallback(() => {
if (onClose && typeof onClose === 'function') {
onClose()
}
}, [onClose])

return (
<footer className="display-flex justify-content-space-between align-items-center">
<SqButton
color="transparent"
borderColor="var(--gray)"
textColor="var(--gray)"
style={{ borderWidth: '1px' }}
onClick={() => handleClose()}
>
{t('cancel')}
</SqButton>
<SqButton disabled={!hasValueFilled || !hasChangedValues} onClick={() => handleSubmit()}>
{t('save')}
</SqButton>
</footer>
)
}
Loading

0 comments on commit 08c6e27

Please sign in to comment.