randt commited on
Commit
1ddbce4
β€’
1 Parent(s): b373fb9

Add 17 files

Browse files
.huskyrc.json ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ {
2
+ "hooks": {
3
+ "pre-commit": "lint-staged"
4
+ }
5
+ }
.lintstagedrc.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ {
2
+ "*.{js,jsx,ts,tsx}": "eslint --fix"
3
+ }
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,14 @@
1
  ---
2
- title: LessAPPNAMEgreater
3
- emoji: πŸ“‰
4
- colorFrom: green
5
- colorTo: red
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
  ---
2
+ license: apache-2.0
3
+ title: <APPNAME>
4
+ sdk: docker
5
+ emoji: πŸ‘¨β€πŸ’»
6
+ colorFrom: yellow
7
+ colorTo: green
 
8
  ---
9
 
10
+ This is a simple todo list app using NextJS and Tailwind CSS.
11
+
12
+ ## Getting Started
13
+
14
+ To get started, clone this repository and run
package.json ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "<APPNAME>",
3
+ "version": "1.0.0",
4
+ "description": "A simple todo list app using Next.js and Tailwind CSS",
5
+ "scripts": {
6
+ "dev": "next dev",
7
+ "build": "next build",
8
+ "start": "next start"
9
+ },
10
+ "dependencies": {
11
+ "@tailwindcss/typography": "2.2.1",
12
+ "@types/node": "17.0.22",
13
+ "@types/react": "18.2.15",
14
+ "@types/react-dom": "18.9.11",
15
+ "next": "12.0.1",
16
+ "react": "18.0.1",
17
+ "react-dom": "18.0.1",
18
+ "tailwindcss": "3.0.23",
19
+ "typescript": "5.1.6"
20
+ },
21
+ "devDependencies": {
22
+ "husky": "7.0.4",
23
+ "lint-staged": "12.1.5"
24
+ }
25
+ }
src/components/Footer.tsx ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from 'react';
2
+
3
+ const Footer = () => {
4
+ return (
5
+ <footer className="bg-gray-200 py-4 text-center">
6
+ <p>&copy; 2023 My Company</p>
7
+ </footer>
8
+ );
9
+ };
10
+
11
+ export default Footer;
src/components/Header.tsx ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from 'react';
2
+
3
+ const Header = ({pageTitle}) => {
4
+ return (
5
+ <header className="bg-gray-200 py-4 text-center">
6
+ <h1 className="text-2xl">{pageTitle}</h1>
7
+ </header>
8
+ );
9
+ };
10
+
11
+ export default Header;
src/components/Layout.tsx ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from 'react';
2
+ import Header from './Header';
3
+ import Footer from './Footer';
4
+
5
+ const Layout = ({pageTitle, children}) => {
6
+ return (
7
+ <section className="flex flex-col min-h-screen">
8
+ <Header pageTitle={pageTitle} />
9
+ <main className="flex-1">
10
+ {children}
11
+ </main>
12
+ <Footer />
13
+ </section>
14
+ );
15
+ };
16
+
17
+ export default Layout;
src/components/Task.tsx ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from 'react';
2
+
3
+ const Task = ({task}) => {
4
+ return (
5
+ <li className="flex">
6
+ <input type="checkbox" />
7
+ {task}
8
+ </li>
9
+ );
10
+ };
11
+
12
+ export default Task;
src/components/TodoList.tsx ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, {useState} from 'react';
2
+ import Task from '../components/Task';
3
+
4
+ const TodoList = () => {
5
+ const [tasks, setTasks] = useState([]);
6
+
7
+ const addTask = (task) => {
8
+ setTasks([...tasks, task]);
9
+ };
10
+
11
+ const handleKeyDown = (e) => {
12
+ if (e.key === 'Enter') {
13
+ addTask(e.target.value);
14
+ e.target.value = '';
15
+ }
16
+ };
17
+
18
+ return (
19
+ <section className="">
20
+ <h2 className="text-xl">Todo List</h2>
21
+ <div className="mt-4">
22
+ <input
23
+ type="text"
24
+ className="w-full h-full p-2"
25
+ placeholder="Add a task..."
26
+ onKeyDown={handleKeyDown}
27
+ />
28
+ </div>
29
+ <ul className="mt-4">
30
+ {tasks.map((task, index) => (
31
+ <li key={index}>
32
+ <Task task={task} />
33
+ </li>
34
+ ))}
35
+ </ul>
36
+ </section>
37
+ );
38
+ };
39
+
40
+ export default TodoList;
src/pages/api/addTask.ts ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { NextApiRequest, NextApiResponse } from 'next';
2
+
3
+ const handler = (req: NextApiRequest, res: NextApiResponse) => {
4
+ const task = {
5
+ title: req.body.tasks,
6
+ };
7
+
8
+ // Add task to API
9
+ fetch('https://api.example.com/tasks', {
10
+ method: 'POST',
11
+ body: JSON.stringify(task),
12
+ })
13
+ .then((response) => response.json())
14
+ .then((data) => {
15
+ res.json(data);
16
+ })
17
+ .catch((error) => {
18
+ console.error(error);
19
+ res.status(500).json({ message: 'Error adding task' });
20
+ });
21
+ };
22
+
23
+ export default handler;
src/pages/api/tasks.ts ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { NextApiRequest, NextApiResponse } from 'next';
2
+
3
+ const handler = (req: NextApiRequest, res: NextApiResponse) => {
4
+ const tasks = [];
5
+
6
+ // Fetch tasks from API
7
+ fetch('https://api.example.com/tasks')
8
+ .then((response) => response.json())
9
+ .then((data) => {
10
+ tasks = data;
11
+ res.json(tasks);
12
+ })
13
+ .catch((error) => {
14
+ console.error(error);
15
+ res.status(500).json({ message: 'Error fetching tasks' });
16
+ });
17
+ };
18
+
19
+ export default handler;
src/pages/index.tsx ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from 'react';
2
+ import Layout from '../components/Layout';
3
+ import TodoList from '../components/TodoList';
4
+
5
+ const HomePage = () => {
6
+ return (
7
+ <Layout pageTitle="Todo List">
8
+ <TodoList />
9
+ </Layout>
10
+ );
11
+ };
12
+
13
+ export default HomePage;
src/public/index.html ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Todo List</title>
7
+ <link rel="stylesheet" href="styles.css" />
8
+ </head>
9
+ <body>
10
+ <div id="root"></div>
11
+ <script defer src="bundle.js"></script>
12
+ </body>
13
+ </html>
src/public/styles.css ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ /* Your custom CSS goes here */
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
+ }