Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
712a53c9bc | |||
997803149a | |||
c8bdd9e444 | |||
9e61855edb | |||
fe13f05ab9 | |||
e2a7e9fb17 | |||
3986fc49ee | |||
67b2dcc051 |
36
.github/workflows/codeql-analysis.yml
vendored
Normal file
36
.github/workflows/codeql-analysis.yml
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ main ]
|
||||
schedule:
|
||||
- cron: '19 9 * * 2'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'javascript' ]
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
@ -1,7 +1,7 @@
|
||||
# Simple TODO application
|
||||
|
||||
<p align="center">
|
||||
<img src="https://github.com/dm1sh/toodo/raw/main/logo.svg" alt="TooDo logo" width="150px">
|
||||
<img src="./logo.png" alt="TooDo logo" width="150px">
|
||||
</p>
|
||||
|
||||
## Overview
|
||||
|
@ -3,7 +3,12 @@
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>React application</title>
|
||||
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
|
||||
<link rel="apple-touch-icon" href="/pwa-192x192.png" />
|
||||
<link rel="mask-icon" href="/favicon.svg" color="#FFFFFF" />
|
||||
<meta name="msapplication-TileColor" content="#FFFFFF" />
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
<title>TooDo</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
93
logo.svg
93
logo.svg
@ -1,93 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="512"
|
||||
height="351"
|
||||
viewBox="0 0 135.46666 92.868752"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
|
||||
sodipodi:docname="logo.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#999999"
|
||||
borderopacity="1"
|
||||
inkscape:pageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:document-units="px"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
width="512px"
|
||||
inkscape:zoom="1.4142136"
|
||||
inkscape:cx="181.01934"
|
||||
inkscape:cy="141.42136"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1000"
|
||||
inkscape:window-x="-11"
|
||||
inkscape:window-y="-11"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1"
|
||||
showguides="true" />
|
||||
<defs
|
||||
id="defs2" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<rect
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:8.16147;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
||||
id="rect3999"
|
||||
width="135.46666"
|
||||
height="92.868752"
|
||||
x="0"
|
||||
y="0" />
|
||||
<path
|
||||
id="rect846"
|
||||
style="color:#000000;fill:#000000;stroke-width:2.25708;-inkscape-stroke:none"
|
||||
d="M 7.937444,4.545348 V 7.9309728 H 28.815465 V 80.157642 h 3.385626 V 7.9309728 H 53.079112 V 4.545348 Z" />
|
||||
<path
|
||||
style="color:#000000;fill:#000000;stroke-width:0.85307;stroke-miterlimit:0;-inkscape-stroke:none"
|
||||
d="m 51.950372,11.315964 c -9.017447,0 -16.363299,7.347496 -16.363299,16.364915 0,9.017419 7.345852,16.36325 16.363299,16.36325 9.017448,0 16.364966,-7.345831 16.364966,-16.36325 0,-9.017419 -7.347518,-16.364915 -16.364966,-16.364915 z m 0,3.385615 c 7.187722,0 12.979341,5.791601 12.979341,12.9793 0,7.1877 -5.791619,12.977635 -12.979341,12.977635 -7.187722,0 -12.977674,-5.789935 -12.977674,-12.977635 0,-7.187699 5.789952,-12.9793 12.977674,-12.9793 z"
|
||||
id="path1247" />
|
||||
<path
|
||||
style="color:#000000;fill:#000000;stroke-width:0.853071;stroke-miterlimit:0;-inkscape-stroke:none"
|
||||
d="m 51.950372,47.429933 c -9.017447,0 -16.363299,7.345852 -16.363299,16.363299 -3e-6,9.017445 7.34585,16.364962 16.363299,16.364962 9.017449,0 16.364969,-7.347517 16.364966,-16.364962 0,-9.017447 -7.347518,-16.363299 -16.364966,-16.363299 z m 0,3.385625 c 7.187722,0 12.979341,5.789952 12.979341,12.977674 2e-6,7.187723 -5.791618,12.979337 -12.979341,12.979337 -7.187722,0 -12.977676,-5.791614 -12.977674,-12.979337 0,-7.187722 5.789952,-12.977674 12.977674,-12.977674 z"
|
||||
id="path1247-9" />
|
||||
<path
|
||||
id="path1247-8"
|
||||
style="color:#000000;fill:#000000;stroke-width:0.853071;stroke-miterlimit:0;-inkscape-stroke:none"
|
||||
d="m 75.05173,11.316158 v 4.4e-4 h -3.35168 v 68.841044 h 3.35168 v 4.52e-4 c 0.01135,0 0.0226,-4.52e-4 0.03394,-4.52e-4 8.888602,-0.01824 16.143403,-7.174814 16.324619,-16.025292 h 0.0049 V 27.567599 h -0.0018 C 91.35203,18.602098 84.031302,11.316158 75.05173,11.316158 Z m 0.03394,3.386066 c 7.171954,0.01824 12.943405,5.802297 12.943405,12.978669 h 4.51e-4 v 36.112454 h -4.51e-4 c 0,7.176372 -5.771451,12.960421 -12.943405,12.97867 z" />
|
||||
<path
|
||||
style="color:#000000;fill:#000000;stroke-width:0.853071;stroke-miterlimit:0;-inkscape-stroke:none"
|
||||
d="m 111.16382,48.821171 c -9.01744,-2e-6 -16.363297,7.345851 -16.363297,16.3633 -2e-6,9.017454 7.345857,16.363298 16.363297,16.363298 9.01746,0 16.36497,-7.345844 16.36496,-16.363298 1e-5,-9.017449 -7.34751,-16.363302 -16.36496,-16.3633 z m 0,3.385625 c 7.18773,-2e-6 12.97935,5.789952 12.97934,12.977675 1e-5,7.187728 -5.79161,12.977673 -12.97934,12.977673 -7.18772,0 -12.977672,-5.789945 -12.977672,-12.977673 0,-7.187723 5.789952,-12.977677 12.977672,-12.977675 z"
|
||||
id="path1247-3" />
|
||||
<rect
|
||||
style="fill:#000000;fill-opacity:1;stroke-width:1.29937"
|
||||
id="rect2043"
|
||||
width="12.943417"
|
||||
height="3.3856249"
|
||||
x="71.699966"
|
||||
y="27.116087" />
|
||||
<rect
|
||||
style="fill:#000000;fill-opacity:1;stroke-width:1.29937"
|
||||
id="rect2043-7"
|
||||
width="12.943417"
|
||||
height="3.3856082"
|
||||
x="71.699966"
|
||||
y="40.65852" />
|
||||
<rect
|
||||
style="fill:#000000;fill-opacity:1;stroke-width:1.29937"
|
||||
id="rect2043-9"
|
||||
width="12.943417"
|
||||
height="3.3856249"
|
||||
x="71.699966"
|
||||
y="33.887302" />
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 4.7 KiB |
@ -11,7 +11,8 @@
|
||||
"@types/react-dom": "^17.0.9",
|
||||
"serve": "^12.0.0",
|
||||
"typescript": "^4.4.2",
|
||||
"vite": "^2.5.3"
|
||||
"vite": "^2.5.3",
|
||||
"vite-plugin-pwa": "^0.11.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@mui/icons-material": "^5.0.3",
|
||||
@ -19,7 +20,8 @@
|
||||
"@reduxjs/toolkit": "^1.6.2",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-redux": "^7.2.5"
|
||||
"react-redux": "^7.2.5",
|
||||
"react-transition-group": "^4.4.2"
|
||||
},
|
||||
"private": "true"
|
||||
}
|
||||
|
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
70
public/favicon.svg
Normal file
70
public/favicon.svg
Normal file
@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="512"
|
||||
height="512"
|
||||
viewBox="0 0 135.46666 135.46667"
|
||||
version="1.1"
|
||||
id="svg6347"
|
||||
sodipodi:docname="favicon.svg"
|
||||
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview6349"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#999999"
|
||||
borderopacity="1"
|
||||
inkscape:pageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:document-units="px"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:zoom="2"
|
||||
inkscape:cx="195"
|
||||
inkscape:cy="282.5"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1000"
|
||||
inkscape:window-x="-11"
|
||||
inkscape:window-y="-11"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1" />
|
||||
<defs
|
||||
id="defs6344" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<path
|
||||
style="color:#000000;fill:#1565c0;stroke-width:3.77953;-inkscape-stroke:none"
|
||||
d="M 422,286.56641 V 302 H 336.68555 C 305.05466,322.31153 284,357.80423 284,397.99805 c 0,62.72345 51.27458,114 113.99805,114 62.72345,0 114,-51.27655 114,-114 0,-54.49514 -38.70808,-100.33896 -89.99805,-111.43164 z m -24.00195,37.42773 c 41.10595,0 73.99609,32.89793 73.99609,74.00391 0,41.10595 -32.89014,73.99609 -73.99609,73.99609 -41.10597,0 -74.00391,-32.89014 -74.00391,-73.99609 0,-41.10598 32.89794,-74.00391 74.00391,-74.00391 z"
|
||||
id="circle11-0"
|
||||
transform="scale(0.26458333)" />
|
||||
<path
|
||||
style="color:#000000;fill:#000000;stroke-width:10.5833;-inkscape-stroke:none"
|
||||
d="M 39.687481,0 H 50.270814 V 135.46666 H 39.687481 Z"
|
||||
id="rect6430" />
|
||||
<path
|
||||
id="path6644"
|
||||
style="color:#000000;fill:#000000;stroke-width:3.77953;-inkscape-stroke:none"
|
||||
d="M 300 0 L 300 340 L 340 340 C 433.41973 340 509.8112 264.91908 511.94727 171.99805 L 512 171.99805 C 512 171.30446 511.98091 170.61552 511.97266 169.92383 C 511.97974 169.28281 511.99805 168.6446 511.99805 168.00195 L 511.94922 168.00195 C 509.81315 75.080923 433.42168 1.8680609e-14 340.00195 0 L 340.00195 40.001953 C 412.44625 40.001953 470.87001 97.750087 471.97266 169.92188 C 470.95198 242.16664 412.4965 300.00587 340 300.00586 L 340 0 L 300 0 z "
|
||||
transform="scale(0.26458333)" />
|
||||
<path
|
||||
style="color:#000000;fill:#1565c0;-inkscape-stroke:none"
|
||||
d="M 44.978516,5.2910156 C 20.19992,5.2910156 0,25.492888 0,50.271484 0,75.05008 20.19992,95.25 44.978516,95.25 c 24.778596,0 44.980468,-20.19992 44.980468,-44.978516 0,-24.778596 -20.201872,-44.9804684 -44.980468,-44.9804684 z m 0,10.5839844 c 19.058962,0 34.396484,15.337522 34.396484,34.396484 0,19.058962 -15.337522,34.394532 -34.396484,34.394532 -19.058962,0 -34.394532,-15.33557 -34.394532,-34.394532 0,-19.058962 15.33557,-34.396484 34.394532,-34.396484 z"
|
||||
id="path6644-1-2-5-6" />
|
||||
<path
|
||||
style="color:#000000;fill:#000000;stroke-width:8.10116;-inkscape-stroke:none"
|
||||
d="M 0,0 H 79.375008 V 10.583333 H 0 Z"
|
||||
id="rect6430-2" />
|
||||
<path
|
||||
style="color:#000000;fill:#000000;stroke-width:3.77953;-inkscape-stroke:none"
|
||||
d="M 169.99805,342.00391 C 76.346656,342.00391 0,418.3486 0,512 h 40.001953 c 0,-72.0339 57.962218,-130.00195 129.996097,-130.00195 C 242.03192,381.99805 300,439.9661 300,512 h 40.00195 c 0,-5.57081 -0.36122,-11.0532 -0.89062,-16.48828 -32.97319,-20.03088 -55.10742,-56.29887 -55.10742,-97.50977 0,-3.84101 0.19294,-7.63875 0.56836,-11.38476 -30.25769,-27.67704 -70.4894,-44.61328 -114.57422,-44.61328 z"
|
||||
id="path6644-1-2-5"
|
||||
transform="scale(0.26458333)" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.8 KiB |
BIN
public/pwa-192x192.png
Normal file
BIN
public/pwa-192x192.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
BIN
public/pwa-512x512.png
Normal file
BIN
public/pwa-512x512.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
BIN
public/pwa-maskable-512x512.png
Normal file
BIN
public/pwa-maskable-512x512.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
@ -7,8 +7,7 @@ import InboxIcon from "@mui/icons-material/Inbox";
|
||||
export const EmptyList: React.FC = () => (
|
||||
<Box
|
||||
sx={{
|
||||
padding: (theme) => theme.spacing(1),
|
||||
paddingBottom: (theme) => theme.spacing(3),
|
||||
paddingBottom: (theme) => theme.spacing(2),
|
||||
textAlign: "center",
|
||||
}}
|
||||
>
|
||||
|
@ -47,7 +47,9 @@ export const TodoItem: React.FC<TodoItemProps> = ({ task, index }) => {
|
||||
}}
|
||||
onChange={(e) => change(e.currentTarget.value)}
|
||||
onBlur={save}
|
||||
inputProps={{ onKeyDown: (e) => enterHandler(save) }}
|
||||
inputProps={{
|
||||
onKeyDown: enterHandler(save),
|
||||
}}
|
||||
multiline
|
||||
/>
|
||||
) : (
|
||||
|
@ -1,26 +1,43 @@
|
||||
import React from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
|
||||
import List from "@mui/material/List";
|
||||
import Paper from "@mui/material/Paper";
|
||||
import Collapse from "@mui/material/Collapse";
|
||||
|
||||
import { TransitionGroup } from "react-transition-group";
|
||||
|
||||
import { TodoItem } from "./TodoItem";
|
||||
import { useAppSelector } from "../hooks";
|
||||
import { EmptyList } from "./EmptyList";
|
||||
import { isTaskItem, TaskItemT } from "../types";
|
||||
|
||||
export const TodoList: React.FC = () => {
|
||||
const tasks = useAppSelector((state) => state.todo.tasks);
|
||||
|
||||
const [list, setList] = useState<TaskItemT[] | {}[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (tasks.length) setList(tasks);
|
||||
else setList([{}]);
|
||||
}, [tasks]);
|
||||
|
||||
return (
|
||||
<Paper variant="outlined">
|
||||
{tasks.length ? (
|
||||
<List>
|
||||
{tasks.map((task, index) => (
|
||||
<TodoItem key={task.id} task={task} index={index} />
|
||||
))}
|
||||
</List>
|
||||
) : (
|
||||
<EmptyList />
|
||||
)}
|
||||
<List>
|
||||
<TransitionGroup>
|
||||
{list.map((task, index) =>
|
||||
isTaskItem(task) ? (
|
||||
<Collapse key={task.id}>
|
||||
<TodoItem task={task} index={index} />
|
||||
</Collapse>
|
||||
) : (
|
||||
<Collapse key={"empty"}>
|
||||
<EmptyList />
|
||||
</Collapse>
|
||||
)
|
||||
)}
|
||||
</TransitionGroup>
|
||||
</List>
|
||||
</Paper>
|
||||
);
|
||||
};
|
||||
|
@ -10,7 +10,7 @@ export const todoSlice = createSlice({
|
||||
name: "todo",
|
||||
initialState: initialState,
|
||||
reducers: {
|
||||
hydrate: (state, { payload }) => {
|
||||
hydrate: (state, { payload }: PayloadAction<TaskItemT[]>) => {
|
||||
state.tasks = payload;
|
||||
},
|
||||
add: (state, { payload }: PayloadAction<string>) => {
|
||||
|
@ -3,3 +3,7 @@ export type TaskItemT = {
|
||||
text: string;
|
||||
done: boolean;
|
||||
};
|
||||
|
||||
export const isTaskItem = (el: TaskItemT | {}): el is TaskItemT => {
|
||||
return "id" in el && "text" in el && "done" in el;
|
||||
};
|
||||
|
@ -1,3 +0,0 @@
|
||||
import { defineConfig } from "vite";
|
||||
|
||||
export default defineConfig({});
|
34
vite.config.ts
Normal file
34
vite.config.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import { defineConfig } from "vite";
|
||||
import { VitePWA } from "vite-plugin-pwa";
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
VitePWA({
|
||||
includeAssets: ["robots.txt", "favicon.ico", "favicon.svg"],
|
||||
manifest: {
|
||||
name: "TooDo",
|
||||
short_name: "TooDo",
|
||||
description: "Task management application",
|
||||
theme_color: "#ffffff",
|
||||
icons: [
|
||||
{
|
||||
src: "pwa-192x192.png",
|
||||
sizes: "192x192",
|
||||
type: "image/png",
|
||||
},
|
||||
{
|
||||
src: "pwa-512x512.png",
|
||||
sizes: "512x512",
|
||||
type: "image/png",
|
||||
},
|
||||
{
|
||||
src: "pwa-maskable-512x512.png",
|
||||
sizes: "512x512",
|
||||
type: "image/png",
|
||||
purpose: "any maskable",
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user