Merge branch 'feat/habit-stop-use-case' into 'develop'
feat: habit stop use case See merge request rrll/p61-project!5
This commit is contained in:
commit
1a89fa03c5
@ -8,6 +8,7 @@ export const HabitSchema = EntitySchema.extend({
|
||||
name: z.string().min(1).max(50),
|
||||
color: z.string().min(4).max(9).regex(/^#/),
|
||||
icon: z.string().min(1),
|
||||
endDate: z.date().optional(),
|
||||
})
|
||||
|
||||
export const HabitCreateSchema = HabitSchema.extend({
|
||||
@ -29,7 +30,6 @@ export interface HabitData extends HabitBase {
|
||||
export interface HabitJSON extends HabitBase {
|
||||
goal: GoalBaseJSON
|
||||
startDate: string
|
||||
endDate?: string
|
||||
}
|
||||
|
||||
export class Habit extends Entity implements HabitData {
|
||||
@ -62,7 +62,7 @@ export class Habit extends Entity implements HabitData {
|
||||
icon: this.icon,
|
||||
goal: this.goal,
|
||||
startDate: this.startDate.toISOString(),
|
||||
endDate: this.endDate?.toISOString(),
|
||||
endDate: this?.endDate,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
24
domain/use-cases/HabitStop.ts
Normal file
24
domain/use-cases/HabitStop.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import type { Habit } from "../entities/Habit"
|
||||
import type { HabitEditRepository } from "../repositories/HabitEdit"
|
||||
|
||||
export interface HabitStopUseCaseDependencyOptions {
|
||||
habitEditRepository: HabitEditRepository
|
||||
}
|
||||
|
||||
export class HabitStopUseCase implements HabitStopUseCaseDependencyOptions {
|
||||
public habitEditRepository: HabitEditRepository
|
||||
|
||||
public constructor(options: HabitStopUseCaseDependencyOptions) {
|
||||
this.habitEditRepository = options.habitEditRepository
|
||||
}
|
||||
|
||||
public async execute(habitToStop: Habit): Promise<Habit> {
|
||||
const habit = await this.habitEditRepository.execute({
|
||||
habitEditData: {
|
||||
...habitToStop,
|
||||
endDate: new Date(),
|
||||
},
|
||||
})
|
||||
return habit
|
||||
}
|
||||
}
|
@ -13,6 +13,7 @@ import { HabitEditUseCase } from "@/domain/use-cases/HabitEdit"
|
||||
import { HabitProgressCreateSupabaseRepository } from "./supabase/repositories/HabitProgressCreate"
|
||||
import { HabitProgressUpdateSupabaseRepository } from "./supabase/repositories/HabitProgressUpdate"
|
||||
import { HabitGoalProgressUpdateUseCase } from "@/domain/use-cases/HabitGoalProgressUpdate"
|
||||
import { HabitStopUseCase } from "@/domain/use-cases/HabitStop"
|
||||
|
||||
/**
|
||||
* Repositories
|
||||
@ -64,6 +65,9 @@ const habitGoalProgressUpdateUseCase = new HabitGoalProgressUpdateUseCase({
|
||||
habitProgressCreateRepository,
|
||||
habitProgressUpdateRepository,
|
||||
})
|
||||
const habitStopUseCase = new HabitStopUseCase({
|
||||
habitEditRepository,
|
||||
})
|
||||
|
||||
/**
|
||||
* Presenters
|
||||
@ -75,5 +79,6 @@ export const habitsTrackerPresenter = new HabitsTrackerPresenter({
|
||||
retrieveHabitsTrackerUseCase,
|
||||
habitCreateUseCase,
|
||||
habitEditUseCase,
|
||||
habitStopUseCase,
|
||||
habitGoalProgressUpdateUseCase,
|
||||
})
|
||||
|
@ -15,6 +15,7 @@ export class HabitEditSupabaseRepository
|
||||
name: habitEditData.name,
|
||||
color: habitEditData.color,
|
||||
icon: habitEditData.icon,
|
||||
end_date: habitEditData?.endDate?.toISOString(),
|
||||
})
|
||||
.eq("id", habitEditData.id)
|
||||
.select("*")
|
||||
@ -43,6 +44,10 @@ export class HabitEditSupabaseRepository
|
||||
}),
|
||||
color: updatedHabit.color,
|
||||
startDate: new Date(updatedHabit.start_date),
|
||||
endDate:
|
||||
updatedHabit.end_date != null
|
||||
? new Date(updatedHabit.end_date)
|
||||
: undefined,
|
||||
})
|
||||
return habit
|
||||
}
|
||||
|
@ -7,10 +7,15 @@ import type {
|
||||
RetrieveHabitsTrackerUseCase,
|
||||
RetrieveHabitsTrackerUseCaseOptions,
|
||||
} from "@/domain/use-cases/RetrieveHabitsTracker"
|
||||
import type { HabitCreateData, HabitEditData } from "@/domain/entities/Habit"
|
||||
import type {
|
||||
Habit,
|
||||
HabitCreateData,
|
||||
HabitEditData,
|
||||
} from "@/domain/entities/Habit"
|
||||
import { getErrorsFieldsFromZodError } from "../../utils/zod"
|
||||
import type { HabitCreateUseCase } from "@/domain/use-cases/HabitCreate"
|
||||
import type { HabitEditUseCase } from "@/domain/use-cases/HabitEdit"
|
||||
import type { HabitStopUseCase } from "@/domain/use-cases/HabitStop"
|
||||
import type {
|
||||
HabitGoalProgressUpdateUseCase,
|
||||
HabitGoalProgressUpdateUseCaseOptions,
|
||||
@ -39,6 +44,10 @@ export interface HabitsTrackerPresenterState {
|
||||
}
|
||||
}
|
||||
|
||||
habitStop: {
|
||||
state: FetchState
|
||||
}
|
||||
|
||||
habitGoalProgressUpdate: {
|
||||
state: FetchState
|
||||
}
|
||||
@ -48,6 +57,7 @@ export interface HabitsTrackerPresenterOptions {
|
||||
retrieveHabitsTrackerUseCase: RetrieveHabitsTrackerUseCase
|
||||
habitCreateUseCase: HabitCreateUseCase
|
||||
habitEditUseCase: HabitEditUseCase
|
||||
habitStopUseCase: HabitStopUseCase
|
||||
habitGoalProgressUpdateUseCase: HabitGoalProgressUpdateUseCase
|
||||
}
|
||||
|
||||
@ -58,6 +68,7 @@ export class HabitsTrackerPresenter
|
||||
public retrieveHabitsTrackerUseCase: RetrieveHabitsTrackerUseCase
|
||||
public habitCreateUseCase: HabitCreateUseCase
|
||||
public habitEditUseCase: HabitEditUseCase
|
||||
public habitStopUseCase: HabitStopUseCase
|
||||
public habitGoalProgressUpdateUseCase: HabitGoalProgressUpdateUseCase
|
||||
|
||||
public constructor(options: HabitsTrackerPresenterOptions) {
|
||||
@ -65,6 +76,7 @@ export class HabitsTrackerPresenter
|
||||
retrieveHabitsTrackerUseCase,
|
||||
habitCreateUseCase,
|
||||
habitEditUseCase,
|
||||
habitStopUseCase,
|
||||
habitGoalProgressUpdateUseCase,
|
||||
} = options
|
||||
const habitsTracker = HabitsTracker.default()
|
||||
@ -85,6 +97,9 @@ export class HabitsTrackerPresenter
|
||||
global: null,
|
||||
},
|
||||
},
|
||||
habitStop: {
|
||||
state: "idle",
|
||||
},
|
||||
habitGoalProgressUpdate: {
|
||||
state: "idle",
|
||||
},
|
||||
@ -92,6 +107,7 @@ export class HabitsTrackerPresenter
|
||||
this.retrieveHabitsTrackerUseCase = retrieveHabitsTrackerUseCase
|
||||
this.habitCreateUseCase = habitCreateUseCase
|
||||
this.habitEditUseCase = habitEditUseCase
|
||||
this.habitStopUseCase = habitStopUseCase
|
||||
this.habitGoalProgressUpdateUseCase = habitGoalProgressUpdateUseCase
|
||||
}
|
||||
|
||||
@ -153,6 +169,25 @@ export class HabitsTrackerPresenter
|
||||
}
|
||||
}
|
||||
|
||||
public async habitStop(habitToStop: Habit): Promise<FetchState> {
|
||||
try {
|
||||
this.setState((state) => {
|
||||
state.habitStop.state = "loading"
|
||||
})
|
||||
const habit = await this.habitStopUseCase.execute(habitToStop)
|
||||
this.setState((state) => {
|
||||
state.habitStop.state = "success"
|
||||
state.habitsTracker.editHabit(habit)
|
||||
})
|
||||
return "success"
|
||||
} catch (error) {
|
||||
this.setState((state) => {
|
||||
state.habitStop.state = "error"
|
||||
})
|
||||
return "error"
|
||||
}
|
||||
}
|
||||
|
||||
public async retrieveHabitsTracker(
|
||||
options: RetrieveHabitsTrackerUseCaseOptions,
|
||||
): Promise<void> {
|
||||
|
@ -19,7 +19,7 @@ export interface HabitEditFormProps {
|
||||
}
|
||||
|
||||
export const HabitEditForm: React.FC<HabitEditFormProps> = ({ habit }) => {
|
||||
const { habitEdit, habitsTrackerPresenter } = useHabitsTracker()
|
||||
const { habitEdit, habitStop, habitsTrackerPresenter } = useHabitsTracker()
|
||||
|
||||
const {
|
||||
control,
|
||||
@ -134,6 +134,18 @@ export const HabitEditForm: React.FC<HabitEditFormProps> = ({ habit }) => {
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
mode="outlined"
|
||||
onPress={async () => {
|
||||
await habitsTrackerPresenter.habitStop(habit)
|
||||
}}
|
||||
loading={habitStop.state === "loading"}
|
||||
disabled={habitStop.state === "loading"}
|
||||
style={[styles.spacing, { width: "90%" }]}
|
||||
>
|
||||
Stop
|
||||
</Button>
|
||||
</ScrollView>
|
||||
|
||||
<Snackbar
|
||||
|
@ -90,16 +90,24 @@ export const HabitsList: React.FC<HabitsListProps> = (props) => {
|
||||
},
|
||||
]}
|
||||
>
|
||||
{habitsTracker.habitsHistory[frequency].map((item) => {
|
||||
return (
|
||||
<HabitCard
|
||||
habitHistory={item}
|
||||
selectedDate={selectedDate}
|
||||
key={item.habit.id + selectedDate.toISOString()}
|
||||
confettiRef={confettiRef}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
{habitsTracker.habitsHistory[frequency]
|
||||
.filter((habitItem) => {
|
||||
return (
|
||||
(habitItem.habit.endDate != null &&
|
||||
habitItem.habit.endDate <= selectedDate) ||
|
||||
habitItem.habit.endDate == null
|
||||
)
|
||||
})
|
||||
.map((item) => {
|
||||
return (
|
||||
<HabitCard
|
||||
habitHistory={item}
|
||||
selectedDate={selectedDate}
|
||||
key={item.habit.id + selectedDate.toISOString()}
|
||||
confettiRef={confettiRef}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</List.Accordion>
|
||||
)
|
||||
})}
|
||||
|
Reference in New Issue
Block a user