106 lines
2.6 KiB
TypeScript
106 lines
2.6 KiB
TypeScript
import React from 'react';
|
|
import { IonButton, IonIcon, IonSpinner } from '@ionic/react';
|
|
import {
|
|
checkmarkOutline,
|
|
ellipseOutline,
|
|
flameOutline,
|
|
trashOutline,
|
|
} from 'ionicons/icons';
|
|
import { useHistory } from 'react-router-dom';
|
|
import type { Tables } from '../database.types';
|
|
|
|
interface HabitCardProps {
|
|
habit: Tables<'habits'>;
|
|
completedToday: boolean;
|
|
currentStreak: number;
|
|
completionRate: number;
|
|
onToggle: () => void;
|
|
onDelete: () => void;
|
|
busy: boolean;
|
|
}
|
|
|
|
const HabitCard: React.FC<HabitCardProps> = ({
|
|
habit,
|
|
completedToday,
|
|
currentStreak,
|
|
completionRate,
|
|
onToggle,
|
|
onDelete,
|
|
busy,
|
|
}) => {
|
|
const history = useHistory();
|
|
|
|
return (
|
|
<div
|
|
className={`habit-card habit-card--editorial ${completedToday ? 'is-complete' : ''}`}
|
|
>
|
|
<button
|
|
type="button"
|
|
className={`habit-check-button ${completedToday ? 'is-complete' : ''}`}
|
|
onClick={(e) => {
|
|
e.stopPropagation();
|
|
onToggle();
|
|
}}
|
|
disabled={busy}
|
|
aria-label={
|
|
completedToday
|
|
? `Mark ${habit.name} as not done`
|
|
: `Mark ${habit.name} as done`
|
|
}
|
|
>
|
|
{busy ? (
|
|
<IonSpinner name="crescent" />
|
|
) : completedToday ? (
|
|
<IonIcon icon={checkmarkOutline} />
|
|
) : (
|
|
<IonIcon icon={ellipseOutline} />
|
|
)}
|
|
</button>
|
|
|
|
<button
|
|
type="button"
|
|
className="habit-card-tap-area"
|
|
onClick={() => history.push(`/habit/${habit.id}`)}
|
|
aria-label={`View details for ${habit.name}`}
|
|
>
|
|
<div className="habit-card-main">
|
|
<div className="habit-copy">
|
|
<div className="habit-copy-topline">
|
|
<h3>{habit.name}</h3>
|
|
<span
|
|
className="habit-color-pill"
|
|
style={{ background: habit.color }}
|
|
/>
|
|
</div>
|
|
<p>
|
|
{habit.target_description ||
|
|
'Show up today and keep the chain alive.'}
|
|
</p>
|
|
<div className="habit-metrics-row">
|
|
<span>
|
|
<IonIcon icon={flameOutline} /> {currentStreak} streak
|
|
</span>
|
|
<span>{completionRate}% this week</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</button>
|
|
|
|
<IonButton
|
|
className="habit-delete-button"
|
|
fill="clear"
|
|
color="medium"
|
|
onClick={(e) => {
|
|
e.stopPropagation();
|
|
onDelete();
|
|
}}
|
|
disabled={busy}
|
|
>
|
|
<IonIcon icon={trashOutline} />
|
|
</IonButton>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default HabitCard;
|