Refactor state and make list detail a page

This commit is contained in:
Max Lynch
2020-12-24 15:56:08 -06:00
parent 0056d6fe81
commit 06c1a8f71d
12 changed files with 182 additions and 115 deletions
+14 -11
View File
@@ -1,4 +1,6 @@
import Store from '../store';
import * as actions from '../store/actions';
import * as selectors from '../store/selectors';
const MenuItem = ({ children, ...props }) => (
<li {...props}>
@@ -12,14 +14,11 @@ const MenuItem = ({ children, ...props }) => (
);
const MenuContent = () => {
const pages = Store.useState(s => s.pages);
const menuLinks = Store.useState(selectors.getMenuLinks);
const go = page => {
Store.update(s => {
console.log('Going to', page);
s.currentPage = page;
s.showMenu = false;
});
actions.setPage(page);
actions.setMenuOpen(false);
};
return (
@@ -28,11 +27,15 @@ const MenuContent = () => {
<h2 className="text-xl select-none">Menu</h2>
</div>
<ul>
{pages.map(p => (
<MenuItem key={p.id} onClick={() => go(p)}>
{p.title}
</MenuItem>
))}
{menuLinks.map(p => {
const title = typeof p.title === 'function' ? p.title() : p.title;
return (
<MenuItem key={p.id} onClick={() => go(p)}>
{title}
</MenuItem>
);
})}
</ul>
</>
);
+3 -2
View File
@@ -1,8 +1,9 @@
import { homeItems } from '../../data';
import Store from '../../store';
import Card from '../ui/Card';
import Content from '../ui/Content';
import * as selectors from '../../store/selectors';
const HomeCard = ({ title, type, text, author, image }) => (
<Card className="my-4">
<div>
@@ -17,7 +18,7 @@ const HomeCard = ({ title, type, text, author, image }) => (
);
const Home = ({ selected }) => {
const homeItems = Store.useState(s => s.homeItems);
const homeItems = Store.useState(selectors.getHomeItems);
return (
<Content visible={selected} className="p-4">
+60
View File
@@ -0,0 +1,60 @@
import Store from '../../store';
import * as actions from '../../store/actions';
import * as selectors from '../../store/selectors';
import Content from '../ui/Content';
import List from '../ui/List';
import VirtualScroll from '../ui/VirtualScroll';
const ListItems = ({ list, onClose }) => {
return (
<>
<div className="py-2">
<a href="#" onClick={onClose}>
All Lists
</a>
</div>
<VirtualScroll
data={list?.items || []}
totalCount={(list?.items || []).length}
style={{ height: '100%', width: '100%' }}
itemContent={(i, item) => <ListItemEntry list={list} item={item} />}
/>
</>
);
};
const ListItemEntry = ({ list, item }) => (
<div className="p-4 border-solid border-b cursor-pointer">
<span className="text-md">{item.name}</span>
<input
type="checkbox"
checked={item.done}
onChange={() => {
actions.setDone(list, item, !item.done);
}}
/>
</div>
);
const ListDetail = ({ selected }) => {
const selectedList = Store.useState(selectors.getSelectedList);
return (
<Content visible={selected} className="p-4">
<List className="h-full w-full">
{selected && (
<ListItems
list={selectedList}
onClose={() => {
actions.setSelectedList(null);
actions.setPageById('lists');
}}
/>
)}
</List>
</Content>
);
};
export default ListDetail;
+8 -53
View File
@@ -1,11 +1,9 @@
import { useState } from 'react';
import Store from '../../store';
import { setDone } from '../../store/actions';
import Card from '../ui/Card';
import * as actions from '../../store/actions';
import * as selectors from '../../store/selectors';
import Content from '../ui/Content';
import List from '../ui/List';
import ListItem from '../ui/ListItem';
import VirtualScroll from '../ui/VirtualScroll';
const ListEntry = ({ list, ...props }) => (
@@ -15,7 +13,7 @@ const ListEntry = ({ list, ...props }) => (
);
const AllLists = ({ onSelect }) => {
const lists = Store.useState(s => s.lists);
const lists = Store.useState(selectors.getLists);
return (
<VirtualScroll
@@ -29,58 +27,15 @@ const AllLists = ({ onSelect }) => {
);
};
const ListItems = ({ list, onClose }) => {
return (
<>
<div className="py-2">
<a href="#" onClick={onClose}>
All Lists
</a>
</div>
<VirtualScroll
data={list.items || []}
totalCount={(list.items || []).length}
style={{ height: '100%', width: '100%' }}
itemContent={(i, item) => <ListItemEntry list={list} item={item} />}
/>
</>
);
};
const ListItemEntry = ({ list, item }) => (
<div className="p-4 border-solid border-b cursor-pointer">
<span className="text-md">{item.name}</span>
<input
type="checkbox"
checked={item.done}
onChange={() => {
setDone(list, item, !item.done);
}}
/>
</div>
);
const Feed = ({ selected }) => {
const selectedList = Store.useState(s => s.selectedList);
const Lists = ({ selected }) => {
return (
<Content visible={selected} className="p-4">
<List className="h-full w-full">
{selected && selectedList ? (
<ListItems
list={selectedList}
onClose={() =>
Store.update(s => {
s.selectedList = null;
})
}
/>
) : (
{selected && (
<AllLists
onSelect={list => {
Store.update(s => {
s.selectedList = list;
});
actions.setSelectedList(list);
actions.setPageById('list-detail');
}}
/>
)}
@@ -89,4 +44,4 @@ const Feed = ({ selected }) => {
);
};
export default Feed;
export default Lists;
+9 -15
View File
@@ -1,10 +1,12 @@
import { useEffect, useState } from 'react';
import { Plugins } from '@capacitor/core';
import Store from '../../store';
import * as actions from '../../store/actions';
const Nav = ({ page }) => {
const [showMenu, setShowMenu] = useState(false);
const [showProfileMenu, setShowProfileMenu] = useState(false);
const title = typeof page.title === 'function' ? page.title() : page.title;
useEffect(() => {
Plugins.StatusBar.setStyle({
@@ -23,11 +25,7 @@ const Nav = ({ page }) => {
<div className="relative flex items-center justify-between h-16">
<div
className="absolute inset-y-0 left-0 flex items-center sm:hidden"
onClick={() =>
Store.update(s => {
s.showMenu = true;
})
}
onClick={() => actions.setMenuOpen(true)}
>
{/* Mobile menu button*/}
<button
@@ -81,7 +79,7 @@ const Nav = ({ page }) => {
</div>
<div className="flex-1 flex items-center justify-center sm:items-stretch sm:justify-start">
<div className="flex-shrink-0 flex items-center">
<h1 className="text-gray-50">{page.title}</h1>
<h1 className="text-gray-50">{title}</h1>
</div>
<div className="hidden sm:block sm:ml-6">
<div className="flex space-x-4">
@@ -116,11 +114,7 @@ const Nav = ({ page }) => {
<div className="absolute inset-y-0 right-0 flex items-center pr-2 sm:static sm:inset-auto sm:ml-6 sm:pr-0">
<button
className="bg-gray-800 p-1 rounded-full text-gray-400 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-800 focus:ring-white"
onClick={() =>
Store.update(s => {
s.showNotifications = true;
})
}
onClick={() => actions.setNotificationsOpen(true)}
>
<span className="sr-only">View notifications</span>
{/* Heroicon name: bell */}
@@ -148,7 +142,7 @@ const Nav = ({ page }) => {
className="bg-gray-800 flex text-sm rounded-full focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-800 focus:ring-white"
id="user-menu"
aria-haspopup="true"
onClick={() => setShowMenu(!showMenu)}
onClick={() => setShowProfileMenu(!showProfileMenu)}
>
<span className="sr-only">Open user menu</span>
<img
@@ -170,7 +164,7 @@ const Nav = ({ page }) => {
*/}
<div
className={`${
showMenu ? '' : 'hidden'
showProfileMenu ? '' : 'hidden'
} origin-top-right absolute right-0 mt-2 w-48 rounded-md shadow-lg py-1 bg-white ring-1 ring-black ring-opacity-5`}
role="menu"
aria-orientation="vertical"