diff --git a/.prettierrc.json b/.prettierrc.json
index f6b149f..7cac555 100644
--- a/.prettierrc.json
+++ b/.prettierrc.json
@@ -1,5 +1,5 @@
{
- "singleQuote": true,
- "arrowParens": "avoid",
- "printWidth": 100
-}
\ No newline at end of file
+ "singleQuote": true,
+ "arrowParens": "avoid",
+ "trailingComma": "all"
+}
diff --git a/app/[...all]/page.tsx b/app/[...all]/page.tsx
index 044dbe8..defd15b 100644
--- a/app/[...all]/page.tsx
+++ b/app/[...all]/page.tsx
@@ -1,11 +1,17 @@
import dynamic from 'next/dynamic';
+import { lists } from '../../mock';
const App = dynamic(() => import('../../components/AppShell'), {
ssr: false,
});
-export function generateStaticParams() {
- return [{ all: ['tabs', 'feed'] }];
+export async function generateStaticParams() {
+ return [
+ { all: ['feed'] },
+ { all: ['lists'] },
+ ...lists.map(list => ({ all: ['lists', list.id] })),
+ { all: ['settings'] },
+ ];
}
export default function Page() {
diff --git a/app/layout.tsx b/app/layout.tsx
index ef93351..37398e2 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -40,8 +40,16 @@ export default function RootLayout({
return (
{children}
-
-
+
+
);
}
diff --git a/components/AppShell.tsx b/components/AppShell.tsx
index edd9d5d..9cca69a 100644
--- a/components/AppShell.tsx
+++ b/components/AppShell.tsx
@@ -1,29 +1,29 @@
'use client';
import { IonApp, IonRouterOutlet, setupIonicReact } from '@ionic/react';
import { StatusBar, Style } from '@capacitor/status-bar';
-
import { IonReactRouter } from '@ionic/react-router';
-import { Redirect, Route } from 'react-router-dom';
+import { Route } from 'react-router-dom';
import Tabs from './pages/Tabs';
setupIonicReact({});
-window.matchMedia('(prefers-color-scheme: dark)').addListener(async status => {
- try {
- await StatusBar.setStyle({
- style: status.matches ? Style.Dark : Style.Light,
- });
- } catch {}
-});
+window
+ .matchMedia('(prefers-color-scheme: dark)')
+ .addEventListener('change', async status => {
+ try {
+ await StatusBar.setStyle({
+ style: status.matches ? Style.Dark : Style.Light,
+ });
+ } catch {}
+ });
const AppShell = () => {
return (
- } />
- } exact={true} />
+ } />
diff --git a/components/pages/Feed.tsx b/components/pages/Feed.tsx
index 2b5e952..0f130c3 100644
--- a/components/pages/Feed.tsx
+++ b/components/pages/Feed.tsx
@@ -25,22 +25,47 @@ type FeedCardProps = {
author: string;
authorAvatar: string;
image: string;
-}
+};
-const FeedCard = ({ title, type, text, author, authorAvatar, image }: FeedCardProps) => (
+const FeedCard = ({
+ title,
+ type,
+ text,
+ author,
+ authorAvatar,
+ image,
+}: FeedCardProps) => (
-
+
-
{type}
-
{title}
-
{text}
+
+ {type}
+
+
+ {title}
+
+
+ {text}
+
-
+
-
{author}
+
+ {author}
+
@@ -71,7 +96,10 @@ const Feed = () => {
Feed
- setShowNotifications(false)} />
+ setShowNotifications(false)}
+ />
{homeItems.map((i, index) => (
))}
diff --git a/components/pages/ListDetail.tsx b/components/pages/ListDetail.tsx
index 71f784b..e2d5b9d 100644
--- a/components/pages/ListDetail.tsx
+++ b/components/pages/ListDetail.tsx
@@ -22,7 +22,7 @@ type ListDetailParams = {
listId: string;
};
-const ListItems = ({ list }: {list: TodoListItem}) => {
+const ListItems = ({ list }: { list: TodoListItem }) => {
return (
{(list?.items || []).map((item, key) => (
@@ -32,10 +32,20 @@ const ListItems = ({ list }: {list: TodoListItem}) => {
);
};
-const ListItemEntry = ({ list, item }: {list: TodoListItem, item: ListItem}) => (
+const ListItemEntry = ({
+ list,
+ item,
+}: {
+ list: TodoListItem;
+ item: ListItem;
+}) => (
actions.setDone(list, item, !item.done)}>
{item.name}
-
+
);
@@ -50,14 +60,12 @@ const ListDetail = () => {
-
+
{loadedList?.name}
-
- {loadedList && }
-
+ {loadedList && }
);
};
diff --git a/components/pages/Lists.tsx b/components/pages/Lists.tsx
index f021088..18b228b 100644
--- a/components/pages/Lists.tsx
+++ b/components/pages/Lists.tsx
@@ -1,7 +1,6 @@
import { TodoListItem } from '../../mock';
import Store from '../../store';
import * as selectors from '../../store/selectors';
-
import {
IonPage,
IonHeader,
@@ -13,11 +12,13 @@ import {
IonList,
} from '@ionic/react';
-const ListEntry = ({ list }: {list: TodoListItem}) => (
-
- {list.name}
-
-);
+const ListEntry = ({ list }: { list: TodoListItem }) => {
+ return (
+
+ {list.name}
+
+ );
+};
const AllLists = () => {
const lists = Store.useState(selectors.selectLists);
diff --git a/components/pages/Notifications.tsx b/components/pages/Notifications.tsx
index b466ad1..c7849fe 100644
--- a/components/pages/Notifications.tsx
+++ b/components/pages/Notifications.tsx
@@ -17,7 +17,11 @@ import { selectNotifications } from '../../store/selectors';
import { close } from 'ionicons/icons';
import { NotificationItem } from '../../mock';
-const NotificationItem = ({ notification }: {notification: NotificationItem}) => (
+const NotificationItem = ({
+ notification,
+}: {
+ notification: NotificationItem;
+}) => (
{notification.title}
{notification.when}
@@ -27,7 +31,13 @@ const NotificationItem = ({ notification }: {notification: NotificationItem}) =>
);
-const Notifications = ({ open, onDidDismiss }: {open: boolean, onDidDismiss: () => void}) => {
+const Notifications = ({
+ open,
+ onDidDismiss,
+}: {
+ open: boolean;
+ onDidDismiss: () => void;
+}) => {
const notifications = Store.useState(selectNotifications);
return (
@@ -35,7 +45,12 @@ const Notifications = ({ open, onDidDismiss }: {open: boolean, onDidDismiss: ()
Notifications
-
+
diff --git a/components/pages/Settings.tsx b/components/pages/Settings.tsx
index 28ed1b2..7fc80b6 100644
--- a/components/pages/Settings.tsx
+++ b/components/pages/Settings.tsx
@@ -7,7 +7,6 @@ import {
IonContent,
IonList,
IonToggle,
- IonLabel,
} from '@ionic/react';
import Store from '../../store';
@@ -16,7 +15,6 @@ import { setSettings } from '../../store/actions';
const Settings = () => {
const settings = Store.useState(selectors.selectSettings);
-
return (
@@ -27,7 +25,6 @@ const Settings = () => {
- Enable Notifications
{
@@ -36,7 +33,9 @@ const Settings = () => {
enableNotifications: e.target.checked,
});
}}
- />
+ >
+ Enable Notifications
+
diff --git a/components/pages/Tabs.tsx b/components/pages/Tabs.tsx
index 82de725..d89724b 100644
--- a/components/pages/Tabs.tsx
+++ b/components/pages/Tabs.tsx
@@ -1,6 +1,12 @@
import { Redirect, Route } from 'react-router-dom';
-import { IonRouterOutlet, IonTabs, IonTabBar, IonTabButton, IonIcon, IonLabel } from '@ionic/react';
-import { IonReactRouter } from '@ionic/react-router';
+import {
+ IonRouterOutlet,
+ IonTabs,
+ IonTabBar,
+ IonTabButton,
+ IonIcon,
+ IonLabel,
+} from '@ionic/react';
import { cog, flash, list } from 'ionicons/icons';
import Home from './Feed';
@@ -12,22 +18,26 @@ const Tabs = () => {
return (
- } exact={true} />
- } exact={true} />
- } exact={true} />
- } exact={true} />
- } exact={true} />
+ } exact={true} />
+ } exact={true} />
+ }
+ exact={true}
+ />
+ } exact={true} />
+ } exact={true} />
-
+
Feed
-
+
Lists
-
+
Settings
diff --git a/components/ui/Card.tsx b/components/ui/Card.tsx
index ac48028..bd4cb5e 100644
--- a/components/ui/Card.tsx
+++ b/components/ui/Card.tsx
@@ -1,8 +1,16 @@
import classNames from 'classnames';
-const Card = ({ children, className }: {children: React.ReactElement[], className: string}) => (
+const Card = ({
+ children,
+ className,
+}: {
+ children: React.ReactElement[];
+ className: string;
+}) => (
-
{children}
+
+ {children}
+
);
diff --git a/mock/index.ts b/mock/index.ts
index 77e97d0..8bd54d4 100644
--- a/mock/index.ts
+++ b/mock/index.ts
@@ -1,9 +1,3 @@
-export const images = [
- '/img/c1.avif',
- '/img/c2.avif',
- '/img/c3.avif',
-];
-
export type HomeItem = {
id: number;
title: string;
@@ -22,27 +16,25 @@ export const homeItems: HomeItem[] = [
text: 'We just got back from a trip to Maui, and we had a great time...',
author: 'Max Lynch',
authorAvatar: '/img/max.jpg',
- image: images[0],
+ image: '/img/c1.avif',
},
{
id: 2,
title: 'Arctic Adventures',
type: 'Blog',
- text:
- 'Last month we took a trek to the Arctic Circle. The isolation was just what we needed after...',
- author: 'Max Lynch',
- authorAvatar: '/img/max.jpg',
- image: images[1],
+ text: 'Last month we took a trek to the Arctic Circle. The isolation was just what we needed after...',
+ author: 'Nathan Chapman',
+ authorAvatar: '/img/nathan.jpg',
+ image: '/img/c2.avif',
},
{
id: 3,
title: 'Frolicking in the Faroe Islands',
type: 'Blog',
- text:
- 'The Faroe Islands are a North Atlantic archipelago located 320 kilometres (200 mi) north-northwest of Scotland...',
- author: 'Max Lynch',
- authorAvatar: '/img/max.jpg',
- image: images[2],
+ text: 'The Faroe Islands are a North Atlantic archipelago located 320 kilometres (200 mi) north-northwest of Scotland...',
+ author: 'Leo Giovanetti',
+ authorAvatar: '/img/leo.jpg',
+ image: '/img/c3.avif',
},
];
@@ -62,24 +54,29 @@ export const notifications: NotificationItem[] = [
export type ListItem = {
name: string;
done?: boolean;
-}
+};
export type TodoListItem = {
name: string;
id: string;
items?: ListItem[];
-}
+};
// Some fake lists
export const lists: TodoListItem[] = [
{
name: 'Groceries',
- id: 'groceries',
- items: [{ name: 'Apples' }, { name: 'Bananas' }, { name: 'Milk' }, { name: 'Ice Cream' }],
+ id: '01HRCYTYED31N83MJ0WK97WC02',
+ items: [
+ { name: 'Apples' },
+ { name: 'Bananas' },
+ { name: 'Milk' },
+ { name: 'Ice Cream' },
+ ],
},
{
name: 'Hardware Store',
- id: 'hardware',
+ id: '01HRCYV2KPNJQJ43Y7X526BHVX',
items: [
{ name: 'Circular Saw' },
{ name: 'Tack Cloth' },
@@ -87,14 +84,22 @@ export const lists: TodoListItem[] = [
{ name: 'Router' },
],
},
- { name: 'Work', id: 'work', items: [{ name: 'TPS Report' }, { name: 'Set up email' }] },
- { name: 'Reminders', id: 'reminders' },
+ {
+ name: 'Work',
+ id: '01HRCYV6C3YWAJRF2ZE7AZ17K7',
+ items: [{ name: 'TPS Report' }, { name: 'Set up email' }],
+ },
+ {
+ name: 'Reminders',
+ id: '01HRCYVADRPCM5SYV5BH98C7HS',
+ items: [{ name: 'Get car inspection', done: true }],
+ },
];
export type Settings = {
enableNotifications: boolean;
-}
+};
export const settings: Settings = {
enableNotifications: true,
-}
+};
diff --git a/next.config.js b/next.config.js
index 97b9437..60cad2b 100644
--- a/next.config.js
+++ b/next.config.js
@@ -13,5 +13,10 @@ module.exports = {
},
output: 'export',
swcMinify: true,
- transpilePackages: ['@ionic/react', '@ionic/core', '@stencil/core', 'ionicons'],
-}
+ transpilePackages: [
+ '@ionic/react',
+ '@ionic/core',
+ '@stencil/core',
+ 'ionicons',
+ ],
+};
diff --git a/package-lock.json b/package-lock.json
index 927dd99..d41ade7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,38 +8,38 @@
"name": "nextjs-tailwind-ionic-capacitor-starter",
"version": "5.0.0",
"dependencies": {
- "@capacitor/android": "5.7.0",
- "@capacitor/core": "5.7.0",
- "@capacitor/ios": "5.7.0",
+ "@capacitor/android": "5.7.2",
+ "@capacitor/core": "5.7.2",
+ "@capacitor/ios": "5.7.2",
"@capacitor/status-bar": "5.0.7",
- "@ionic/react": "7.7.3",
- "@ionic/react-router": "7.7.3",
+ "@ionic/react": "7.7.4",
+ "@ionic/react-router": "7.7.4",
"classnames": "2.5.1",
- "next": "14.1.0",
+ "next": "14.1.3",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-router": "5.3.4",
"react-router-dom": "5.3.4",
- "react-virtuoso": "4.7.0"
+ "react-virtuoso": "4.7.1"
},
"devDependencies": {
- "@capacitor/cli": "5.7.0",
+ "@capacitor/cli": "5.7.2",
"@types/jest": "29.5.12",
- "@types/node": "20.11.19",
- "@types/react": "18.2.57",
- "@types/react-dom": "18.2.19",
+ "@types/node": "20.11.25",
+ "@types/react": "18.2.64",
+ "@types/react-dom": "18.2.21",
"@types/react-router": "5.1.20",
"@types/react-router-dom": "5.3.3",
- "autoprefixer": "10.4.17",
- "eslint": "8.56.0",
- "eslint-config-next": "14.1.0",
+ "autoprefixer": "10.4.18",
+ "eslint": "8.57.0",
+ "eslint-config-next": "14.1.3",
"ionicons": "7.2.2",
"postcss": "8.4.35",
"prettier": "3.2.5",
"pullstate": "1.25",
"reselect": "5.1.0",
"tailwindcss": "3.4.1",
- "typescript": "5.3.3"
+ "typescript": "5.4.2"
},
"engines": {
"node": ">=18.17"
@@ -256,17 +256,17 @@
}
},
"node_modules/@capacitor/android": {
- "version": "5.7.0",
- "resolved": "https://registry.npmjs.org/@capacitor/android/-/android-5.7.0.tgz",
- "integrity": "sha512-0bnG1dqfT/nTjzMeHF/a5kF8mqGjHrPLADNqn41seWDfb2ch6AMiKUHsmHpEOWmGIrWOM25qNTrTOytoCSpuXg==",
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/@capacitor/android/-/android-5.7.2.tgz",
+ "integrity": "sha512-T4U+15R/1PyokW0Le92j7AV19kuO25his2ymF2xf2I04fZUDj8RjmXA+za7i3K8vhxtKkTdY2dPAywrfNAM09Q==",
"peerDependencies": {
"@capacitor/core": "^5.7.0"
}
},
"node_modules/@capacitor/cli": {
- "version": "5.7.0",
- "resolved": "https://registry.npmjs.org/@capacitor/cli/-/cli-5.7.0.tgz",
- "integrity": "sha512-md6217RXFQwSNo9vr1gDgBqR88MJaQVwu3C5W3bpWlmajhec6NUR7yT7QNcBWErhCIJfqOOqXu4ZSSShndF0ug==",
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/@capacitor/cli/-/cli-5.7.2.tgz",
+ "integrity": "sha512-dTW48klx39Mm2twkRU5pHw7tFRGtGk80fw5psopmbx8Ep5FG08HprqnwK5DXsFPhgJaC+ax4VDwmFCvb8uAGFA==",
"dev": true,
"dependencies": {
"@ionic/cli-framework-output": "^2.2.5",
@@ -296,17 +296,17 @@
}
},
"node_modules/@capacitor/core": {
- "version": "5.7.0",
- "resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.7.0.tgz",
- "integrity": "sha512-wa9Fao+Axa1t2ZERMyQD9r0xyfglQyC4DHQKintzKaIqcRuVe9J31TmfD3IxROYi9LGpY4X8cq4m4bjb0W94Qg==",
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.7.2.tgz",
+ "integrity": "sha512-/OUtfINmk7ke32VtKIHRAy8NlunbeK+aCqCHOS+fvtr7nUsOJXPkYgbgqZp/CWXET/gSK1xxMecaVBzpE98UKA==",
"dependencies": {
"tslib": "^2.1.0"
}
},
"node_modules/@capacitor/ios": {
- "version": "5.7.0",
- "resolved": "https://registry.npmjs.org/@capacitor/ios/-/ios-5.7.0.tgz",
- "integrity": "sha512-zoEdsYQHI1zz2vjKsTpu5bSfxQQ5jrk3Qs6Op9MYcckZZ2QWIs0YpL99p+zODXNpkkyLG73NXEIrOjvyI9jx8A==",
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/@capacitor/ios/-/ios-5.7.2.tgz",
+ "integrity": "sha512-msh+Kqjv/MyVCrSH0zVtwxptXnsgky4FENUq+Xdaa1pqEglmpHlUKod1Jf7qhfAhTLhHPyokOZMvaIyTtoSwCA==",
"peerDependencies": {
"@capacitor/core": "^5.7.0"
}
@@ -367,9 +367,9 @@
}
},
"node_modules/@eslint/js": {
- "version": "8.56.0",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz",
- "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==",
+ "version": "8.57.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz",
+ "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -423,9 +423,9 @@
}
},
"node_modules/@ionic/core": {
- "version": "7.7.3",
- "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.7.3.tgz",
- "integrity": "sha512-DSv6DPuiLU2MXsgDAXKFJW5OXxT7EyPy2jcQf03RcWooWeFryy979mqotPw7BgUuWt/fVGuz2tl3peAJGSqmDQ==",
+ "version": "7.7.4",
+ "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.7.4.tgz",
+ "integrity": "sha512-zThio3ZfbTu+3eM6QBdyeEk5OBc7M0ApFwSlP/G7rrFVcTPm12FNvG9VPD+aN5NwnYy0EsV3hlMkxbawoqjVLw==",
"dependencies": {
"@stencil/core": "^4.12.2",
"ionicons": "^7.2.2",
@@ -433,11 +433,11 @@
}
},
"node_modules/@ionic/react": {
- "version": "7.7.3",
- "resolved": "https://registry.npmjs.org/@ionic/react/-/react-7.7.3.tgz",
- "integrity": "sha512-b8jLpqv4dZ9nB9zoxhe0KR1Wk9bWMQ3UXQcOPu20+zYrxExwPqpLJ93LI0bU4F7ellduMjsakvELY486FeRrXw==",
+ "version": "7.7.4",
+ "resolved": "https://registry.npmjs.org/@ionic/react/-/react-7.7.4.tgz",
+ "integrity": "sha512-UBNBUjBN1fmCUyH8hetu0/q3F4pSNFVpjhh3Bt3s/bUXy0ksCuGbiYg/hET9QW1ja17ijq0+coqREXEB8lTmrA==",
"dependencies": {
- "@ionic/core": "7.7.3",
+ "@ionic/core": "7.7.4",
"ionicons": "^7.0.0",
"tslib": "*"
},
@@ -447,11 +447,11 @@
}
},
"node_modules/@ionic/react-router": {
- "version": "7.7.3",
- "resolved": "https://registry.npmjs.org/@ionic/react-router/-/react-router-7.7.3.tgz",
- "integrity": "sha512-NmEk801pfbrqzyTAb5nLDWGseUzm7kMpUy0dMY6OU76tpuHrEFBCFkZYAlTJWqXhkGRj9cR0cMnFAhPtGeSCkg==",
+ "version": "7.7.4",
+ "resolved": "https://registry.npmjs.org/@ionic/react-router/-/react-router-7.7.4.tgz",
+ "integrity": "sha512-phPpcRGoeQA3YTxRx1069yrtgsqWXhsDfcR7BJlgj0/uk4Wmx2NsUKV/nQrFmrtXdZSspFIrbd3yorq3gRhClA==",
"dependencies": {
- "@ionic/react": "7.7.3",
+ "@ionic/react": "7.7.4",
"tslib": "*"
},
"peerDependencies": {
@@ -791,23 +791,23 @@
}
},
"node_modules/@next/env": {
- "version": "14.1.0",
- "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.0.tgz",
- "integrity": "sha512-Py8zIo+02ht82brwwhTg36iogzFqGLPXlRGKQw5s+qP/kMNc4MAyDeEwBKDijk6zTIbegEgu8Qy7C1LboslQAw=="
+ "version": "14.1.3",
+ "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.3.tgz",
+ "integrity": "sha512-VhgXTvrgeBRxNPjyfBsDIMvgsKDxjlpw4IAUsHCX8Gjl1vtHUYRT3+xfQ/wwvLPDd/6kqfLqk9Pt4+7gysuCKQ=="
},
"node_modules/@next/eslint-plugin-next": {
- "version": "14.1.0",
- "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.1.0.tgz",
- "integrity": "sha512-x4FavbNEeXx/baD/zC/SdrvkjSby8nBn8KcCREqk6UuwvwoAPZmaV8TFCAuo/cpovBRTIY67mHhe86MQQm/68Q==",
+ "version": "14.1.3",
+ "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.1.3.tgz",
+ "integrity": "sha512-VCnZI2cy77Yaj3L7Uhs3+44ikMM1VD/fBMwvTBb3hIaTIuqa+DmG4dhUDq+MASu3yx97KhgsVJbsas0XuiKyww==",
"dev": true,
"dependencies": {
"glob": "10.3.10"
}
},
"node_modules/@next/swc-darwin-arm64": {
- "version": "14.1.0",
- "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.0.tgz",
- "integrity": "sha512-nUDn7TOGcIeyQni6lZHfzNoo9S0euXnu0jhsbMOmMJUBfgsnESdjN97kM7cBqQxZa8L/bM9om/S5/1dzCrW6wQ==",
+ "version": "14.1.3",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.3.tgz",
+ "integrity": "sha512-LALu0yIBPRiG9ANrD5ncB3pjpO0Gli9ZLhxdOu6ZUNf3x1r3ea1rd9Q+4xxUkGrUXLqKVK9/lDkpYIJaCJ6AHQ==",
"cpu": [
"arm64"
],
@@ -820,9 +820,9 @@
}
},
"node_modules/@next/swc-darwin-x64": {
- "version": "14.1.0",
- "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.0.tgz",
- "integrity": "sha512-1jgudN5haWxiAl3O1ljUS2GfupPmcftu2RYJqZiMJmmbBT5M1XDffjUtRUzP4W3cBHsrvkfOFdQ71hAreNQP6g==",
+ "version": "14.1.3",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.3.tgz",
+ "integrity": "sha512-E/9WQeXxkqw2dfcn5UcjApFgUq73jqNKaE5bysDm58hEUdUGedVrnRhblhJM7HbCZNhtVl0j+6TXsK0PuzXTCg==",
"cpu": [
"x64"
],
@@ -835,9 +835,9 @@
}
},
"node_modules/@next/swc-linux-arm64-gnu": {
- "version": "14.1.0",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.0.tgz",
- "integrity": "sha512-RHo7Tcj+jllXUbK7xk2NyIDod3YcCPDZxj1WLIYxd709BQ7WuRYl3OWUNG+WUfqeQBds6kvZYlc42NJJTNi4tQ==",
+ "version": "14.1.3",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.3.tgz",
+ "integrity": "sha512-USArX9B+3rZSXYLFvgy0NVWQgqh6LHWDmMt38O4lmiJNQcwazeI6xRvSsliDLKt+78KChVacNiwvOMbl6g6BBw==",
"cpu": [
"arm64"
],
@@ -850,9 +850,9 @@
}
},
"node_modules/@next/swc-linux-arm64-musl": {
- "version": "14.1.0",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.0.tgz",
- "integrity": "sha512-v6kP8sHYxjO8RwHmWMJSq7VZP2nYCkRVQ0qolh2l6xroe9QjbgV8siTbduED4u0hlk0+tjS6/Tuy4n5XCp+l6g==",
+ "version": "14.1.3",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.3.tgz",
+ "integrity": "sha512-esk1RkRBLSIEp1qaQXv1+s6ZdYzuVCnDAZySpa62iFTMGTisCyNQmqyCTL9P+cLJ4N9FKCI3ojtSfsyPHJDQNw==",
"cpu": [
"arm64"
],
@@ -865,9 +865,9 @@
}
},
"node_modules/@next/swc-linux-x64-gnu": {
- "version": "14.1.0",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.0.tgz",
- "integrity": "sha512-zJ2pnoFYB1F4vmEVlb/eSe+VH679zT1VdXlZKX+pE66grOgjmKJHKacf82g/sWE4MQ4Rk2FMBCRnX+l6/TVYzQ==",
+ "version": "14.1.3",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.3.tgz",
+ "integrity": "sha512-8uOgRlYEYiKo0L8YGeS+3TudHVDWDjPVDUcST+z+dUzgBbTEwSSIaSgF/vkcC1T/iwl4QX9iuUyUdQEl0Kxalg==",
"cpu": [
"x64"
],
@@ -880,9 +880,9 @@
}
},
"node_modules/@next/swc-linux-x64-musl": {
- "version": "14.1.0",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.0.tgz",
- "integrity": "sha512-rbaIYFt2X9YZBSbH/CwGAjbBG2/MrACCVu2X0+kSykHzHnYH5FjHxwXLkcoJ10cX0aWCEynpu+rP76x0914atg==",
+ "version": "14.1.3",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.3.tgz",
+ "integrity": "sha512-DX2zqz05ziElLoxskgHasaJBREC5Y9TJcbR2LYqu4r7naff25B4iXkfXWfcp69uD75/0URmmoSgT8JclJtrBoQ==",
"cpu": [
"x64"
],
@@ -895,9 +895,9 @@
}
},
"node_modules/@next/swc-win32-arm64-msvc": {
- "version": "14.1.0",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.0.tgz",
- "integrity": "sha512-o1N5TsYc8f/HpGt39OUQpQ9AKIGApd3QLueu7hXk//2xq5Z9OxmV6sQfNp8C7qYmiOlHYODOGqNNa0e9jvchGQ==",
+ "version": "14.1.3",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.3.tgz",
+ "integrity": "sha512-HjssFsCdsD4GHstXSQxsi2l70F/5FsRTRQp8xNgmQs15SxUfUJRvSI9qKny/jLkY3gLgiCR3+6A7wzzK0DBlfA==",
"cpu": [
"arm64"
],
@@ -910,9 +910,9 @@
}
},
"node_modules/@next/swc-win32-ia32-msvc": {
- "version": "14.1.0",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.0.tgz",
- "integrity": "sha512-XXIuB1DBRCFwNO6EEzCTMHT5pauwaSj4SWs7CYnME57eaReAKBXCnkUE80p/pAZcewm7hs+vGvNqDPacEXHVkw==",
+ "version": "14.1.3",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.3.tgz",
+ "integrity": "sha512-DRuxD5axfDM1/Ue4VahwSxl1O5rn61hX8/sF0HY8y0iCbpqdxw3rB3QasdHn/LJ6Wb2y5DoWzXcz3L1Cr+Thrw==",
"cpu": [
"ia32"
],
@@ -925,9 +925,9 @@
}
},
"node_modules/@next/swc-win32-x64-msvc": {
- "version": "14.1.0",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.0.tgz",
- "integrity": "sha512-9WEbVRRAqJ3YFVqEZIxUqkiO8l1nool1LmNxygr5HWF8AcSYsEpneUDhmjUVJEzO2A04+oPtZdombzzPPkTtgg==",
+ "version": "14.1.3",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.3.tgz",
+ "integrity": "sha512-uC2DaDoWH7h1P/aJ4Fok3Xiw6P0Lo4ez7NbowW2VGNXw/Xv6tOuLUcxhBYZxsSUJtpeknCi8/fvnSpyCFp4Rcg==",
"cpu": [
"x64"
],
@@ -1072,9 +1072,9 @@
"dev": true
},
"node_modules/@types/node": {
- "version": "20.11.19",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.19.tgz",
- "integrity": "sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==",
+ "version": "20.11.25",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.25.tgz",
+ "integrity": "sha512-TBHyJxk2b7HceLVGFcpAUjsa5zIdsPWlR6XHfyGzd0SFu+/NFgQgMAl96MSDZgQDvJAvV6BKsFOrt6zIL09JDw==",
"dev": true,
"dependencies": {
"undici-types": "~5.26.4"
@@ -1087,9 +1087,9 @@
"dev": true
},
"node_modules/@types/react": {
- "version": "18.2.57",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.57.tgz",
- "integrity": "sha512-ZvQsktJgSYrQiMirAN60y4O/LRevIV8hUzSOSNB6gfR3/o3wCBFQx3sPwIYtuDMeiVgsSS3UzCV26tEzgnfvQw==",
+ "version": "18.2.64",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.64.tgz",
+ "integrity": "sha512-MlmPvHgjj2p3vZaxbQgFUQFvD8QiZwACfGqEdDSWou5yISWxDQ4/74nCAwsUiX7UFLKZz3BbVSPj+YxeoGGCfg==",
"dev": true,
"dependencies": {
"@types/prop-types": "*",
@@ -1098,9 +1098,9 @@
}
},
"node_modules/@types/react-dom": {
- "version": "18.2.19",
- "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.19.tgz",
- "integrity": "sha512-aZvQL6uUbIJpjZk4U8JZGbau9KDeAwMfmhyWorxgBkqDIEf6ROjRozcmPIicqsUwPUjbkDfHKgGee1Lq65APcA==",
+ "version": "18.2.21",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.21.tgz",
+ "integrity": "sha512-gnvBA/21SA4xxqNXEwNiVcP0xSGHh/gi1VhWv9Bl46a0ItbTT5nFY+G9VSQpaG/8N/qdJpJ+vftQ4zflTtnjLw==",
"dev": true,
"dependencies": {
"@types/react": "*"
@@ -1590,9 +1590,9 @@
}
},
"node_modules/autoprefixer": {
- "version": "10.4.17",
- "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.17.tgz",
- "integrity": "sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==",
+ "version": "10.4.18",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.18.tgz",
+ "integrity": "sha512-1DKbDfsr6KUElM6wg+0zRNkB/Q7WcKYAaK+pzXn+Xqmszm/5Xa9coeNdtP88Vi+dPzZnMjhge8GIV49ZQkDa+g==",
"dev": true,
"funding": [
{
@@ -1609,8 +1609,8 @@
}
],
"dependencies": {
- "browserslist": "^4.22.2",
- "caniuse-lite": "^1.0.30001578",
+ "browserslist": "^4.23.0",
+ "caniuse-lite": "^1.0.30001591",
"fraction.js": "^4.3.7",
"normalize-range": "^0.1.2",
"picocolors": "^1.0.0",
@@ -1827,9 +1827,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001588",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001588.tgz",
- "integrity": "sha512-+hVY9jE44uKLkH0SrUTqxjxqNTOWHsbnQDIKjwkZ3lNTzUUVdBLBGXtj/q5Mp5u98r3droaZAewQuEDzjQdZlQ==",
+ "version": "1.0.30001594",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001594.tgz",
+ "integrity": "sha512-VblSX6nYqyJVs8DKFMldE2IVCJjZ225LW00ydtUWwh5hk9IfkTOffO6r8gJNsH0qqqeAF8KrbMYA2VEwTlGW5g==",
"funding": [
{
"type": "opencollective",
@@ -2344,16 +2344,16 @@
}
},
"node_modules/eslint": {
- "version": "8.56.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz",
- "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==",
+ "version": "8.57.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz",
+ "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
"@eslint/eslintrc": "^2.1.4",
- "@eslint/js": "8.56.0",
- "@humanwhocodes/config-array": "^0.11.13",
+ "@eslint/js": "8.57.0",
+ "@humanwhocodes/config-array": "^0.11.14",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",
"@ungap/structured-clone": "^1.2.0",
@@ -2399,12 +2399,12 @@
}
},
"node_modules/eslint-config-next": {
- "version": "14.1.0",
- "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-14.1.0.tgz",
- "integrity": "sha512-SBX2ed7DoRFXC6CQSLc/SbLY9Ut6HxNB2wPTcoIWjUMd7aF7O/SIE7111L8FdZ9TXsNV4pulUDnfthpyPtbFUg==",
+ "version": "14.1.3",
+ "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-14.1.3.tgz",
+ "integrity": "sha512-sUCpWlGuHpEhI0pIT0UtdSLJk5Z8E2DYinPTwsBiWaSYQomchdl0i60pjynY48+oXvtyWMQ7oE+G3m49yrfacg==",
"dev": true,
"dependencies": {
- "@next/eslint-plugin-next": "14.1.0",
+ "@next/eslint-plugin-next": "14.1.3",
"@rushstack/eslint-patch": "^1.3.3",
"@typescript-eslint/parser": "^5.4.2 || ^6.0.0",
"eslint-import-resolver-node": "^0.3.6",
@@ -4278,11 +4278,11 @@
"dev": true
},
"node_modules/next": {
- "version": "14.1.0",
- "resolved": "https://registry.npmjs.org/next/-/next-14.1.0.tgz",
- "integrity": "sha512-wlzrsbfeSU48YQBjZhDzOwhWhGsy+uQycR8bHAOt1LY1bn3zZEcDyHQOEoN3aWzQ8LHCAJ1nqrWCc9XF2+O45Q==",
+ "version": "14.1.3",
+ "resolved": "https://registry.npmjs.org/next/-/next-14.1.3.tgz",
+ "integrity": "sha512-oexgMV2MapI0UIWiXKkixF8J8ORxpy64OuJ/J9oVUmIthXOUCcuVEZX+dtpgq7wIfIqtBwQsKEDXejcjTsan9g==",
"dependencies": {
- "@next/env": "14.1.0",
+ "@next/env": "14.1.3",
"@swc/helpers": "0.5.2",
"busboy": "1.6.0",
"caniuse-lite": "^1.0.30001579",
@@ -4297,15 +4297,15 @@
"node": ">=18.17.0"
},
"optionalDependencies": {
- "@next/swc-darwin-arm64": "14.1.0",
- "@next/swc-darwin-x64": "14.1.0",
- "@next/swc-linux-arm64-gnu": "14.1.0",
- "@next/swc-linux-arm64-musl": "14.1.0",
- "@next/swc-linux-x64-gnu": "14.1.0",
- "@next/swc-linux-x64-musl": "14.1.0",
- "@next/swc-win32-arm64-msvc": "14.1.0",
- "@next/swc-win32-ia32-msvc": "14.1.0",
- "@next/swc-win32-x64-msvc": "14.1.0"
+ "@next/swc-darwin-arm64": "14.1.3",
+ "@next/swc-darwin-x64": "14.1.3",
+ "@next/swc-linux-arm64-gnu": "14.1.3",
+ "@next/swc-linux-arm64-musl": "14.1.3",
+ "@next/swc-linux-x64-gnu": "14.1.3",
+ "@next/swc-linux-x64-musl": "14.1.3",
+ "@next/swc-win32-arm64-msvc": "14.1.3",
+ "@next/swc-win32-ia32-msvc": "14.1.3",
+ "@next/swc-win32-x64-msvc": "14.1.3"
},
"peerDependencies": {
"@opentelemetry/api": "^1.1.0",
@@ -5064,9 +5064,9 @@
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/react-virtuoso": {
- "version": "4.7.0",
- "resolved": "https://registry.npmjs.org/react-virtuoso/-/react-virtuoso-4.7.0.tgz",
- "integrity": "sha512-cpgvI1rSOETGDMhqVAVDuH+XHbWO1uIGKv5I6l4CyC71xWYUeGrE5n7sgTZklROB4+Vbv85pcgfWloTlY48HGQ==",
+ "version": "4.7.1",
+ "resolved": "https://registry.npmjs.org/react-virtuoso/-/react-virtuoso-4.7.1.tgz",
+ "integrity": "sha512-V1JIZLEwgX7R+YNkbY8dq6NcnIGKGWXe4mnMJJPsA2L4qeFKst0LY3mDk6sBCJyKRbMzYFxTZWyTT4QsA1JvVQ==",
"engines": {
"node": ">=10"
},
@@ -5906,9 +5906,9 @@
}
},
"node_modules/tiny-invariant": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz",
- "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw=="
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz",
+ "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="
},
"node_modules/tiny-warning": {
"version": "1.0.3",
@@ -6069,9 +6069,9 @@
}
},
"node_modules/typescript": {
- "version": "5.3.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz",
- "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==",
+ "version": "5.4.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz",
+ "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==",
"dev": true,
"bin": {
"tsc": "bin/tsc",
diff --git a/package.json b/package.json
index d354972..780d557 100644
--- a/package.json
+++ b/package.json
@@ -11,6 +11,7 @@
"build": "next build",
"dev": "next dev",
"lint": "eslint . --ext .ts,.tsx",
+ "prettify": "prettier --write **/*.tsx",
"preserve": "npm run build",
"serve": "npx serve out",
"presync": "npm run build",
@@ -19,37 +20,37 @@
"ios": "npx cap run ios"
},
"dependencies": {
- "@capacitor/android": "5.7.0",
- "@capacitor/core": "5.7.0",
- "@capacitor/ios": "5.7.0",
+ "@capacitor/android": "5.7.2",
+ "@capacitor/core": "5.7.2",
+ "@capacitor/ios": "5.7.2",
"@capacitor/status-bar": "5.0.7",
- "@ionic/react": "7.7.3",
- "@ionic/react-router": "7.7.3",
+ "@ionic/react": "7.7.4",
+ "@ionic/react-router": "7.7.4",
"classnames": "2.5.1",
- "next": "14.1.0",
+ "next": "14.1.3",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-router": "5.3.4",
"react-router-dom": "5.3.4",
- "react-virtuoso": "4.7.0"
+ "react-virtuoso": "4.7.1"
},
"devDependencies": {
- "@capacitor/cli": "5.7.0",
+ "@capacitor/cli": "5.7.2",
"@types/jest": "29.5.12",
- "@types/node": "20.11.19",
- "@types/react": "18.2.57",
- "@types/react-dom": "18.2.19",
+ "@types/node": "20.11.25",
+ "@types/react": "18.2.64",
+ "@types/react-dom": "18.2.21",
"@types/react-router-dom": "5.3.3",
"@types/react-router": "5.1.20",
- "autoprefixer": "10.4.17",
- "eslint": "8.56.0",
- "eslint-config-next": "14.1.0",
+ "autoprefixer": "10.4.18",
+ "eslint": "8.57.0",
+ "eslint-config-next": "14.1.3",
"ionicons": "7.2.2",
"postcss": "8.4.35",
"prettier": "3.2.5",
"pullstate": "1.25",
"reselect": "5.1.0",
"tailwindcss": "3.4.1",
- "typescript": "5.3.3"
+ "typescript": "5.4.2"
}
}
diff --git a/public/img/leo.jpg b/public/img/leo.jpg
new file mode 100644
index 0000000..788d94b
Binary files /dev/null and b/public/img/leo.jpg differ
diff --git a/public/img/nathan.jpg b/public/img/nathan.jpg
new file mode 100644
index 0000000..65d95a5
Binary files /dev/null and b/public/img/nathan.jpg differ
diff --git a/store/actions.ts b/store/actions.ts
index ef852a9..e0452ab 100644
--- a/store/actions.ts
+++ b/store/actions.ts
@@ -21,13 +21,17 @@ export const setSettings = (settings: Settings) => {
// App-specific actions
-export const setDone = (list: TodoListItem, item: ListItem, done: boolean) => {
+export const setDone = (
+ list: TodoListItem,
+ listItem: ListItem,
+ done: boolean,
+) => {
Store.update((s, o) => {
const listIndex = o.lists.findIndex(l => l === list);
const items = o.lists[listIndex].items;
- if(!items) return;
- const itemIndex = items.findIndex(i => i === item);
- const item = items[itemIndex];
+ const itemIndex = items?.findIndex(i => i === listItem);
+ const item = items?.[itemIndex ?? -1];
+ if (!item) return;
item.done = done;
if (list === o.selectedList) {
s.selectedList = s.lists[listIndex];