Skip to content

Jawad A. - #2

Open
jivvyjams wants to merge 9 commits into
HackYourAssignment:mainfrom
jivvyjams:main
Open

jivvyjams wants to merge 9 commits into
HackYourAssignment:mainfrom
jivvyjams:main

Conversation

@jivvyjams

Copy link
Copy Markdown

No description provided.

@rafasilpereira rafasilpereira left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great to see you went beyond the assignment by also scaffolding task-list-ts! For future PRs, it's better to keep each task in its own PR — having both apps in one diff makes it harder to review. The actual assignment (task-1) would be much easier to evaluate on its own.

Comment thread task-1/src/types.ts
id: string;
title: string;
description: string;
completed: boolean;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add also here createdAt

Comment thread task-1/src/types.ts
onDelete(id: string): void;
onEdit(id: string, title: string, description: string): void;
onFilter(status: FilterStatus): void;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good approach on creating types.ts file!

Comment thread task-1/src/main.ts
Comment on lines 10 to 12
function render() {
appView.render(taskManager.getFiltered(currentFilter), currentFilter);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No return type specified here

Comment on lines +48 to 58
render(tasks: Task[], activeFilter: FilterStatus) {
this.taskListView.render(tasks);
this.updateFilterButtons(activeFilter);
}

updateFilterButtons(activeFilter) {
const buttons = this.filterBar.querySelectorAll("[data-filter]");
updateFilterButtons(activeFilter: FilterStatus) {
const buttons =
this.filterBar.querySelectorAll<HTMLButtonElement>("[data-filter]");
for (const btn of buttons) {
btn.classList.toggle("active", btn.dataset.filter === activeFilter);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both methods doesn't have a return type

Comment on lines +4 to +49
export function enterEditMode(
li: HTMLLIElement,
task: Task,
handlers: TaskHandlers,
) {
li.innerHTML = String.raw`
<input type="checkbox"${task.completed ? " checked" : ""}>
<div class="edit-form">
<input type="text" class="edit-title" value="${escapeHtml(task.title)}">
<input type="text" class="edit-desc" value="${escapeHtml(task.description)}">
<div class="edit-actions">
<button class="save-btn">Save</button>
<button class="cancel-btn">Cancel</button>
</div>
</div>
`;

const checkbox = li.querySelector<HTMLInputElement>(
"input[type='checkbox']",
)!;
const titleInput = li.querySelector<HTMLInputElement>(".edit-title")!;
const descInput = li.querySelector<HTMLInputElement>(".edit-desc")!;

checkbox.addEventListener("change", () => handlers.onToggle(task.id));

li.querySelector<HTMLButtonElement>(".save-btn")!.addEventListener(
"click",
() => {
const newTitle = titleInput.value.trim();
if (!newTitle) return;
handlers.onEdit(task.id, newTitle, descInput.value.trim());
},
);

li.querySelector<HTMLButtonElement>(".cancel-btn")!.addEventListener(
"click",
() => {
const activeFilter =
(document.querySelector<HTMLButtonElement>(".filter-bar .active")
?.dataset.filter as FilterStatus) ?? "all";
handlers.onFilter(activeFilter);
},
);

titleInput.focus();
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a common pattern, even the function is no return, add void

Comment thread task-1/src/main.ts
Comment on lines 15 to 17
onAdd(title, description) {
taskManager.addTask(title, description);
render();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All parameters doesn't have a type in the methods

Comment on lines +37 to +38
for (const li of this.root.querySelectorAll<HTMLLIElement>(".task-item")) {
const id = (li as HTMLLIElement).dataset.id!;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cast in line 38 is redudant since you are already specifying that you want a list element in line 37

Comment on lines +5 to +6
filterBar: HTMLDivElement;
taskListView: TaskListView;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recommend the reading for encapsulation in TypeScript and how to protect the objects

@rafasilpereira rafasilpereira left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The build generates asset paths as /assets/index.js (absolute), which breaks when dist/index.html is opened and that doesn't root at the project folder. Adding a vite.config.ts with base: './' fixes this so the built app works anywhere:

import { defineConfig } from 'vite'
export default defineConfig({
  base: './',
})

@rafasilpereira rafasilpereira added Reviewed This assignment has been reivewed by a mentor and a feedback has been provided and removed Review in progress labels May 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Reviewed This assignment has been reivewed by a mentor and a feedback has been provided

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants