234 lines
6.4 KiB
TypeScript
234 lines
6.4 KiB
TypeScript
import { ZodError } from "zod"
|
|
|
|
import { HabitsTracker } from "@/domain/entities/HabitsTracker"
|
|
import type { ErrorGlobal, FetchState } from "./_Presenter"
|
|
import { Presenter } from "./_Presenter"
|
|
import type {
|
|
RetrieveHabitsTrackerUseCase,
|
|
RetrieveHabitsTrackerUseCaseOptions,
|
|
} from "@/domain/use-cases/RetrieveHabitsTracker"
|
|
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,
|
|
} from "@/domain/use-cases/HabitGoalProgressUpdate"
|
|
|
|
export interface HabitsTrackerPresenterState {
|
|
habitsTracker: HabitsTracker
|
|
|
|
retrieveHabitsTracker: {
|
|
state: FetchState
|
|
}
|
|
|
|
habitCreate: {
|
|
state: FetchState
|
|
errors: {
|
|
fields: Array<keyof HabitCreateData>
|
|
global: ErrorGlobal
|
|
}
|
|
}
|
|
|
|
habitEdit: {
|
|
state: FetchState
|
|
errors: {
|
|
fields: Array<keyof HabitEditData>
|
|
global: ErrorGlobal
|
|
}
|
|
}
|
|
|
|
habitStop: {
|
|
state: FetchState
|
|
}
|
|
|
|
habitGoalProgressUpdate: {
|
|
state: FetchState
|
|
}
|
|
}
|
|
|
|
export interface HabitsTrackerPresenterOptions {
|
|
retrieveHabitsTrackerUseCase: RetrieveHabitsTrackerUseCase
|
|
habitCreateUseCase: HabitCreateUseCase
|
|
habitEditUseCase: HabitEditUseCase
|
|
habitStopUseCase: HabitStopUseCase
|
|
habitGoalProgressUpdateUseCase: HabitGoalProgressUpdateUseCase
|
|
}
|
|
|
|
export class HabitsTrackerPresenter
|
|
extends Presenter<HabitsTrackerPresenterState>
|
|
implements HabitsTrackerPresenterOptions
|
|
{
|
|
public retrieveHabitsTrackerUseCase: RetrieveHabitsTrackerUseCase
|
|
public habitCreateUseCase: HabitCreateUseCase
|
|
public habitEditUseCase: HabitEditUseCase
|
|
public habitStopUseCase: HabitStopUseCase
|
|
public habitGoalProgressUpdateUseCase: HabitGoalProgressUpdateUseCase
|
|
|
|
public constructor(options: HabitsTrackerPresenterOptions) {
|
|
const {
|
|
retrieveHabitsTrackerUseCase,
|
|
habitCreateUseCase,
|
|
habitEditUseCase,
|
|
habitStopUseCase,
|
|
habitGoalProgressUpdateUseCase,
|
|
} = options
|
|
const habitsTracker = HabitsTracker.default()
|
|
super({
|
|
habitsTracker,
|
|
retrieveHabitsTracker: { state: "idle" },
|
|
habitCreate: {
|
|
state: "idle",
|
|
errors: {
|
|
fields: [],
|
|
global: null,
|
|
},
|
|
},
|
|
habitEdit: {
|
|
state: "idle",
|
|
errors: {
|
|
fields: [],
|
|
global: null,
|
|
},
|
|
},
|
|
habitStop: {
|
|
state: "idle",
|
|
},
|
|
habitGoalProgressUpdate: {
|
|
state: "idle",
|
|
},
|
|
})
|
|
this.retrieveHabitsTrackerUseCase = retrieveHabitsTrackerUseCase
|
|
this.habitCreateUseCase = habitCreateUseCase
|
|
this.habitEditUseCase = habitEditUseCase
|
|
this.habitStopUseCase = habitStopUseCase
|
|
this.habitGoalProgressUpdateUseCase = habitGoalProgressUpdateUseCase
|
|
}
|
|
|
|
public async habitCreate(data: unknown): Promise<FetchState> {
|
|
try {
|
|
this.setState((state) => {
|
|
state.habitCreate.state = "loading"
|
|
state.habitCreate.errors = {
|
|
fields: [],
|
|
global: null,
|
|
}
|
|
})
|
|
const habit = await this.habitCreateUseCase.execute(data)
|
|
this.setState((state) => {
|
|
state.habitCreate.state = "success"
|
|
state.habitsTracker.addHabit(habit)
|
|
})
|
|
return "success"
|
|
} catch (error) {
|
|
this.setState((state) => {
|
|
state.habitCreate.state = "error"
|
|
if (error instanceof ZodError) {
|
|
state.habitCreate.errors.fields =
|
|
getErrorsFieldsFromZodError<HabitCreateData>(error)
|
|
} else {
|
|
state.habitCreate.errors.global = "unknown"
|
|
}
|
|
})
|
|
return "error"
|
|
}
|
|
}
|
|
|
|
public async habitEdit(data: unknown): Promise<FetchState> {
|
|
try {
|
|
this.setState((state) => {
|
|
state.habitEdit.state = "loading"
|
|
state.habitEdit.errors = {
|
|
fields: [],
|
|
global: null,
|
|
}
|
|
})
|
|
const habit = await this.habitEditUseCase.execute(data)
|
|
this.setState((state) => {
|
|
state.habitEdit.state = "success"
|
|
state.habitsTracker.editHabit(habit)
|
|
})
|
|
return "success"
|
|
} catch (error) {
|
|
this.setState((state) => {
|
|
state.habitEdit.state = "error"
|
|
if (error instanceof ZodError) {
|
|
state.habitEdit.errors.fields =
|
|
getErrorsFieldsFromZodError<HabitEditData>(error)
|
|
} else {
|
|
state.habitEdit.errors.global = "unknown"
|
|
}
|
|
})
|
|
return "error"
|
|
}
|
|
}
|
|
|
|
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> {
|
|
this.setState((state) => {
|
|
state.retrieveHabitsTracker.state = "loading"
|
|
state.habitsTracker = HabitsTracker.default()
|
|
})
|
|
try {
|
|
const habitsTracker =
|
|
await this.retrieveHabitsTrackerUseCase.execute(options)
|
|
this.setState((state) => {
|
|
state.habitsTracker = habitsTracker
|
|
state.retrieveHabitsTracker.state = "success"
|
|
})
|
|
} catch (error) {
|
|
this.setState((state) => {
|
|
state.retrieveHabitsTracker.state = "error"
|
|
})
|
|
}
|
|
}
|
|
|
|
public async habitUpdateProgress(
|
|
options: HabitGoalProgressUpdateUseCaseOptions,
|
|
): Promise<FetchState> {
|
|
try {
|
|
this.setState((state) => {
|
|
state.habitGoalProgressUpdate.state = "loading"
|
|
})
|
|
const habitProgress =
|
|
await this.habitGoalProgressUpdateUseCase.execute(options)
|
|
this.setState((state) => {
|
|
state.habitsTracker.updateHabitProgress(habitProgress)
|
|
state.habitGoalProgressUpdate.state = "success"
|
|
})
|
|
return "success"
|
|
} catch (error) {
|
|
this.setState((state) => {
|
|
state.habitGoalProgressUpdate.state = "error"
|
|
})
|
|
return "error"
|
|
}
|
|
}
|
|
}
|