Skip to content
Open
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
d9d207c
feat(app): public witnessing
ux-git Jul 16, 2026
2298012
feat(public-witnessing): data layer, route and dashboard entry
ux-git Jul 16, 2026
7f3c000
feat(public-witnessing): locations management UI
ux-git Jul 16, 2026
1de5273
feat(public-witnessing): day view with shift booking
ux-git Jul 16, 2026
4e5a01f
fix(public-witnessing): align dialogs and header with Figma spec
ux-git Jul 16, 2026
35db5c7
fix(public-witnessing): polish cells, icons and dialog details
ux-git Jul 16, 2026
7169e79
fix(public-witnessing): dialog spacing, delete placement, optional max
ux-git Jul 16, 2026
7b0ff47
feat(public-witnessing): mobile list-to-subpage flow and calendar header
ux-git Jul 16, 2026
e66c801
feat(public-witnessing): inline day shifts accordion on mobile
ux-git Jul 16, 2026
62ace7f
fix(public-witnessing): route-driven subpage, empty note, day rules
ux-git Jul 16, 2026
2640861
feat(public-witnessing): week and month views for shifts
ux-git Jul 30, 2026
03601ea
fix(public-witnessing): keep the locations sidebar usable on desktop
ux-git Jul 30, 2026
a0ab4ff
refactor(public-witnessing): design-system pass on the shift cells
ux-git Jul 30, 2026
7159979
feat(public-witnessing): match the Figma week and month designs
ux-git Jul 30, 2026
eb6ec78
tweak(public-witnessing): schedule setup, calendar polish and mobile UX
ux-git Jul 30, 2026
a2be641
fix(public-witnessing): never arrange more publishers than the shift …
ux-git Jul 30, 2026
95f705a
tweak(public-witnessing): move the arrangement delete to the dialog h…
ux-git Jul 30, 2026
65861b2
tweak(public-witnessing): badge styling and labels
ux-git Jul 30, 2026
39ca7b1
refactor(ui): size badge text from the badge size
ux-git Jul 30, 2026
323f466
refactor(public-witnessing): keys, ternaries and nesting
ux-git Jul 30, 2026
639a15a
refactor(ui): simplify badge colours and the shift cell
ux-git Jul 31, 2026
c372d24
refactor(public-witnessing): drop the superseded card components
ux-git Jul 31, 2026
a571ff1
fix(public-witnessing): require the publisher cap, level the shift cells
ux-git Jul 31, 2026
3628b27
tweak(public-witnessing): keep the schedule divider and the day prompt
ux-git Jul 31, 2026
be432f6
tweak(public-witnessing): mark required location fields and centre th…
ux-git Jul 31, 2026
a3defee
feat(public-witnessing): add locations through a two-step form
ux-git Jul 31, 2026
4616137
fix(components): use the red token for field error outlines
ux-git Jul 31, 2026
bc09828
chore(public-witnessing): drop the unused translation key, clarify th…
ux-git Jul 31, 2026
322602d
refactor(public-witnessing): split the location form and make day row…
ux-git Jul 31, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ const FieldServiceReportsPage = lazy(
const MidweekMeeting = lazy(() => import('@pages/meetings/midweek'));
const MinistryReport = lazy(() => import('@pages/ministry/ministry_report'));
const ServiceYear = lazy(() => import('@pages/ministry/service_year'));
const PublicWitnessing = lazy(
() => import('@pages/ministry/public_witnessing')
);
const AuxiliaryPioneerApplication = lazy(
() => import('@pages/ministry/auxiliary_pioneer')
);
Expand Down Expand Up @@ -128,6 +131,11 @@ const App = ({ updatePwa }: { updatePwa: VoidFunction }) => {
children: [
{ path: '/ministry-report', element: <MinistryReport /> },
{ path: '/service-year', element: <ServiceYear /> },
{ path: '/public-witnessing', element: <PublicWitnessing /> },
{
path: '/public-witnessing/:locationId',
element: <PublicWitnessing />,
},

// only if connected
{
Expand Down
130 changes: 61 additions & 69 deletions src/components/badge/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Box } from '@mui/material';
import Typography from '@components/typography';
import { CustomClassName } from '@definition/app';
import {
BadgeContentPropsType,
BadgePropsType,
Expand Down Expand Up @@ -60,6 +61,46 @@ const BadgeTypography = ({
);
};

type ColorProps = Pick<BadgePropsType, 'color' | 'filled' | 'faded' | 'size'> &
Pick<BadgePropsType, 'light'>;

const resolveTextColor = ({ color, filled, faded, size }: ColorProps) => {
if (filled) return 'var(--always-white)';
if (color === 'transparent') return 'var(--accent-400)';
if (color === 'grey') return faded ? 'var(--grey-300)' : 'var(--grey-400)';
if (color === 'green') return 'var(--green-main)';
if (color === 'red' && size === 'big') return 'var(--red-main)';

return `var(--${color}-dark)`;
};

const resolveBackgroundColor = ({ color, filled, faded, light }: ColorProps) => {
if (color === 'transparent') return 'transparent';
if (filled) {
return color === 'grey' ? 'var(--grey-400)' : `var(--${color}-main)`;
}
if (light) {
return color === 'accent' || color === 'grey'
? `var(--${color}-150)`
: `var(--${color}-secondary)`;
}
if (color === 'grey') return faded ? 'var(--grey-100)' : 'var(--grey-150)';
if (color === 'accent') return 'var(--accent-200)';

return `var(--${color}-secondary)`;
};

const bigBadgeHeight = (multiLine?: boolean, filled?: boolean) => {
if (multiLine) return 'unset';
return filled ? '24px' : '28px';
};

const sizeClassName: Record<BadgePropsType['size'], CustomClassName> = {
small: 'label-small-medium',
medium: 'body-small-semibold',
big: 'body-regular',
};

const Badge = (props: BadgePropsType) => {
const {
icon,
Expand All @@ -72,52 +113,15 @@ const Badge = (props: BadgePropsType) => {
borderStyle,
className,
faded,
light,
sx = {},
} = props;

const getColor = () => {
if (filled) return `var(--always-white)`;

if (color === 'grey') {
if (faded) {
return `var(--${color}-300)`;
}

return `var(--${color}-400)`;
} else if (color === 'green') {
return `var(--${color}-main)`;
} else if (color === 'transparent') return 'var(--accent-400)';
else {
if (size === 'big' && color === 'red') {
return `var(--${color}-main)`;
} else {
return `var(--${color}-dark)`;
}
}
};

const getBackgroundColor = () => {
if (color === 'transparent') return color;
if (filled) {
if (color === 'grey') {
return `var(--${color}-400)`;
} else {
return `var(--${color}-main)`;
}
} else {
if (color === 'grey') {
if (faded) {
return `var(--${color}-100)`;
}

return `var(--${color}-150)`;
} else if (color === 'accent') {
return `var(--accent-200)`;
} else {
return `var(--${color}-secondary)`;
}
}
};
const textClassName = className ?? sizeClassName[size];

const colorProps = { color, filled, faded, size, light };
const textColor = resolveTextColor(colorProps);
const backgroundColor = resolveBackgroundColor(colorProps);

return (
<>
Expand All @@ -126,10 +130,10 @@ const Badge = (props: BadgePropsType) => {
sx={{
border: '2px',
height: props.multiLine ? 'unset' : '20px',
background: getBackgroundColor(),
background: backgroundColor,
display: 'flex',
flexDirection: 'row',
borderRadius: 'var(--radius-xs)',
borderRadius: 'var(--radius-s)',
gap: '4px',
padding: '2px 6px',
flexShrink: '0',
Expand All @@ -143,16 +147,11 @@ const Badge = (props: BadgePropsType) => {
icon={icon}
iconHeight={'16px'}
iconWidth={'16px'}
color={getColor()}
color={textColor}
>
<BadgeTypography
className={className}
sx={{
fontSize: '12px',
fontWeight: '500',
lineHeight: '16px',
color: getColor(),
}}
className={textClassName}
sx={{ lineHeight: '16px', color: textColor }}
>
{text}
</BadgeTypography>
Expand All @@ -165,7 +164,7 @@ const Badge = (props: BadgePropsType) => {
border: '1px',
borderColor: 'var(--accent-350)',
height: props.multiLine ? 'unset' : '22px',
background: getBackgroundColor(),
background: backgroundColor,
display: 'flex',
flexDirection: 'row',
borderRadius: 'var(--radius-s)',
Expand All @@ -182,16 +181,11 @@ const Badge = (props: BadgePropsType) => {
icon={icon}
iconHeight={'18px'}
iconWidth={'18px'}
color={getColor()}
color={textColor}
>
<BadgeTypography
className={className}
sx={{
fontSize: '14px',
fontWeight: '520',
lineHeight: '16px',
color: getColor(),
}}
className={textClassName}
sx={{ lineHeight: '16px', color: textColor }}
>
{text}
</BadgeTypography>
Expand All @@ -202,8 +196,8 @@ const Badge = (props: BadgePropsType) => {
<Box
sx={{
border: '4px',
height: props.multiLine ? 'unset' : filled ? '24px' : '28px',
background: getBackgroundColor(),
height: bigBadgeHeight(props.multiLine, filled),
background: backgroundColor,
display: 'flex',
flexDirection: 'row',
borderRadius: 'var(--radius-s)',
Expand All @@ -221,15 +215,13 @@ const Badge = (props: BadgePropsType) => {
icon={icon}
iconHeight={'20px'}
iconWidth={'20px'}
color={getColor()}
color={textColor}
>
<BadgeTypography
className={className}
className={textClassName}
sx={{
fontSize: '16px',
fontWeight: '420',
lineHeight: '20px',
color: getColor(),
color: textColor,
}}
>
{text}
Expand Down
5 changes: 5 additions & 0 deletions src/components/badge/index.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ export type BadgePropsType = {
*/
icon?: ReactElement;

/**
* Fills the badge with the lightest shade of its color.
*/
light?: boolean;

/**
* Custom styles for the badge.
*/
Expand Down
3 changes: 1 addition & 2 deletions src/components/icons/IconReorder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,9 @@ const IconReorder = ({
<path
fillRule="evenodd"
clipRule="evenodd"
d="M15.8795 12.7505L19.5305 12.7505L17.4459 14.8351L18.5151 15.9043L22.4189 12.0005L18.5151 8.09668L17.4459 9.16588L19.5305 11.2505L15.8795 11.2505L15.8795 12.7505ZM8.33138 12.7505L4.58316 12.7505L6.66781 14.8197L5.58321 15.9043L1.67939 12.0005L5.58321 8.09668L6.65241 9.16588L4.56779 11.2505L8.33138 11.2505L8.33138 12.7505Z"
d="M15.8795 12.7505L19.5305 12.7505L17.4459 14.8351L18.5151 15.9043L22.4189 12.0005L18.5151 8.09668L17.4459 9.16588L19.5305 11.2505L15.8795 11.2505L15.8795 12.7505ZM8.33138 12.7505L4.58316 12.7505L6.66781 14.8197L5.58321 15.9043L1.67939 12.0005L5.58321 8.09668L6.65241 9.16588L4.56779 11.2505L8.33138 11.2505L8.33138 12.7505ZM12.0488 10.0005C13.1534 10.0005 14.0488 10.8959 14.0488 12.0005C14.0488 13.1051 13.1534 14.0005 12.0488 14.0005C10.9442 14.0005 10.0488 13.1051 10.0488 12.0005C10.0488 10.8959 10.9442 10.0005 12.0488 10.0005Z"
fill={color}
/>
<circle cx="12.0488" cy="12.0005" r="2" fill={color} />
</g>
</svg>
</SvgIcon>
Expand Down
Loading
Loading