diff --git a/app/application/habits/[habitId]/index.tsx b/app/application/habits/[habitId]/index.tsx
index 5a03693..02c162c 100644
--- a/app/application/habits/[habitId]/index.tsx
+++ b/app/application/habits/[habitId]/index.tsx
@@ -1,39 +1,20 @@
import { Redirect, useLocalSearchParams } from "expo-router"
-import { Text } from "react-native-paper"
-import { SafeAreaView } from "react-native-safe-area-context"
-import { useHabitsTracker } from "@/presentation/react/contexts/HabitsTracker"
import { HabitEditForm } from "@/presentation/react/components/HabitEditForm/HabitEditForm"
-import { useAuthentication } from "@/presentation/react/contexts/Authentication"
+import { useHabitsTracker } from "@/presentation/react/contexts/HabitsTracker"
const HabitPage: React.FC = () => {
const { habitId } = useLocalSearchParams()
const { habitsTracker } = useHabitsTracker()
- const { user } = useAuthentication()
-
- if (user === null) {
- return null
- }
const habitHistory = habitsTracker.getHabitHistoryById(habitId as string)
+
if (habitHistory == null) {
return
}
return (
-
-
- Habit Page {habitId} {habitHistory.habit.name}
-
-
-
+
)
}
diff --git a/app/application/habits/new.tsx b/app/application/habits/new.tsx
index f2c5361..f410ab0 100644
--- a/app/application/habits/new.tsx
+++ b/app/application/habits/new.tsx
@@ -4,7 +4,7 @@ import { useAuthentication } from "@/presentation/react/contexts/Authentication"
const NewHabitPage: React.FC = () => {
const { user } = useAuthentication()
- if (user === null) {
+ if (user == null) {
return null
}
diff --git a/domain/entities/Goal.ts b/domain/entities/Goal.ts
index d55fcbf..ded0b30 100644
--- a/domain/entities/Goal.ts
+++ b/domain/entities/Goal.ts
@@ -33,22 +33,8 @@ export const GoalCreateSchema = z.object({
]),
})
-export const GoalEditSchema = z.object({
- frequency: goalFrequencyZod,
- target: z.discriminatedUnion("type", [
- z.object({ type: z.literal("boolean") }),
- z.object({
- type: z.literal("numeric"),
- value: z.number().int().min(0),
- unit: z.string().min(1),
- }),
- ]),
-})
-
export type GoalCreateData = z.infer
-export type GoalEditData = z.infer
-
interface GoalBase {
frequency: GoalFrequency
}
diff --git a/domain/entities/Habit.ts b/domain/entities/Habit.ts
index e9de6c3..d80ba59 100644
--- a/domain/entities/Habit.ts
+++ b/domain/entities/Habit.ts
@@ -15,9 +15,7 @@ export const HabitCreateSchema = HabitSchema.extend({
}).omit({ id: true })
export type HabitCreateData = z.infer
-export const HabitEditSchema = HabitSchema.extend({
- goal: GoalCreateSchema,
-})
+export const HabitEditSchema = HabitSchema.extend({})
export type HabitEditData = z.infer
type HabitBase = z.infer
diff --git a/domain/entities/HabitsTracker.ts b/domain/entities/HabitsTracker.ts
index 7a99215..19f2122 100644
--- a/domain/entities/HabitsTracker.ts
+++ b/domain/entities/HabitsTracker.ts
@@ -35,6 +35,14 @@ export class HabitsTracker implements HabitsTrackerData {
)
}
+ public editHabit(habit: Habit): void {
+ const habitHistory = this.getHabitHistoryById(habit.id)
+ if (habitHistory == null) {
+ return
+ }
+ habitHistory.habit = habit
+ }
+
public getAllHabitsHistory(): HabitHistory[] {
return [
...this.habitsHistory.daily,
diff --git a/infrastructure/instances.ts b/infrastructure/instances.ts
index 89b1690..8e92055 100644
--- a/infrastructure/instances.ts
+++ b/infrastructure/instances.ts
@@ -8,6 +8,8 @@ import { supabaseClient } from "./supabase/supabase"
import { AuthenticationPresenter } from "@/presentation/presenters/Authentication"
import { HabitCreateSupabaseRepository } from "./supabase/repositories/HabitCreate"
import { HabitCreateUseCase } from "@/domain/use-cases/HabitCreate"
+import { HabitEditSupabaseRepository } from "./supabase/repositories/HabitEdit"
+import { HabitEditUseCase } from "@/domain/use-cases/HabitEdit"
/**
* Repositories
@@ -25,6 +27,9 @@ const getHabitsByUserIdRepository = new GetHabitsByUserIdSupabaseRepository({
const habitCreateRepository = new HabitCreateSupabaseRepository({
supabaseClient,
})
+const habitEditRepository = new HabitEditSupabaseRepository({
+ supabaseClient,
+})
/**
* Use Cases
@@ -39,6 +44,9 @@ const retrieveHabitsTrackerUseCase = new RetrieveHabitsTrackerUseCase({
getHabitProgressHistoryRepository: getHabitProgressesRepository,
getHabitsByUserIdRepository,
})
+const habitEditUseCase = new HabitEditUseCase({
+ habitEditRepository,
+})
/**
* Presenters
@@ -49,4 +57,5 @@ export const authenticationPresenter = new AuthenticationPresenter({
export const habitsTrackerPresenter = new HabitsTrackerPresenter({
retrieveHabitsTrackerUseCase,
habitCreateUseCase,
+ habitEditUseCase,
})
diff --git a/infrastructure/supabase/repositories/HabitEdit.ts b/infrastructure/supabase/repositories/HabitEdit.ts
index 9020098..f482cc3 100644
--- a/infrastructure/supabase/repositories/HabitEdit.ts
+++ b/infrastructure/supabase/repositories/HabitEdit.ts
@@ -12,18 +12,11 @@ export class HabitEditSupabaseRepository
const { data, error } = await this.supabaseClient
.from("habits")
.update({
- id: Number(habitEditData.id),
name: habitEditData.name,
color: habitEditData.color,
icon: habitEditData.icon,
- goal_frequency: habitEditData.goal.frequency,
- ...(habitEditData.goal.target.type === "numeric"
- ? {
- goal_target: habitEditData.goal.target.value,
- goal_target_unit: habitEditData.goal.target.unit,
- }
- : {}),
})
+ .eq("id", habitEditData.id)
.select("*")
const updatedHabit = data?.[0]
if (error != null || updatedHabit == null) {
@@ -34,7 +27,20 @@ export class HabitEditSupabaseRepository
userId: updatedHabit.user_id.toString(),
name: updatedHabit.name,
icon: updatedHabit.icon,
- goal: Goal.create(habitEditData.goal),
+ goal: Goal.create({
+ frequency: updatedHabit.goal_frequency,
+ target:
+ updatedHabit.goal_target != null &&
+ updatedHabit.goal_target_unit != null
+ ? {
+ type: "numeric",
+ value: updatedHabit.goal_target,
+ unit: updatedHabit.goal_target_unit,
+ }
+ : {
+ type: "boolean",
+ },
+ }),
color: updatedHabit.color,
startDate: new Date(updatedHabit.start_date),
})
diff --git a/presentation/presenters/HabitsTracker.ts b/presentation/presenters/HabitsTracker.ts
index 7e0d923..9688adb 100644
--- a/presentation/presenters/HabitsTracker.ts
+++ b/presentation/presenters/HabitsTracker.ts
@@ -7,9 +7,10 @@ import type {
RetrieveHabitsTrackerUseCase,
RetrieveHabitsTrackerUseCaseOptions,
} from "@/domain/use-cases/RetrieveHabitsTracker"
-import type { HabitCreateData } from "@/domain/entities/Habit"
+import type { 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"
export interface HabitsTrackerPresenterState {
habitsTracker: HabitsTracker
@@ -29,7 +30,7 @@ export interface HabitsTrackerPresenterState {
habitEdit: {
state: FetchState
errors: {
- fields: Array
+ fields: Array
global: ErrorGlobal
}
}
@@ -38,6 +39,7 @@ export interface HabitsTrackerPresenterState {
export interface HabitsTrackerPresenterOptions {
retrieveHabitsTrackerUseCase: RetrieveHabitsTrackerUseCase
habitCreateUseCase: HabitCreateUseCase
+ habitEditUseCase: HabitEditUseCase
}
export class HabitsTrackerPresenter
@@ -46,9 +48,14 @@ export class HabitsTrackerPresenter
{
public retrieveHabitsTrackerUseCase: RetrieveHabitsTrackerUseCase
public habitCreateUseCase: HabitCreateUseCase
+ public habitEditUseCase: HabitEditUseCase
public constructor(options: HabitsTrackerPresenterOptions) {
- const { retrieveHabitsTrackerUseCase, habitCreateUseCase } = options
+ const {
+ retrieveHabitsTrackerUseCase,
+ habitCreateUseCase,
+ habitEditUseCase,
+ } = options
const habitsTracker = HabitsTracker.default()
super({
habitsTracker,
@@ -70,6 +77,7 @@ export class HabitsTrackerPresenter
})
this.retrieveHabitsTrackerUseCase = retrieveHabitsTrackerUseCase
this.habitCreateUseCase = habitCreateUseCase
+ this.habitEditUseCase = habitEditUseCase
}
public async habitCreate(data: unknown): Promise {
@@ -110,10 +118,10 @@ export class HabitsTrackerPresenter
global: null,
}
})
- const habit = await this.habitCreateUseCase.execute(data)
+ const habit = await this.habitEditUseCase.execute(data)
this.setState((state) => {
state.habitEdit.state = "success"
- state.habitsTracker.addHabit(habit)
+ state.habitsTracker.editHabit(habit)
})
return "success"
} catch (error) {
@@ -121,7 +129,7 @@ export class HabitsTrackerPresenter
state.habitEdit.state = "error"
if (error instanceof ZodError) {
state.habitEdit.errors.fields =
- getErrorsFieldsFromZodError(error)
+ getErrorsFieldsFromZodError(error)
} else {
state.habitEdit.errors.global = "unknown"
}
diff --git a/presentation/react/components/HabitEditForm/HabitEditForm.tsx b/presentation/react/components/HabitEditForm/HabitEditForm.tsx
index b26d6e2..be69d7f 100644
--- a/presentation/react/components/HabitEditForm/HabitEditForm.tsx
+++ b/presentation/react/components/HabitEditForm/HabitEditForm.tsx
@@ -12,36 +12,28 @@ import ColorPicker, {
import type { Habit, HabitEditData } from "@/domain/entities/Habit"
import { HabitEditSchema } from "@/domain/entities/Habit"
-import type { User } from "@/domain/entities/User"
import { useHabitsTracker } from "../../contexts/HabitsTracker"
export interface HabitEditFormProps {
- user: User
habit: Habit
}
-export const HabitEditForm: React.FC = ({ user }) => {
+export const HabitEditForm: React.FC = ({ habit }) => {
const { habitEdit, habitsTrackerPresenter } = useHabitsTracker()
const {
control,
handleSubmit,
- reset,
formState: { errors },
} = useForm({
mode: "onChange",
resolver: zodResolver(HabitEditSchema),
defaultValues: {
- userId: user.id,
- name: "",
- color: "#006CFF",
- icon: "lightbulb",
- goal: {
- frequency: "daily",
- target: {
- type: "boolean",
- },
- },
+ id: habit.id,
+ userId: habit.userId,
+ name: habit.name,
+ color: habit.color,
+ icon: habit.icon,
},
})
@@ -54,7 +46,6 @@ export const HabitEditForm: React.FC = ({ user }) => {
const onSubmit = async (data: HabitEditData): Promise => {
await habitsTrackerPresenter.habitEdit(data)
setIsVisibleSnackbar(true)
- reset()
}
return (
@@ -141,7 +132,7 @@ export const HabitEditForm: React.FC = ({ user }) => {
disabled={habitEdit.state === "loading"}
style={[styles.spacing, { width: "90%" }]}
>
- Create your habit! 🚀
+ Save
@@ -150,7 +141,7 @@ export const HabitEditForm: React.FC = ({ user }) => {
onDismiss={onDismissSnackbar}
duration={2_000}
>
- ✅ Habit created successfully!
+ ✅ Habit Saved successfully!
)