Mikelue commited on
Commit
1512e66
1 Parent(s): fa509aa

Add 12 files

Browse files
Dockerfile ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ FROM node:18-alpine AS base
3
+
4
+ # Install dependencies only when needed
5
+ FROM base AS deps
6
+ # Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
7
+ RUN apk add --no-cache libc6-compat
8
+ WORKDIR /app
9
+
10
+ # Install dependencies based on the preferred package manager
11
+ COPY package.json package-lock.json* ./
12
+ RUN npm install
13
+
14
+ # Uncomment the following lines if you want to use a secret at buildtime,
15
+ # for example to access your private npm packages
16
+ # RUN --mount=type=secret,id=HF_EXAMPLE_SECRET,mode=0444,required=true # $(cat /run/secrets/HF_EXAMPLE_SECRET)
17
+
18
+ # Rebuild the source code only when needed
19
+ FROM base AS builder
20
+ WORKDIR /app
21
+ COPY --from=deps /app/node_modules ./node_modules
22
+ COPY . .
23
+
24
+ # Next.js collects completely anonymous telemetry data about general usage.
25
+ # Learn more here: https://nextjs.org/telemetry
26
+ # Uncomment the following line in case you want to disable telemetry during the build.
27
+ # ENV NEXT_TELEMETRY_DISABLED 1
28
+
29
+ RUN npm run build
30
+
31
+ # Production image, copy all the files and run next
32
+ FROM base AS runner
33
+ WORKDIR /app
34
+
35
+ ENV NODE_ENV production
36
+ # Uncomment the following line in case you want to disable telemetry during runtime.
37
+ # ENV NEXT_TELEMETRY_DISABLED 1
38
+
39
+ RUN addgroup --system --gid 1001 nodejs
40
+ RUN adduser --system --uid 1001 nextjs
41
+
42
+ COPY --from=builder /app/public ./public
43
+
44
+ # Automatically leverage output traces to reduce image size
45
+ # https://nextjs.org/docs/advanced-features/output-file-tracing
46
+ COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
47
+ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
48
+ COPY --from=builder --chown=nextjs:nodejs /app/.next/cache ./.next/cache
49
+ # COPY --from=builder --chown=nextjs:nodejs /app/.next/cache/fetch-cache ./.next/cache/fetch-cache
50
+
51
+ USER nextjs
52
+
53
+ EXPOSE 3000
54
+
55
+ ENV PORT 3000
56
+
57
+ CMD ["node", "server.js"]
README.md CHANGED
@@ -1,11 +1,26 @@
1
- ---
2
- title: Sf B5f
3
- emoji: 🏢
4
- colorFrom: indigo
5
- colorTo: pink
6
- sdk: static
7
- pinned: false
8
- license: mit
9
- ---
10
-
11
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {{< TOC >}}
2
+
3
+ # {{< Warning >}}
4
+ `<APPNAME>` is a simple todo list app built using NextJS and Progressive Web Apps. The app is designed to work on
5
+ Android devices and has a minimalistic design to provide a clean and easy-to-use interface.
6
+
7
+ ## Features
8
+
9
+ * Create new tasks with a title, deadline, and description
10
+ * View tasks in a list with sorting options
11
+ * Mark tasks as complete or incomplete
12
+ * Delete tasks
13
+
14
+ ## Future Plans
15
+
16
+ * Implement a dark mode theme
17
+ * Add more advanced features such as reminders, notifications, and a calendar view
18
+ * Optimize the app for better performance on mobile devices
19
+
20
+ ## Contributing
21
+
22
+ Contributions are welcome! If you have any ideas or suggestions, feel free to open an issue or pull request.
23
+
24
+ ## License
25
+
26
+ MIT
cypress/fixtures/seedData.json ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "id": 1,
4
+ "title": "First task",
5
+ "deadline": "2024-01-01",
6
+ "description": "A task"
7
+ },
8
+ {
9
+ "id": 2,
10
+ "title": "Second task",
11
+ "deadline": "2023-01-01",
12
+ "description": "Another task"
13
+ },
14
+ {
15
+ "id": 3,
16
+ "title": "Third task",
17
+ "deadline": "2023-01-02",
18
+ "description": "A third task"
19
+ }
20
+ ]
cypress/integration/index.spec.js ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ describe("Complete App", () => {
2
+ beforeEach(() => cy.visit("/"));
3
+
4
+ it("displays the title", () => {
5
+ cy.get("h1").should("have.text", "Todo List");
6
+ });
7
+
8
+ it("displays the create task form", () => {
9
+ cy.get("form").should("have.attr", {
10
+ "method": "POST",
11
+ "action": "/task/create",
12
+ });
13
+ cy.get("input[name=title]").should("be.visible");
14
+ cy.get("input[name=deadline]").should("be.visible");
15
+ cy.get("textarea[name=description]").should("be.visible");
16
+ cy.get("button[type=submit]").should("be.visible");
17
+ });
18
+
19
+ it("allows the user to create a new task", () => {
20
+ const newTask = {
21
+ title: "New task",
22
+ deadline: "2024-01-01",
23
+ description: "A new task"
24
+ };
25
+ cy.get("input[name=title]").type(newTask.title);
26
+ cy.get("input[name=deadline]").type(newTask.deadline);
27
+ cy.get("textarea[name=description]").type(newTask.description);
28
+ cy.get("button[type=submit]").click();
29
+
30
+ cy.get("h2").should("have.text", "Tasks");
31
+ cy.get("li").should("have.length", 1);
32
+ cy.get("li:first").should("contain.text", newTask.title);
33
+ cy.get("li:first").should("contain.text", newTask.deadline);
34
+ cy.get("li:first").should("contain.text", newTask.description);
35
+ });
36
+
37
+ it("allows the user to mark a task as complete", () => {
38
+ cy.get("input[type=checkbox]").should("be.visible");
39
+ cy.get("input[type=checkbox]").click();
40
+ cy.get("input[type=checkbox]").should("be.checked");
41
+ });
42
+
43
+ it("allows the user to delete a task", () => {
44
+ cy.get("li:first").should("contain.text", "New task");
45
+ cy.get("li:first").find("button.delete-task").click();
46
+ cy.get("li:first").find("button.delete-task").should("have.text", "Delete");
47
+ cy.get("li:first").should("contain.text", "Task deleted");
48
+ cy.get("li").should("have.length", 0);
49
+ });
50
+ });
package.json ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "<APPNAME>",
3
+ "version": "1.0.0",
4
+ "description": "A simple todo list app using nextjs with progressive web app that can be installed on Android",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "start": "next dev",
8
+ "build": "next build",
9
+ "test": "jest",
10
+ "eject": "next eject"
11
+ },
12
+ "dependencies": {
13
+ "@types/next": "12.3.5",
14
+ "@types/node": "20.4.2",
15
+ "@types/react": "18.2.15",
16
+ "@types/react-dom": "18.2.7",
17
+ "next": "12.3.5",
18
+ "react": "18.2.0",
19
+ "react-dom": "18.2.0"
20
+ },
21
+ "devDependencies": {
22
+ "@types/jest": "28.2.2",
23
+ "jest": "28.2.2",
24
+ "tsc": "5.1.5"
25
+ }
26
+ }
public/manifest.json ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "short_name": "<APPNAME>",
3
+ "name": "<APPNAME> - A simple todo list app using nextjs with progressive web app that can be installed on Android",
4
+ "description": "A simple todo list app using nextjs with progressive web app that can be installed on Android",
5
+ "icons": [
6
+ {
7
+ "src": "icons/icon-72x72.png",
8
+ "sizes": "72x72",
9
+ "type": "image/png"
10
+ },
11
+ {
12
+ "src": "icons/icon-96x96.png",
13
+ "sizes": "96x96",
14
+ "type": "image/png"
15
+ },
16
+ {
17
+ "src": "icons/icon-128x128.png",
18
+ "sizes": "128x128",
19
+ "type": "image/png"
20
+ },
21
+ {
22
+ "src": "icons/icon-144x144.png",
23
+ "sizes": "144x144",
24
+ "type": "image/png"
25
+ },
26
+ {
27
+ "src": "icons/icon-152x152.png",
28
+ "sizes": "152x152",
29
+ "type": "image/png"
30
+ },
31
+ {
32
+ "src": "icons/icon-192x192.png",
33
+ "sizes": "192x192",
34
+ "type": "image/png"
35
+ },
36
+ {
37
+ "src": "icons/icon-256x256.png",
38
+ "sizes": "256x256",
39
+ "type": "image/png"
40
+ },
41
+ {
42
+ "src": "icons/icon-384x384.png",
43
+ "sizes": "384x384",
44
+ "type": "image/png"
45
+ },
46
+ {
47
+ "src": "icons/icon-512x512.png",
48
+ "sizes": "512x512",
49
+ "type": "image/png"
50
+ }
51
+ ],
52
+ "start_url": "/",
53
+ "display": "standalone",
54
+ "theme_color": "#000000",
55
+ "background_color": "#ffffff"
56
+ }
src/index.css ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ html,
2
+ body {
3
+ margin: 0;
4
+ padding: 0;
5
+ font-family: Arial, sans-serif;
6
+ background-color: var(--background-color);
7
+ }
8
+
9
+ .container {
10
+ margin: 0;
11
+ padding: 0;
12
+ display: flex;
13
+ flex-flow: row wrap;
14
+ justify-content: space-evenly;
15
+ }
16
+
17
+ .task-container {
18
+ background-color: var(--primary-lightgray-color);
19
+ box-shadow: 0px 0px 10px 0px rgba(167, 167, 167, 0.2);
20
+ border-radius: 0.25rem;
21
+ padding: 1rem;
22
+ margin-bottom: 1rem;
23
+ }
24
+
25
+ .task-title {
26
+ font-weight: bold;
27
+ font-size: 1.25rem;
28
+ line-height: 1.5;
29
+ color: var(--text-color);
30
+ }
31
+
32
+ .task-deadline {
33
+ font-size: 0.75rem;
34
+ line-height: 1.25;
35
+ color: var(--text-color);
36
+ }
37
+
38
+ .task-description {
39
+ font-size: 0.875rem;
40
+ line-height: 1.25;
41
+ color: var(--text-color);
42
+ }
43
+
44
+ .task-field {
45
+ width: 100%;
46
+ outline: none;
47
+ background-color: var(--primary-beige-color);
48
+ padding: 0.5rem;
49
+ border: none;
50
+ border-radius: 0.25rem;
51
+ text-align: center;
52
+ }
53
+
54
+ .task-button {
55
+ display: inline-block;
56
+ width: 100%;
57
+ font-size: 1.25rem;
58
+ background-color: var(--primary-color);
59
+ color: #fff;
60
+ border: none;
61
+ cursor: pointer;
62
+ padding: 1rem;
63
+ transition: background-color 0.3s ease;
64
+ }
65
+
66
+ .task-button:hover {
67
+ background-color: var(--primary-color);
68
+ color: #fff;
69
+ }
src/pages/index.tsx ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import styles from "../styles.module.css";
2
+
3
+ const Home = () => {
4
+ return (
5
+ <div className="text-gray-900 text-center">
6
+ <h1 className="text-6xl m-20 mb-6 font-bold">Todo List</h1>
7
+ <div className="min-h-$screen-2 bg-white px-6 py-4">
8
+ <h2 className="text-5xl font-medium">Create a New Task:</h2>
9
+ <form className="mx-auto w-full md:w-3/4">
10
+ <input
11
+ type="text"
12
+ className="block bg-white text-gray-900 font-medium text-xl mb-2 mt-4"
13
+ placeholder="Task Title"
14
+ />
15
+ <input
16
+ type="date"
17
+ className="block bg-white text-gray-900 font-medium text-sm mb-2 mt-4"
18
+ placeholder="Task Deadline"
19
+ />
20
+ <button className="block font-medium text-sm text-white transition duration-150 ease-in-out bg-blue-500 hover:bg-blue-600 border-blue-500 hover:border-blue-600 font-logo rounded px-2 mt-6 py-2">
21
+ Create Task
22
+ </button>
23
+ </form>
24
+ </div>
25
+ </div>
26
+ );
27
+ };
28
+
29
+ export { Home };
src/styles.module.css ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @import "./variables.css";
2
+
3
+ .container {
4
+ display: grid;
5
+ grid-template-columns: repeat(12, 1fr);
6
+ gap: 2rem;
7
+ }
8
+
9
+ .task-container {
10
+ border-radius: 0.25rem;
11
+ background-color: #fff;
12
+ padding: 1rem;
13
+ }
14
+
15
+ .task-title {
16
+ font-weight: bold;
17
+ font-size: 1.25rem;
18
+ }
19
+
20
+ .task-deadline {
21
+ font-size: 0.875rem;
22
+ }
23
+
24
+ .task-description {
25
+ font-size: 0.875rem;
26
+ }
27
+
28
+ .task-field {
29
+ width: 100%;
30
+ outline: none;
31
+ background-color: #f5f5f5;
32
+ padding: 0.5rem;
33
+ border: none;
34
+ border-radius: 0.25rem;
35
+ text-align: center;
36
+ }
37
+
38
+ .task-button {
39
+ display: inline-block;
40
+ width: 100%;
41
+ font-size: 1.25rem;
42
+ background-color: #3498db;
43
+ color: #fff;
44
+ border: none;
45
+ cursor: pointer;
46
+ padding: 1rem;
47
+ transition: background-color 0.3s ease;
48
+ }
49
+
50
+ .task-button:hover {
51
+ background-color: #555;
52
+ color: #fafafa;
53
+ }
src/variables.css ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ @tailwind base;
2
+ @tailwind components;
3
+
4
+ :root {
5
+ --text-color: #4e4c4d;
6
+ --primary-color: #159969;
7
+ --primary-lightgray-color: #f1f1f1;
8
+ --primary-beige-color: #f7f7f7;
9
+ --background-color: #ffffff;
10
+ }
test/test.js ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from "react";
2
+ import renderer from "react-test-renderer";
3
+ import MyComponent from "../components/MyComponent";
4
+
5
+ describe("MyComponent", () => {
6
+ it("renders correctly", () => {
7
+ const tree = renderer.create(<MyComponent />).toJSON();
8
+ expect(tree).toMatchSnapshot();
9
+ });
10
+ });
tsconfig.json ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": ["dom", "dom.iterable", "esnext"],
5
+ "allowJs": true,
6
+ "skipLibCheck": true,
7
+ "strict": true,
8
+ "forceConsistentCasingInFileNames": true,
9
+ "noEmit": true,
10
+ "esModuleInterop": true,
11
+ "module": "esnext",
12
+ "moduleResolution": "node",
13
+ "resolveJsonModule": true,
14
+ "isolatedModules": true,
15
+ "jsx": "preserve",
16
+ "incremental": true,
17
+ "plugins": [
18
+ {
19
+ "name": "next"
20
+ }
21
+ ],
22
+ "paths": {
23
+ "@/*": ["./src/*"]
24
+ }
25
+ },
26
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
27
+ "exclude": ["node_modules"]
28
+ }