No tasks yet...
;
-
- return tasks.map((task, index) => (
-
-
+ return (
+
+
+ {tasks.length === 0 ? (
+ No tasks yet...
+ ) : (
+
+ {tasks.map((task, index) => (
+
+ ))}
+
+ )}
+
- ));
+ );
};
export default TaskList;
diff --git a/src/contexts/UserContextProvider.tsx b/src/contexts/UserContextProvider.tsx
index d0cfa46..7a92f95 100644
--- a/src/contexts/UserContextProvider.tsx
+++ b/src/contexts/UserContextProvider.tsx
@@ -8,6 +8,8 @@ export const UserContextProvider = ({
}: Readonly<{ children: React.ReactNode }>) => {
const userProps = useUsers();
+ if(userProps.users == null && !userProps.loading) return
Failed to load users
;
+
return (
{children}
diff --git a/src/css/MainPage.css b/src/css/MainPage.css
new file mode 100644
index 0000000..5247534
--- /dev/null
+++ b/src/css/MainPage.css
@@ -0,0 +1,25 @@
+.task-form {
+ padding: 10px;
+ display: flex;
+ flex-direction: row;
+ gap: 10px;
+ width: 50vw;
+ max-width: 1000px;
+ justify-content: stretch;
+}
+
+.task-form > * {
+ flex: 1;
+}
+
+.task-list {
+ margin-top: 20px;
+}
+
+.task-list-item {
+ cursor: pointer;
+}
+
+.task-list-item:hover {
+ background-color: #f0f0f0;
+}
diff --git a/src/hooks/useUsers.ts b/src/hooks/useUsers.ts
index e144c67..4c41f4a 100644
--- a/src/hooks/useUsers.ts
+++ b/src/hooks/useUsers.ts
@@ -23,8 +23,8 @@ export function useUsers() {
const data = parseUserData(await response.json());
setUsers(data);
setError(null);
- } catch(error) {
- console.error(error)
+ } catch (error) {
+ console.error(error);
setError("An error occurred during data fetching.");
}
setLoading(false);
diff --git a/src/pages/MainPage.tsx b/src/pages/MainPage.tsx
index b17f9eb..7d16986 100644
--- a/src/pages/MainPage.tsx
+++ b/src/pages/MainPage.tsx
@@ -1,6 +1,7 @@
import React from "react";
import TaskForm from "../components/TaskForm";
import TaskList from "../components/TaskList";
+import "@/css/MainPage.css";
const MainPage: React.FC = () => {
return (
diff --git a/src/pages/NotFound.tsx b/src/pages/NotFound.tsx
index b40c576..49d6c76 100644
--- a/src/pages/NotFound.tsx
+++ b/src/pages/NotFound.tsx
@@ -1,7 +1,7 @@
import React from "react";
const NotFound: React.FC = () => {
- return Not found
;
+ return Page not found
;
};
export default NotFound;
diff --git a/src/utils/types.ts b/src/utils/types.ts
index 7c5dc37..8825656 100644
--- a/src/utils/types.ts
+++ b/src/utils/types.ts
@@ -10,6 +10,7 @@ export type Task = {
finished: boolean;
assignedTo: number; // User ID
createdAt: React.RefObject;
+ due: string;
text: string;
};
diff --git a/src/utils/validation.ts b/src/utils/validation.ts
new file mode 100644
index 0000000..9f2acdf
--- /dev/null
+++ b/src/utils/validation.ts
@@ -0,0 +1,11 @@
+import type { Dayjs } from "dayjs";
+
+export function validateDueDate(value: Dayjs): string | boolean {
+ const selected = new Date(value.format("YYYY-MM-DD"));
+ const now = new Date();
+ now.setHours(0, 0, 0, 0);
+
+ if (selected < now) return "Due date cannot be in the past";
+
+ return true;
+}
diff --git a/tsconfig.app.json b/tsconfig.app.json
index c9ccbd4..a311297 100644
--- a/tsconfig.app.json
+++ b/tsconfig.app.json
@@ -1,27 +1,27 @@
{
- "compilerOptions": {
- "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
- "target": "ES2020",
- "useDefineForClassFields": true,
- "lib": ["ES2020", "DOM", "DOM.Iterable"],
- "module": "ESNext",
- "skipLibCheck": true,
+ "compilerOptions": {
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+ "target": "ES2020",
+ "useDefineForClassFields": true,
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
+ "module": "ESNext",
+ "skipLibCheck": true,
- /* Bundler mode */
- "moduleResolution": "bundler",
- "allowImportingTsExtensions": true,
- "verbatimModuleSyntax": true,
- "moduleDetection": "force",
- "noEmit": true,
- "jsx": "react-jsx",
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "verbatimModuleSyntax": true,
+ "moduleDetection": "force",
+ "noEmit": true,
+ "jsx": "react-jsx",
- /* Linting */
- "strict": true,
- "noUnusedLocals": true,
- "noUnusedParameters": true,
- "erasableSyntaxOnly": true,
- "noFallthroughCasesInSwitch": true,
- "noUncheckedSideEffectImports": true
- },
- "include": ["src"]
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "erasableSyntaxOnly": true,
+ "noFallthroughCasesInSwitch": true,
+ "noUncheckedSideEffectImports": true
+ },
+ "include": ["src"]
}
diff --git a/vite.config.ts b/vite.config.ts
index 2328e17..38b6de1 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -1,7 +1,13 @@
-import { defineConfig } from 'vite'
-import react from '@vitejs/plugin-react-swc'
+import { defineConfig } from "vite";
+import react from "@vitejs/plugin-react-swc";
+import path from 'path';
// https://vite.dev/config/
export default defineConfig({
- plugins: [react()],
-})
+ plugins: [react()],
+ resolve: {
+ alias: {
+ "@": path.resolve(__dirname, "./src"),
+ },
+ },
+});