Skip to content
Open
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
24 changes: 24 additions & 0 deletions .github/workflows/production.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Vercel Production Deployment
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
on:
push:
branches:
- main
jobs:
Deploy-Production:
runs-on: ubuntu-latest
steps:
- uses: pnpm/action-setup@v4
with:
version: 10
- uses: actions/checkout@v2
- name: Install Vercel CLI
run: npm install --global vercel@latest
- name: Pull Vercel Environment Information
run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
- name: Build Project Artifacts
run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}
- name: Deploy Project Artifacts to Vercel
run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}
11 changes: 6 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,17 @@
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
"react-dom": "^18.2.0",
"zustand": "^5.0.3"
},
"devDependencies": {
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"typescript": "^4.6.0",
"vite": "^4.0.0",
"@vitejs/plugin-react": "^3.0.0",
"tailwindcss": "^3.0.0",
"autoprefixer": "^10.0.0",
"postcss": "^8.0.0",
"autoprefixer": "^10.0.0"
"tailwindcss": "^3.0.0",
"typescript": "^4.6.0",
"vite": "^4.0.0"
}
}
26 changes: 26 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 0 additions & 30 deletions src/components/TaskItem.tsx

This file was deleted.

89 changes: 0 additions & 89 deletions src/components/TaskManager.tsx

This file was deleted.

47 changes: 47 additions & 0 deletions src/components/TaskManager/DeleteTaskModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from "react";
import useTaskStore from "../../store/taskStore";

const DeleteTaskModal = () => {
const deleteTask = useTaskStore((state) => state.deleteTask);
const deletingTask = useTaskStore((state) => state.deletingTask);
const setDeletingTask = useTaskStore((state) => state.setDeletingTask);

const handleCloseModal = () => {
setDeletingTask(null);
};

if (!deletingTask) return null;

return (
<div
className="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50"
onClick={handleCloseModal}
>
<div
className="bg-white p-6 rounded-lg shadow-lg w-80 text-center animate-fadeIn"
onClick={(e) => e.stopPropagation()}
>
<p className="text-lg font-semibold">Are you sure?</p>
<p className="text-gray-600 mb-4">
Do you really want to delete the task <i>{deletingTask.title}</i>?
</p>
<div className="flex justify-center gap-4">
<button
onClick={handleCloseModal}
className="px-4 py-2 bg-gray-300 rounded hover:bg-gray-400 transition"
>
Cancel
</button>
<button
onClick={() => deleteTask(deletingTask.id)}
className="px-4 py-2 bg-red-500 text-white rounded hover:bg-red-600 transition"
>
Delete
</button>
</div>
</div>
</div>
);
};

export default DeleteTaskModal;
27 changes: 27 additions & 0 deletions src/components/TaskManager/TaskFilter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from "react";
import { Filter } from "../../types/filter";
import useTaskStore from "../../store/taskStore";

const TaskFilter = () => {
const currentFilter = useTaskStore((state) => state.currentFilter);
const setFilter = useTaskStore((state) => state.setFilter);
const filters: Filter[] = ["all", "completed", "pending"];

return (
<div className="flex justify-around mb-4">
{filters.map((filter) => (
<button
key={filter}
onClick={() => setFilter(filter)}
className={`text-gray-700 w-1/2 p-1 duration-200 ${
currentFilter === filter ? "font-bold bg-slate-300" : "bg-slate-200"
}`}
>
{filter.charAt(0).toUpperCase() + filter.slice(1)}
</button>
))}
</div>
);
};

export default TaskFilter;
37 changes: 37 additions & 0 deletions src/components/TaskManager/TaskForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React, { useState } from "react";
import useTaskStore from "../../store/taskStore";

const TaskForm = () => {
const tasks = useTaskStore((state) => state.tasks);
const addTask = useTaskStore((state) => state.addTask);
const [newTaskTitle, setNewTaskTitle] = useState("");

const handleAddTask = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();

if (newTaskTitle.trim() === "") return;

const existingTask = tasks.find((task) => task.title === newTaskTitle);
if (existingTask) return;

addTask(newTaskTitle);
setNewTaskTitle("");
};

return (
<form onSubmit={handleAddTask} className="mb-4 flex">
<input
type="text"
placeholder="New task..."
value={newTaskTitle}
onChange={(e) => setNewTaskTitle(e.target.value)}
className="flex-grow border rounded-l py-2 px-3"
/>
<button type="submit" className="bg-blue-500 text-white px-4 rounded-r">
Add
</button>
</form>
);
};

export default TaskForm;
34 changes: 34 additions & 0 deletions src/components/TaskManager/TaskList/TaskItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from "react";
import { Task } from "../../../types/task";
import useTaskStore from "../../../store/taskStore";

const TaskItem = ({ task }: { task: Task }) => {
const toggleTaskCompletion = useTaskStore(
(state) => state.toggleTaskCompletion
);
const setDeletingTask = useTaskStore((state) => state.setDeletingTask);

return (
<>
<li className="flex items-center justify-between border-b py-2">
<span
onClick={() => toggleTaskCompletion(task.id)}
className={`cursor-pointer select-none duration-200 active:scale-110 ${
task.completed ? "line-through text-green-500" : "text-black"
}`}
>
{task.title}
</span>

<button
onClick={() => setDeletingTask(task)}
className="bg-red-500 text-white px-2 py-1 rounded hover:bg-red-600 transition"
>
Delete
</button>
</li>
</>
);
};

export default TaskItem;
24 changes: 24 additions & 0 deletions src/components/TaskManager/TaskList/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from "react";
import TaskItem from "./TaskItem";
import useTaskStore from "../../../store/taskStore";

const TaskList = () => {
const tasks = useTaskStore((state) => state.tasks);
const currentFilter = useTaskStore((state) => state.currentFilter);

const filteredTasks = tasks.filter((task) => {
if (currentFilter === "completed") return task.completed === true;
if (currentFilter === "pending") return task.completed === false;
return true;
});

return (
<ul>
{filteredTasks.map((task) => (
<TaskItem key={task.id} task={task} />
))}
</ul>
);
};

export default TaskList;
Loading