Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 5 additions & 5 deletions locales/en/reading-goal.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@
"remaining": "Remaining for today",
"remaining-base": "Remaining",
"remaining-days": {
"one": "{{days}} day remaining",
"other": "{{days}} days remaining"
"one": "<span>{{days}}</span> day remaining",
"other": "<span>{{days}}</span> days remaining"
},
"set-a-new-goal": "Set a new Goal",
"set-reading-goal-success": "Your reading goal has been set successfully.",
Expand All @@ -111,10 +111,10 @@
},
"todays-goal": "Today's Goal",
"view-progress": "View Progress",
"week-progress": "This week's progress",
"week-progress": "This Week's Progress",
"x-days": {
"one": "{{days}} day",
"other": "{{days}} days"
"one": "<span>{{days}}</span> Day streak",
"other": "<span>{{days}}</span> Days streak"
},
"x-days-streak": "<p>{{days}}</p> <span>day streak</span>",
"x-hours": {
Expand Down
10 changes: 10 additions & 0 deletions public/icons/arrow-left.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,25 @@ const CurrentWeekProgress: React.FC<Props> = ({ weekData, goal, fixedWidth = tru
const hasRead = readingDay?.hasRead;

// if the user has a goal, we want to show a checked circle if the user has completed his goal for the day
// otherwise, we want to show a filled circle if the user has read at all for the day
// otherwise, we want to show a checked circle if the user has read at all for the day
const isGoalDone = goal ? convertFractionToPercent(readingDay?.progress || 0) >= 100 : hasRead;

if (isGoalDone) return DayState.Checked;
if (hasRead) return DayState.Filled;

return day.current ? DayState.Stroked : DayState.None;
// Check if the day is in the future
const today = new Date();
today.setHours(0, 0, 0, 0);
const dayDate = new Date(day.date);
dayDate.setHours(0, 0, 0, 0);

if (dayDate > today) return DayState.Future;

return DayState.None;
};

return (
<div>
<p className={styles.weekProgressLabel}>{t('reading-goal:week-progress')}</p>
<div className={styles.currentWeekProgress}>
<p className={styles.weekProgressLabel}>{t('reading-goal:week-progress')}:</p>
<div
className={classNames(styles.week, {
[styles.fixedWidth]: fixedWidth,
Expand All @@ -45,21 +52,31 @@ const CurrentWeekProgress: React.FC<Props> = ({ weekData, goal, fixedWidth = tru
{days.map((day) => {
const dayState = getDayState(day);

const today = new Date();
today.setHours(0, 0, 0, 0);
const dayDate = new Date(day.date);
dayDate.setHours(0, 0, 0, 0);
const isToday = dayDate.getTime() === today.getTime();

return (
<div key={day.info.localizedNumber} className={styles.day}>
<div className={styles.circleContainer}>
<DayCircle state={dayState} />
</div>
<HoverablePopover
content={dateToReadableFormat(day.date, lang)}
contentSide={ContentSide.TOP}
contentSide={ContentSide.BOTTOM}
>
<span className={styles.fullName}>{day.info.title}</span>
<span className={styles.shortName}>{day.info.localizedNumber}</span>
<span
className={classNames(styles.shortName, {
[styles.textBold]: isToday,
})}
>
{dayState === DayState.Future || isToday
? day.info.localizedNumber
: day.info.shortName}
</span>
</HoverablePopover>

<div className={styles.circleContainer}>
<DayCircle state={dayState} />

<div className={styles.dayDivider} />
</div>
</div>
);
})}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
width: var(--spacing-large);
height: var(--spacing-large);
border-radius: var(--border-radius-circle);
border: 2px solid var(--color-success-medium);
background-color: var(--day-circle-color);
border: 2px solid var(--color-blue-buttons-and-icons);
background-color: var(--color-background-default);
display: flex;
justify-content: center;
align-items: center;
Expand All @@ -12,7 +12,7 @@
inset-block-start: 50%;
transform: translate(-50%, -50%);

[dir="rtl"] & {
[dir='rtl'] & {
transform: translate(50%, -50%);
}

Expand All @@ -23,10 +23,11 @@
}
}

.filled {
background-color: var(--color-success-medium) !important;
.checked {
background-color: var(--color-blue-buttons-and-icons);
}

.stroked {
border-style: dashed;
.future {
border-color: var(--color-daily-progress);
background-color: var(--color-daily-progress);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ import CheckIcon from '@/icons/check.svg';

export enum DayState {
None = 'none',
Stroked = 'stroked',
Filled = 'filled',
Checked = 'checked',
Future = 'future',
}

interface DayCircleProps {
Expand All @@ -19,8 +18,8 @@ const DayCircle: React.FC<DayCircleProps> = ({ state }) => {
return (
<div
className={classNames(styles.dayCircle, {
[styles.filled]: state === DayState.Filled || state === DayState.Checked,
[styles.stroked]: state === DayState.Stroked,
[styles.checked]: state === DayState.Checked,
[styles.future]: state === DayState.Future,
})}
>
{state === DayState.Checked ? <CheckIcon /> : null}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@use "src/styles/theme";
@use "src/styles/breakpoints";
@use 'src/styles/theme';
@use 'src/styles/breakpoints';

.container {
display: flex;
Expand All @@ -21,8 +21,14 @@
color: var(--color-text-default-new);
}

.currentWeekProgress {
display: flex;
flex-direction: column;
gap: var(--spacing-medium);
}

.weekProgressLabel {
font-weight: var(--font-weight-medium);
font-weight: var(--font-weight-bold);
}

.week {
Expand All @@ -48,22 +54,15 @@
gap: var(--spacing-large);
}

.fullName {
display: none;

@include breakpoints.tablet {
display: block;
}
}

.shortName {
display: none;
color: var(--color-text-default-new);
font-size: var(--font-size-normal);
font-weight: var(--font-weight-medium);
display: block;
}

@include breakpoints.smallerThanTablet {
font-size: var(--font-size-normal);
font-weight: var(--font-weight-medium);
display: block;
}
.textBold {
font-weight: var(--font-weight-bold);
}

.circleContainer {
Expand All @@ -72,12 +71,6 @@
position: relative;
}

.dayDivider {
width: 100%;
height: 2px;
background-color: var(--color-success-medium);
}

.goalContainer {
margin-block-start: var(--spacing-mega);
}
Expand Down
91 changes: 38 additions & 53 deletions src/components/ReadingGoal/DeleteReadingGoalModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ import { makeStreakUrl } from '@/utils/auth/apiPaths';
import { logButtonClick } from '@/utils/eventLogger';

type DeleteReadingGoalButtonProps = {
isDisabled?: boolean;
isOpen: boolean;
onModalChange: (visible: boolean) => void;
};

const DeleteReadingGoalModal = ({ isDisabled }: DeleteReadingGoalButtonProps) => {
const DeleteReadingGoalModal = ({ isOpen, onModalChange }: DeleteReadingGoalButtonProps) => {
const { t } = useTranslation('reading-progress');
const [isModalVisible, setIsModalVisible] = useState(false);
const [confirmationText, setConfirmationText] = useState('');
const { mutate } = useSWRConfig();
const toast = useToast();
Expand All @@ -33,7 +33,7 @@ const DeleteReadingGoalModal = ({ isDisabled }: DeleteReadingGoalButtonProps) =>

const closeModal = () => {
setConfirmationText('');
setIsModalVisible(false);
onModalChange(false);
};

const onDeleteConfirmed = async () => {
Expand All @@ -45,61 +45,46 @@ const DeleteReadingGoalModal = ({ isDisabled }: DeleteReadingGoalButtonProps) =>
closeModal();
};

const onDeleteReadingGoalClicked = () => {
logButtonClick('reading_goal_delete');
setIsModalVisible(true);
};

const CONFIRMATION_TEXT = t('delete-goal.confirmation.confirmation-text');
const canDeleteGoal = confirmationText.toLowerCase() === CONFIRMATION_TEXT.toLowerCase();

return (
<>
<Button
type={ButtonType.Error}
variant={ButtonVariant.Ghost}
onClick={onDeleteReadingGoalClicked}
isDisabled={isDisabled}
>
{t('delete-goal.action')}
</Button>
<Modal isOpen={isModalVisible} onClickOutside={closeModal}>
<Modal.Body>
<Modal.Header>
<Modal.Title>{t('delete-goal.confirmation.title')}</Modal.Title>
<Modal.Subtitle>{t('delete-goal.confirmation.subtitle')}</Modal.Subtitle>
<Modal isOpen={isOpen} onClickOutside={closeModal}>
<Modal.Body>
<Modal.Header>
<Modal.Title>{t('delete-goal.confirmation.title')}</Modal.Title>
<Modal.Subtitle>{t('delete-goal.confirmation.subtitle')}</Modal.Subtitle>

<p className={styles.instructionText}>
<Trans
i18nKey="reading-progress:delete-goal.confirmation.instruction-text"
values={{ text: CONFIRMATION_TEXT }}
components={{
strong: <strong className={styles.confirmationText} />,
}}
/>
</p>
<Input
id="delete-goal-confirmation"
value={confirmationText}
onChange={setConfirmationText}
fixedWidth={false}
containerClassName={styles.inputContainer}
<p className={styles.instructionText}>
<Trans
i18nKey="reading-progress:delete-goal.confirmation.instruction-text"
values={{ text: CONFIRMATION_TEXT }}
components={{
strong: <strong className={styles.confirmationText} />,
}}
/>
</Modal.Header>
<Modal.Footer>
<Button
type={ButtonType.Error}
variant={ButtonVariant.Outlined}
className={styles.deleteButton}
onClick={onDeleteConfirmed}
isDisabled={!canDeleteGoal}
>
{t('delete-goal.confirmation.action-text')}
</Button>
</Modal.Footer>
</Modal.Body>
</Modal>
</>
</p>
<Input
id="delete-goal-confirmation"
value={confirmationText}
onChange={setConfirmationText}
fixedWidth={false}
containerClassName={styles.inputContainer}
/>
</Modal.Header>
<Modal.Footer>
<Button
type={ButtonType.Error}
variant={ButtonVariant.Outlined}
className={styles.deleteButton}
onClick={onDeleteConfirmed}
isDisabled={!canDeleteGoal}
>
{t('delete-goal.confirmation.action-text')}
</Button>
</Modal.Footer>
</Modal.Body>
</Modal>
);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@use 'src/styles/breakpoints';

.inputs {
width: 100%;
}
Expand Down Expand Up @@ -45,3 +47,23 @@
align-items: center;
gap: var(--spacing-xsmall);
}

.footerCtaContainer {
width: 100%;
display: flex;
flex-direction: column;
gap: var(--spacing-micro);
}

.editGoalButton {
background-color: var(--color-streaks-dark);
border: none;
border-radius: calc(var(--border-radius-default) * 3);

@include breakpoints.tablet {
background-color: initial;
border: initial;
border-radius: initial;
color: var(--color-streaks-dark);
}
}
Loading