fixed tabs

This commit is contained in:
Anton Tranelis 2025-04-17 19:25:00 +01:00
parent 9bfe7c6963
commit 73417c9086
10 changed files with 210 additions and 207 deletions

View File

@ -24,7 +24,7 @@ export function AppShell({
}) {
return (
<ContextWrapper>
<div className='tw-flex tw-flex-col tw-h-full'>
<div className='tw:flex tw:flex-col tw:h-full'>
<SetAppState
assetsApi={assetsApi}
embedded={embedded}

View File

@ -91,6 +91,7 @@ export const Autocomplete = ({
onChange={(e) => handleChange(e)}
tabIndex='-1'
onKeyDown={handleKeyDown}
className='tw:border-none tw:focus:outline-none tw:focus:ring-0 tw:mt-5'
/>
<ul
className={`tw:absolute tw:z-4000 ${filteredSuggestions.length > 0 && 'tw:bg-base-100 tw:rounded-xl tw:p-2'}`}

View File

@ -203,9 +203,9 @@ export function ProfileForm() {
></TabsForm>
)}
<div className='tw:mt-4'>
<div className='tw:mt-4 tw:flex-none'>
<button
className={loading ? ' tw:loading tw:btn tw:float-right' : 'tw:btn tw:float-right'}
className={`${loading ? ' tw:loading tw:btn tw:float-right' : 'tw:btn tw:float-right'}`}
type='submit'
style={{
// We could refactor this, it is used several times at different locations

View File

@ -54,7 +54,7 @@ export function ActionButton({
<>
{hasUserPermission(collection, 'update', item) && (
<>
<div className={`tw:absolute tw:right-4 tw:bottom-4 tw:flex tw:flex-col ${customStyle}`}>
<div className={`tw:absolute tw:right-6 tw:bottom-4 tw:flex tw:flex-col ${customStyle}`}>
{triggerItemSelected && (
<button
tabIndex={0}

View File

@ -12,11 +12,11 @@ export const CrowdfundingForm = ({
setState: React.Dispatch<React.SetStateAction<any>>
}) => {
return (
<div className='tw-mt-4 tw-space-y-4'>
<div className='tw:mt-4 tw:space-y-4'>
<div>
<label
htmlFor='OpenCollectiveSlug'
className='tw-block tw-text-sm tw-font-medium tw-text-gray-500 tw-mb-1'
className='tw:block tw:text-sm tw:font-medium tw:text-gray-500 tw:mb-1'
>
Open Collective Slug:
</label>

View File

@ -121,18 +121,18 @@ export const CrowdfundingView = ({ item }: { item: Item }) => {
if (loading)
return (
<div className='tw-flex tw-justify-center'>
<span className='tw-loading tw-loading-spinner tw-loading-lg tw-text-neutral-content'></span>
<div className='tw:flex tw:justify-center'>
<span className='tw:loading tw:loading-spinner tw:loading-lg tw:text-neutral-content'></span>
</div>
)
if (error) {
return <p className='tw-text-center tw-text-lg tw-text-red-500'>Error: {error}</p>
return <p className='tw:text-center tw:text-lg tw:text-red-500'>Error: {error}</p>
}
if (!data?.account) {
return (
<p className='tw-text-center tw-text-lg tw-text-red-500'>
<p className='tw:text-center tw:text-lg tw:text-red-500'>
No data available for this account.
</p>
)
@ -144,46 +144,46 @@ export const CrowdfundingView = ({ item }: { item: Item }) => {
const currentBalance = balanceValueInCents
return (
<div className='tw-mx-6 tw-mb-6'>
<div className='tw-card tw-bg-base-200 tw-w-fit tw-max-w-full tw-shadow'>
<div className='tw-stats tw-bg-base-200 tw-stats-horizontal tw-rounded-b-none'>
<div className='tw-stat tw-p-3'>
<div className='tw-stat-title'>Current Balance</div>
<div className='tw-stat-value tw-text-xl lg:tw-text-3xl'>
<div className='tw:mx-6 tw:mb-6'>
<div className='tw:card tw:bg-base-200 tw:w-fit tw:max-w-full tw:shadow'>
<div className='tw:stats tw:bg-base-200 tw:stats-horizontal tw:rounded-b-none'>
<div className='tw:stat tw:p-3'>
<div className='tw:stat-title'>Current Balance</div>
<div className='tw:stat-value tw:text-xl lg:tw:text-3xl'>
{formatCurrency(currentBalance, currency)}
</div>
</div>
<div className='tw-stat tw-p-3'>
<div className='tw-stat-title'>Received</div>
<div className='tw-stat-value tw-text-green-500 tw-text-xl lg:tw-text-3xl'>
<div className='tw:stat tw:p-3'>
<div className='tw:stat-title'>Received</div>
<div className='tw:stat-value tw:text-green-500 tw:text-xl lg:tw:text-3xl'>
{formatCurrency(stats.totalAmountReceived.valueInCents, currency)}
</div>
</div>
<div className='tw-stat tw-p-3'>
<div className='tw-stat-title'>Spent</div>
<div className='tw-stat-value tw-text-red-500 tw-text-xl lg:tw-text-3xl'>
<div className='tw:stat tw:p-3'>
<div className='tw:stat-title'>Spent</div>
<div className='tw:stat-value tw:text-red-500 tw:text-xl lg:tw:text-3xl'>
{formatCurrency(stats.totalAmountReceived.valueInCents - currentBalance, currency)}
</div>
</div>
</div>
<hr></hr>
<div className='tw-m-4 tw-items-center'>
<hr className='tw:border-1 tw:border-current/10 tw:border-dashed'></hr>
<div className='tw:m-4 tw:items-center'>
<a href={`https://opencollective.com/${slug}/donate`} target='_blank' rel='noreferrer'>
<button className='tw-btn tw-btn-sm tw-btn-primary tw-float-right tw-ml-4'>
<button className='tw:btn tw:btn-sm tw:btn-primary tw:float-right tw:ml-4'>
Donate
</button>
</a>
<div className='tw-flex-1 tw-mr-4'>
<div className='tw:flex-1 tw:mr-4'>
Support{' '}
<a
className='tw-font-bold'
className='tw:font-bold'
href={`https://opencollective.com/${slug}`}
target='_blank'
rel='noreferrer'
>
{data.account.name}
</a>{' '}
on <span className='tw-font-bold'>Open&nbsp;Collective</span>
on <span className='tw:font-bold'>Open&nbsp;Collective</span>
</div>
</div>
</div>

View File

@ -10,52 +10,54 @@ import { ColorPicker } from './ColorPicker'
export const FormHeader = ({ item, state, setState }) => {
return (
<div className='tw:flex'>
<AvatarWidget
avatar={state.image}
setAvatar={(i) =>
setState((prevState) => ({
...prevState,
image: i,
}))
}
/>
<ColorPicker
color={state.color}
onChange={(c) =>
setState((prevState) => ({
...prevState,
color: c,
}))
}
className={'tw:-left-6 tw:top-14 tw:-mr-6'}
/>
<div className='tw:grow tw:mr-4 tw:pt-1'>
<TextInput
placeholder='Name'
defaultValue={item?.name ? item.name : ''}
updateFormValue={(v) =>
<div className='tw:flex-none'>
<div className='tw:flex'>
<AvatarWidget
avatar={state.image}
setAvatar={(i) =>
setState((prevState) => ({
...prevState,
name: v,
image: i,
}))
}
containerStyle='tw:grow tw:px-4'
inputStyle='tw:input-md'
/>
<TextInput
placeholder='Subtitle'
required={false}
defaultValue={item?.subname ? item.subname : ''}
updateFormValue={(v) =>
<ColorPicker
color={state.color}
onChange={(c) =>
setState((prevState) => ({
...prevState,
subname: v,
color: c,
}))
}
containerStyle='tw:grow tw:px-4 tw:mt-1'
inputStyle='tw:input-sm'
className={'tw:-left-6 tw:top-14 tw:-mr-6'}
/>
<div className='tw:grow tw:mr-4 tw:pt-1'>
<TextInput
placeholder='Name'
defaultValue={item?.name ? item.name : ''}
updateFormValue={(v) =>
setState((prevState) => ({
...prevState,
name: v,
}))
}
containerStyle='tw:grow tw:px-4'
inputStyle='tw:input-md'
/>
<TextInput
placeholder='Subtitle'
required={false}
defaultValue={item?.subname ? item.subname : ''}
updateFormValue={(v) =>
setState((prevState) => ({
...prevState,
subname: v,
}))
}
containerStyle='tw:grow tw:px-4 tw:mt-1'
inputStyle='tw:input-sm'
/>
</div>
</div>
</div>
)

View File

@ -107,7 +107,7 @@ export const TagsWidget = ({ placeholder, containerStyle, defaultTags, onUpdate
setFocusInput(false)
}, 200)
}}
className={`tw:input tw:input-bordered tw:cursor-text ${containerStyle}`}
className={`tw:textarea tw:cursor-text ${containerStyle}`}
>
<div className='tw:flex tw:flex-wrap tw:h-fit'>
{defaultTags.map((tag) => (

View File

@ -53,55 +53,55 @@ export const TabsForm = ({
}, [location.search])
return (
<div role='tablist' className='tw:tabs tw:tabs-lift tw:mt-3'>
<input
type='radio'
name='my_tabs_2'
role='tab'
className={'tw:tab '}
aria-label='Info'
checked={activeTab === 1 && true}
onChange={() => updateActiveTab(1)}
/>
<div
role='tabpanel'
className='tw:tab-content tw:bg-base-100 tw:border-(--fallback-bc,oklch(var(--bc)/0.2)) tw:rounded-box tw:h-[calc(100dvh-332px)] tw:min-h-56 tw:border-none'
>
<div className='tw:grow'>
<div role='tablist' className='tw:tabs tw:h-full tw:tabs-lift tw:mt-3'>
<input
type='radio'
name='my_tabs_2'
role='tab'
className={'tw:tab '}
aria-label='Info'
checked={activeTab === 1 && true}
onChange={() => updateActiveTab(1)}
/>
<div
className={`tw:flex tw:flex-col tw:h-full ${item.layer.itemType.show_start_end_input && 'tw:pt-4'}`}
role='tabpanel'
className='tw:tab-content tw:bg-base-100 tw:border-(--fallback-bc,oklch(var(--bc)/0.2)) tw:rounded-box tw:!h-[calc(100%-48px)] tw:min-h-56 tw:border-none'
>
{item.layer.itemType.show_start_end_input && (
<PopupStartEndInput
item={item}
showLabels={false}
updateEndValue={(e) =>
setState((prevState) => ({
...prevState,
end: e,
}))
}
updateStartValue={(s) =>
setState((prevState) => ({
...prevState,
start: s,
}))
}
></PopupStartEndInput>
)}
<div
className={`tw:flex tw:flex-col tw:h-full ${item.layer.itemType.show_start_end_input && 'tw:pt-4'}`}
>
{item.layer.itemType.show_start_end_input && (
<PopupStartEndInput
item={item}
showLabels={false}
updateEndValue={(e) =>
setState((prevState) => ({
...prevState,
end: e,
}))
}
updateStartValue={(s) =>
setState((prevState) => ({
...prevState,
start: s,
}))
}
></PopupStartEndInput>
)}
<TextAreaInput
placeholder='about ...'
defaultValue={item?.text ? item.text : ''}
updateFormValue={(v) =>
setState((prevState) => ({
...prevState,
text: v,
}))
}
containerStyle='tw:grow'
inputStyle={`tw:h-full ${!item.layer.itemType.show_start_end_input && 'tw:border-t-0 tw:rounded-tl-none'}`}
/>
<div>
<TextAreaInput
placeholder='about ...'
defaultValue={item?.text ? item.text : ''}
updateFormValue={(v) =>
setState((prevState) => ({
...prevState,
text: v,
}))
}
containerStyle='tw:grow'
inputStyle={`tw:h-full ${!item.layer.itemType.show_start_end_input && 'tw:border-t-0 tw:rounded-tl-none'}`}
/>
<TextAreaInput
placeholder='contact info ...'
defaultValue={state.contact || ''}
@ -111,108 +111,108 @@ export const TabsForm = ({
contact: c,
}))
}
inputStyle='tw:h-24'
containerStyle='tw:pt-4'
inputStyle=''
containerStyle='tw:pt-4 tw:h-24 tw:flex-none'
required={false}
/>
</div>
</div>
</div>
{item.layer?.itemType.offers_and_needs && (
<>
<input
type='radio'
name='my_tabs_2'
role='tab'
className={'tw:tab tw:min-w-[10em] '}
aria-label='Offers & Needs'
checked={activeTab === 3 && true}
onChange={() => updateActiveTab(3)}
/>
<div
role='tabpanel'
className='tw:tab-content tw:bg-base-100 tw:border-(--fallback-bc,oklch(var(--bc)/0.2)) tw:rounded-box tw:h-[calc(100dvh-332px)] tw:min-h-56 tw:border-none'
>
<div className='tw:h-full'>
<div className='tw:w-full tw:h-[calc(50%-0.75em)] tw:mb-4'>
<TagsWidget
defaultTags={state.offers}
onUpdate={(v) =>
setState((prevState) => ({
...prevState,
offers: v,
}))
}
placeholder='enter your offers'
containerStyle='tw:bg-transparent tw:w-full tw:h-full tw:mt-3 tw:text-xs tw:h-[calc(100%-1rem)] tw:min-h-[5em] tw:pb-2 tw:overflow-auto'
/>
</div>
<div className='tw:w-full tw:h-[calc(50%-1.5em)]'>
<TagsWidget
defaultTags={state.needs}
onUpdate={(v) =>
setState((prevState) => ({
...prevState,
needs: v,
}))
}
placeholder='enter your needs'
containerStyle='tw:bg-transparent tw:w-full tw:h-full tw:mt-3 tw:text-xs tw:h-[calc(100%-1rem)] tw:min-h-[5em] tw:pb-2 tw:overflow-auto'
/>
{item.layer?.itemType.offers_and_needs && (
<>
<input
type='radio'
name='my_tabs_2'
role='tab'
className={'tw:tab tw:min-w-[10em] '}
aria-label='Offers & Needs'
checked={activeTab === 3 && true}
onChange={() => updateActiveTab(3)}
/>
<div
role='tabpanel'
className='tw:tab-content tw:bg-base-100 tw:border-(--fallback-bc,oklch(var(--bc)/0.2)) tw:rounded-box tw:!h-[calc(100%-48px)] tw:min-h-56 tw:border-none'
>
<div className='tw:h-full'>
<div className='tw:w-full tw:h-[calc(50%-0.75em)] tw:mb-4'>
<TagsWidget
defaultTags={state.offers}
onUpdate={(v) =>
setState((prevState) => ({
...prevState,
offers: v,
}))
}
placeholder='enter your offers'
containerStyle='tw:bg-transparent tw:w-full tw:h-full tw:mt-3 tw:text-xs tw:h-[calc(100%-1rem)] tw:min-h-[5em] tw:pb-2 tw:overflow-auto'
/>
</div>
<div className='tw:w-full tw:h-[calc(50%-1.5em)]'>
<TagsWidget
defaultTags={state.needs}
onUpdate={(v) =>
setState((prevState) => ({
...prevState,
needs: v,
}))
}
placeholder='enter your needs'
containerStyle='tw:bg-transparent tw:w-full tw:h-full tw:mt-3 tw:text-xs tw:h-[calc(100%-1rem)] tw:min-h-[5em] tw:pb-2 tw:overflow-auto'
/>
</div>
</div>
</div>
</div>
</>
)}
{item.layer?.itemType.relations && (
<>
<input
type='radio'
name='my_tabs_2'
role='tab'
className='tw:tab '
aria-label='Links'
checked={activeTab === 7 && true}
onChange={() => updateActiveTab(7)}
/>
<div
role='tabpanel'
className='tw:tab-content tw:bg-base-100 tw:rounded-box tw:h-[calc(100dvh-332px)] tw:overflow-y-auto tw:pt-4 tw:pb-1 tw:-mx-4 tw:overflow-x-hidden fade'
>
<div className='tw:h-full'>
<div className='tw:grid tw:grid-cols-1 tw:sm:grid-cols-2 tw:md:grid-cols-1 tw:lg:grid-cols-1 tw:xl:grid-cols-1 tw:2xl:grid-cols-2 tw:mb-4'>
{state.relations &&
state.relations.map((i) => (
<div
key={i.id}
className='tw:cursor-pointer tw:card tw:bg-base-200 tw:border-[1px] tw:border-base-300 tw:card-body tw:shadow-xl tw:text-base-content tw:mx-4 tw:p-6 tw:mb-4'
onClick={() => navigate('/item/' + i.id)}
>
<LinkedItemsHeaderView
unlinkPermission={updatePermission}
item={i}
unlinkCallback={(id) => unlinkItem(id, item, updateItem)}
loading={loading}
/>
<div className='tw:overflow-y-auto tw:overflow-x-hidden tw:max-h-64 fade'>
<TextView truncate itemId={item.id} />
</>
)}
{item.layer?.itemType.relations && (
<>
<input
type='radio'
name='my_tabs_2'
role='tab'
className='tw:tab '
aria-label='Links'
checked={activeTab === 7 && true}
onChange={() => updateActiveTab(7)}
/>
<div
role='tabpanel'
className='tw:tab-content tw:rounded-box tw:!h-[calc(100%-48px)] tw:overflow-y-auto tw:pt-4 tw:overflow-x-hidden fade'
>
<div className='tw:h-full'>
<div className='tw:grid tw:grid-cols-1 tw:sm:grid-cols-2 tw:md:grid-cols-1 tw:lg:grid-cols-1 tw:xl:grid-cols-1 tw:2xl:grid-cols-2 tw:mb-4'>
{state.relations &&
state.relations.map((i) => (
<div
key={i.id}
className='tw:cursor-pointer tw:card tw:bg-base-200 tw:border-[1px] tw:border-base-300 tw:card-body tw:shadow-xl tw:text-base-content tw:mx-4 tw:p-6 tw:mb-4'
onClick={() => navigate('/item/' + i.id)}
>
<LinkedItemsHeaderView
unlinkPermission={updatePermission}
item={i}
unlinkCallback={(id) => unlinkItem(id, item, updateItem)}
loading={loading}
/>
<div className='tw:overflow-y-auto tw:overflow-x-hidden tw:max-h-64 fade'>
<TextView truncate itemId={item.id} />
</div>
</div>
</div>
))}
{updatePermission && (
<ActionButton
customStyle='tw:bottom-24!'
collection='items'
item={item}
existingRelations={state.relations}
triggerItemSelected={(id) => linkItem(id, item, updateItem)}
></ActionButton>
)}
))}
{updatePermission && (
<ActionButton
customStyle='tw:bottom-24!'
collection='items'
item={item}
existingRelations={state.relations}
triggerItemSelected={(id) => linkItem(id, item, updateItem)}
></ActionButton>
)}
</div>
</div>
</div>
</div>
</>
)}
</>
)}
</div>
</div>
)
}

View File

@ -97,7 +97,7 @@ export const TabsView = ({
/>
<div
role='tabpanel'
className='tw:tab-content tw:bg-base-100 tw:rounded-box tw:h-[calc(100dvh-280px)] tw:overflow-y-auto fade tw:pt-2 tw:pb-4 tw:mb-4 tw:overflow-x-hidden'
className='tw:tab-content tw:bg-base-100 tw:rounded-box tw:!h-[calc(100dvh-280px)] tw:overflow-y-auto fade tw:pt-2 tw:pb-4 tw:mb-4 tw:overflow-x-hidden'
>
{item.layer?.itemType.show_start_end && (
<div className='tw:max-w-xs'>
@ -121,7 +121,7 @@ export const TabsView = ({
/>
<div
role='tabpanel'
className='tw:tab-content tw:bg-base-100 tw:rounded-box tw:h-[calc(100dvh-280px)] tw:overflow-y-auto fade tw:pt-2 tw:pb-4 tw:mb-4 tw:overflow-x-hidden'
className='tw:tab-content tw:bg-base-100 tw:rounded-box tw:!h-[calc(100dvh-280px)] tw:overflow-y-auto fade tw:pt-2 tw:pb-4 tw:mb-4 tw:overflow-x-hidden'
>
<table className='sm:tw:table-sm md:tw:table-md tw:w-full'>
<tbody>
@ -257,7 +257,7 @@ export const TabsView = ({
/>
<div
role='tabpanel'
className='tw:tab-content tw:bg-base-100 tw:rounded-box tw:h-[calc(100dvh-280px)] tw:overflow-y-auto tw:pt-4 tw:pb-1 tw:-mr-4 tw:-mb-4 tw:overflow-x-hidden'
className='tw:tab-content tw:bg-base-100 tw:rounded-box tw:!h-[calc(100dvh-280px)] tw:overflow-y-auto tw:pt-4 tw:pb-1 tw:-mr-4 tw:-mb-4 tw:overflow-x-hidden'
>
<div className='tw:h-full'>
<div className='tw:grid tw:grid-cols-1 tw:sm:grid-cols-2 tw:md:grid-cols-1 tw:lg:grid-cols-1 tw:xl:grid-cols-1 tw:2xl:grid-cols-2 tw:pb-4'>