Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixed create-habit htmx strategy #21

Merged
merged 1 commit into from
Aug 13, 2024
Merged
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
12 changes: 4 additions & 8 deletions src/components/habits.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ import {
} from "$components/buttons.component";
import { FormField } from "$components/fields.component";
import {
Notification,
notificationListId,
Notification
} from "$components/notifications.component";
import { LimitPaginationRadio } from "$components/pagination.component";
import { Habit } from "$db/models";
Expand All @@ -17,13 +16,13 @@ import clsx from "clsx";
export type HabitsProps = { habits: Habit[] };

export function CreateHabitForm() {
const targetId = "habit-list";
const targetId = "habit-container";
const createHabitErrorMessageId = "create-habit-error";
const createHabitFormRef = "create-habit-form";
return (
<form
hx-post="/api/habits"
hx-swap={`afterbegin`}
hx-swap={`outerHTML`}
hx-target={`#${targetId}`}
hx-target-4xx={`#${createHabitErrorMessageId}`}
hx-target-5xx={`#${createHabitErrorMessageId}`}
Expand Down Expand Up @@ -68,7 +67,7 @@ export type EditHabitProps = {
title: Habit["title"];
description: Habit["description"];
modalRef: string;
};
}
export function EditHabitForm({
title,
description,
Expand Down Expand Up @@ -223,9 +222,6 @@ export function HabitItem({
itemId: item._id?.toString() ?? "",
tooltipInformation: "double click on this block to switch on deletion mode",
};
if (restProps["x-notification"]) {
habitItemNotificationData.xNotification = restProps["x-notification"];
}

return (
<li
Expand Down
173 changes: 102 additions & 71 deletions src/controllers/api/habits.api.controller.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ export const habitIdApiController = new Hono<{ Variables: AppVariables }>()

return html(
<>
<span x-init={`
<span
x-init={`
$notify(${JSON.stringify(notification)})
$el.remove();
`}
Expand Down Expand Up @@ -149,8 +150,11 @@ export const habitIdApiController = new Hono<{ Variables: AppVariables }>()
),
async ({ html, req }) => {
const { date, id } = req.valid("param");
const updatedExistingHabit = await habitService.updateDateInHistory(id, date);

const updatedExistingHabit = await habitService.updateDateInHistory(
id,
date
);

return html(
<HabitHistoryItem
habit={updatedExistingHabit}
Expand Down Expand Up @@ -214,35 +218,62 @@ export const habitApiController = new Hono<{ Variables: AppVariables }>()
return text("Please select another color than black", 400);
}

const [createdHabit, habitsCount] = await executeHandlerForSessionUser(
const createdHabit = await executeHandlerForSessionUser(
async (user) =>
Promise.all([
habitService.create({
...body,
userId: user.id,
}),
habitService.count(user.id),
]),
habitService.create({
...body,
userId: user.id,
}),
sessionUser
);

if (!createdHabit) {
res.headers.append("HX-Reswap", "innerHTML");
return text("An error occured", 500);
}
if (habitsCount === 0) {
res.headers.append("HX-Reswap", "outerHTML");
return html(<HabitList habits={[createdHabit]} />, 201);
}

const notification: Notification = {
type: "success",
message: "Habit created successfully",
};

// Refetch new habit list
const url = getURL(req);
const { limit, page, search } = getPaginationQueries(url);
const [habits, count] = await executeHandlerForSessionUser(
async (user) =>
search
? await habitService.findManyWithCountByTitle(
search,
user.id,
page > 1 ? page * limit : limit
)
: await habitService.findManyWithCountByUserId(
user.id,
page > 1 ? page * limit : limit
),
sessionUser
);

return html(
<HabitItem
item={createdHabit}
x-notification={{
type: "success",
message: "Habit created successfully",
}}
/>,
201
<>
<span
x-init={`
$notify(${JSON.stringify(notification)})
$el.remove();
`}
/>
{habits.length || search ? (
<HabitContainer
count={count}
habits={habits}
limit={limit}
searchValue={search}
/>
) : (
<NoHabits />
)}
</>
);
}
)
Expand Down Expand Up @@ -358,56 +389,56 @@ export const habitApiController = new Hono<{ Variables: AppVariables }>()
/>
);
})
.delete(
"/bulk",
zValidator("query", z.object({ items: z.array(z.string()) })),
async ({ req, html, get }) => {
const { items } = req.valid("query");
const deletedResults = await habitService.deleteBulkIds(items);
const notification: Notification = {
type: "success",
message: `${deletedResults.deletedCount} selected habits deleted successfully`,
};

// Refetch new habit list
const url = getURL(req);
const { limit, page, search } = getPaginationQueries(url);
const sessionUser = get("sessionUser");
const [habits, count] = await executeHandlerForSessionUser(
async (user) =>
search
? await habitService.findManyWithCountByTitle(
search,
user.id,
page > 1 ? page * limit : limit
)
: await habitService.findManyWithCountByUserId(
user.id,
page > 1 ? page * limit : limit
),
sessionUser
);
.delete(
"/bulk",
zValidator("query", z.object({ items: z.array(z.string()) })),
async ({ req, html, get }) => {
const { items } = req.valid("query");
const deletedResults = await habitService.deleteBulkIds(items);
const notification: Notification = {
type: "success",
message: `${deletedResults.deletedCount} selected habits deleted successfully`,
};

return html(
<>
<span
x-init={`
// Refetch new habit list
const url = getURL(req);
const { limit, page, search } = getPaginationQueries(url);
const sessionUser = get("sessionUser");
const [habits, count] = await executeHandlerForSessionUser(
async (user) =>
search
? await habitService.findManyWithCountByTitle(
search,
user.id,
page > 1 ? page * limit : limit
)
: await habitService.findManyWithCountByUserId(
user.id,
page > 1 ? page * limit : limit
),
sessionUser
);

return html(
<>
<span
x-init={`
$notify(${JSON.stringify(notification)})
$el.remove();
`}
/>
{habits.length || search ? (
<HabitContainer
count={count}
habits={habits}
limit={limit}
searchValue={search}
/>
) : (
<NoHabits />
)}
</>
);
}
)
.route("/:id", habitIdApiController);
{habits.length || search ? (
<HabitContainer
count={count}
habits={habits}
limit={limit}
searchValue={search}
/>
) : (
<NoHabits />
)}
</>
);
}
)
.route("/:id", habitIdApiController);
9 changes: 1 addition & 8 deletions src/script/alpine/data/habit/habit-item.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,12 @@
* @param {Object} props
* @param {string} props.tooltipInformation
* @param {string} props.itemId
* @param {import("$components/notifications.component").Notification} [props.xNotification]
* @return {import("alpinejs").AlpineComponent<HabitItemData>}
*/
export function habitItemData({itemId, tooltipInformation, xNotification}) {
export function habitItemData({itemId, tooltipInformation}) {
return {
itemId,
xNotification,
tooltipInformation,
init() {
if (this.xNotification) {
this.$notify(this.xNotification);
}
},
addItemToSet() {
this.itemIdsToDelete.add(this.itemId);
},
Expand Down