Compare commits

..

14 Commits

Author SHA1 Message Date
louiscklaw
01a8d2ca02 update main-nav, 2025-05-11 13:24:52 +08:00
louiscklaw
e5b136b8b5 update main-nav refactoring, working, 2025-05-11 13:06:58 +08:00
louiscklaw
031dbed6a9 "implement responsive main navigation bar with dropdown menus and mobile view support" 2025-05-11 13:00:30 +08:00
louiscklaw
f20dfa00c2 "add CMS workspace configuration with linked documentation and AI workspace folders" 2025-05-11 13:00:05 +08:00
louiscklaw
24c91cb6f0 "update gitignore to exclude temporary and backup files" 2025-05-11 10:48:45 +08:00
louiscklaw
abca91c26a "introduce horizontal main navigation component with dynamic styling and interactive elements" 2025-05-11 10:39:09 +08:00
louiscklaw
3321eafffa "update gitignore to exclude draft files" 2025-05-11 10:36:46 +08:00
louiscklaw
adc9275d3f "update prettier config, add TODO list, and create workspace configuration" 2025-05-11 10:35:04 +08:00
louiscklaw
60eed00cb2 "add admin user seed script and refactor common seed utilities" 2025-05-11 10:34:48 +08:00
louiscklaw
c29ab4b920 update project, 2025-05-11 08:02:50 +08:00
louiscklaw
9d46de56c3 update util scripts, 2025-05-11 08:02:07 +08:00
louiscklaw
3f9d88e733 init req0018, family photo of frameworks, 2025-05-11 08:00:31 +08:00
louiscklaw
6e576919ab init docker cofig, 2025-05-11 07:59:35 +08:00
louiscklaw
9739583f43 update ide config, remove yaml and python, 2025-05-11 07:59:11 +08:00
61 changed files with 2414 additions and 799 deletions

9
.editorconfig Normal file
View File

@@ -0,0 +1,9 @@
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
* text=lf

5
.gitignore vendored
View File

@@ -2,8 +2,13 @@
node_modules
005_references/
_archive/
_del
*.bak
*.log
*.del
**/_del
**/volumes/**
006_lab
**/*.draft

12
.vscode/extensions.json vendored Normal file
View File

@@ -0,0 +1,12 @@
{
"recommendations": [
"aflalo.dbml-formatter",
"bierner.markdown-mermaid",
"christian-kohler.path-intellisense",
"esbenp.prettier-vscode",
"humao.rest-client",
"matt-meyers.vscode-dbml",
"nicolas-liger.dbml-viewer",
"yzhang.markdown-all-in-one"
]
}

21
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,21 @@
{
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[jsonc]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"workbench.iconTheme": "material-icon-theme",
"workbench.colorTheme": "Default Dark Modern",
"editor.formatOnSave": true,
"git.ignoreLimitWarning": true
}

View File

@@ -1,6 +1,5 @@
{
"recommendations": [
"redhat.vscode-yaml",
"yzhang.markdown-all-in-one",
"esbenp.prettier-vscode",
"ms-python.python",
@@ -8,7 +7,6 @@
"ms-python.debugpy",
"ms-python.black-formatter",
"ms-python.isort",
"ms-python.pylint",
"bierner.markdown-mermaid",
"shd101wyy.markdown-preview-enhanced",
"yzhang.markdown-all-in-one",

View File

@@ -0,0 +1,7 @@
---
tags: mobile, cms, db
---
# family photo of frameworks
it should have a family photo of used framework

14
002_source/.env Normal file
View File

@@ -0,0 +1,14 @@
# THIS IS env file for use with docker-compose.yml
# cms
# doc
# ionic_mobile
# api_ts
# pocketbase
PB_HOSTNAME=pocketbase
PB_USERNAME=admin@123.com
PB_PASSWORD=Aa12345678

4
002_source/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
**/*.del
**/*.log
**/_archive
**/_del

74
002_source/README.md Normal file
View File

@@ -0,0 +1,74 @@
# README
## to start production
```bash
# start docker before hand
$ ./dc_build.sh
$ ./dc_up.sh
```
## to start develop
```bash
#
$ ./dc_build.sh
$ ./dc_dev.sh
$ docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d pocketbase api_ts --remove-orphans
$ docker compose logs -f pocketbase api_ts
```
## test api endpoint
```bash
# browse to http://localhost:3000/helloworld
```
```bash
# start docker before hand
$ cd 002_source
$ ./dev.sh
# docker containers up
```
---
## deprecated
```bash
# mobile
$ cd 002_source/mobile
$ pnpm run dev
# cms
$ cd 002_source/cms
$ npm run dev
```
ideation
prototyping
testing
production deployment
evaluation
monitoring
## addresses
```
mobile:
http://localhost:5173
pocketbase:
http://localhost:8090/_
cms:
http://localhost:3000
documentation
http://localhost:3001
```
extend to vocabularies

View File

@@ -92,7 +92,11 @@ export function MainNav({ color = 'evident', items = [] }: MainNavProps): React.
py: 1,
}}
>
<Stack direction="row" spacing={2} sx={{ alignItems: 'center', flex: '1 1 auto' }}>
<Stack
direction="row"
spacing={2}
sx={{ alignItems: 'center', flex: '1 1 auto' }}
>
<IconButton
onClick={(): void => {
setOpenNav(true);
@@ -101,8 +105,16 @@ export function MainNav({ color = 'evident', items = [] }: MainNavProps): React.
>
<ListIcon color="var(--NavItem-icon-color)" />
</IconButton>
<Box component={RouterLink} href={paths.home} sx={{ display: { xs: 'none', md: 'inline-block' } }}>
<Logo color={logoColor} height={32} width={122} />
<Box
component={RouterLink}
href={paths.home}
sx={{ display: { xs: 'none', md: 'inline-block' } }}
>
<Logo
color={logoColor}
height={32}
width={122}
/>
</Box>
<Box sx={{ display: { xs: 'none', md: 'block' } }}>
<WorkspacesSwitch />
@@ -154,11 +166,17 @@ function SearchButton(): React.JSX.Element {
return (
<React.Fragment>
<Tooltip title="Search">
<IconButton onClick={dialog.handleOpen} sx={{ display: { xs: 'none', md: 'inline-flex' } }}>
<IconButton
onClick={dialog.handleOpen}
sx={{ display: { xs: 'none', md: 'inline-flex' } }}
>
<MagnifyingGlassIcon color="var(--NavItem-icon-color)" />
</IconButton>
</Tooltip>
<SearchDialog onClose={dialog.handleClose} open={dialog.open} />
<SearchDialog
onClose={dialog.handleClose}
open={dialog.open}
/>
</React.Fragment>
);
}
@@ -174,12 +192,19 @@ function NotificationsButton(): React.JSX.Element {
sx={{ '& .MuiBadge-dot': { borderRadius: '50%', height: '10px', right: '6px', top: '6px', width: '10px' } }}
variant="dot"
>
<IconButton onClick={popover.handleOpen} ref={popover.anchorRef}>
<IconButton
onClick={popover.handleOpen}
ref={popover.anchorRef}
>
<BellIcon color="var(--NavItem-icon-color)" />
</IconButton>
</Badge>
</Tooltip>
<NotificationsPopover anchorEl={popover.anchorRef.current} onClose={popover.handleClose} open={popover.open} />
<NotificationsPopover
anchorEl={popover.anchorRef.current}
onClose={popover.handleClose}
open={popover.open}
/>
</React.Fragment>
);
}
@@ -190,11 +215,18 @@ function ContactsButton(): React.JSX.Element {
return (
<React.Fragment>
<Tooltip title="Contacts">
<IconButton onClick={popover.handleOpen} ref={popover.anchorRef}>
<IconButton
onClick={popover.handleOpen}
ref={popover.anchorRef}
>
<UsersIcon color="var(--NavItem-icon-color)" />
</IconButton>
</Tooltip>
<ContactsPopover anchorEl={popover.anchorRef.current} onClose={popover.handleClose} open={popover.open} />
<ContactsPopover
anchorEl={popover.anchorRef.current}
onClose={popover.handleClose}
open={popover.open}
/>
</React.Fragment>
);
}
@@ -214,11 +246,20 @@ function LanguageSwitch(): React.JSX.Element {
sx={{ display: { xs: 'none', md: 'inline-flex' } }}
>
<Box sx={{ height: '24px', width: '24px' }}>
<Box alt={language} component="img" src={flag} sx={{ height: 'auto', width: '100%' }} />
<Box
alt={language}
component="img"
src={flag}
sx={{ height: 'auto', width: '100%' }}
/>
</Box>
</IconButton>
</Tooltip>
<LanguagePopover anchorEl={popover.anchorRef.current} onClose={popover.handleClose} open={popover.open} />
<LanguagePopover
anchorEl={popover.anchorRef.current}
onClose={popover.handleClose}
open={popover.open}
/>
</React.Fragment>
);
}
@@ -259,7 +300,11 @@ function UserButton(): React.JSX.Element {
<Avatar src={user.avatar} />
</Badge>
</Box>
<UserPopover anchorEl={popover.anchorRef.current} onClose={popover.handleClose} open={popover.open} />
<UserPopover
anchorEl={popover.anchorRef.current}
onClose={popover.handleClose}
open={popover.open}
/>
</React.Fragment>
);
}
@@ -267,7 +312,11 @@ function UserButton(): React.JSX.Element {
function renderNavGroups({ items = [], pathname }: { items?: NavItemConfig[]; pathname: string }): React.JSX.Element {
const children = items.reduce((acc: React.ReactNode[], curr: NavItemConfig): React.ReactNode[] => {
acc.push(
<Box component="li" key={curr.key} sx={{ flex: '0 0 auto' }}>
<Box
component="li"
key={curr.key}
sx={{ flex: '0 0 auto' }}
>
{renderNavItems({ pathname, items: curr.items })}
</Box>
);
@@ -276,7 +325,12 @@ function renderNavGroups({ items = [], pathname }: { items?: NavItemConfig[]; pa
}, []);
return (
<Stack component="ul" direction="row" spacing={2} sx={{ listStyle: 'none', m: 0, p: '8px 12px' }}>
<Stack
component="ul"
direction="row"
spacing={2}
sx={{ listStyle: 'none', m: 0, p: '8px 12px' }}
>
{children}
</Stack>
);
@@ -286,13 +340,24 @@ function renderNavItems({ items = [], pathname }: { items?: NavItemConfig[]; pat
const children = items.reduce((acc: React.ReactNode[], curr: NavItemConfig): React.ReactNode[] => {
const { key, ...item } = curr;
acc.push(<NavItem key={key} pathname={pathname} {...item} />);
acc.push(
<NavItem
key={key}
pathname={pathname}
{...item}
/>
);
return acc;
}, []);
return (
<Stack component="ul" direction="row" spacing={2} sx={{ listStyle: 'none', m: 0, p: 0 }}>
<Stack
component="ul"
direction="row"
spacing={2}
sx={{ listStyle: 'none', m: 0, p: 0 }}
>
{children}
</Stack>
);
@@ -318,7 +383,10 @@ function NavItem({
const isBranch = Boolean(items);
const element = (
<Box component="li" sx={{ userSelect: 'none' }}>
<Box
component="li"
sx={{ userSelect: 'none' }}
>
<Box
{...(isBranch
? { role: 'button' }
@@ -373,10 +441,19 @@ function NavItem({
{title}
</Typography>
</Box>
{label ? <Chip color="primary" label={label} size="small" /> : null}
{label ? (
<Chip
color="primary"
label={label}
size="small"
/>
) : null}
{external ? (
<Box sx={{ alignItems: 'center', display: 'flex', flex: '0 0 auto' }}>
<ArrowSquareOutIcon color="var(--NavItem-icon-color)" fontSize="var(--icon-fontSize-sm)" />
<ArrowSquareOutIcon
color="var(--NavItem-icon-color)"
fontSize="var(--icon-fontSize-sm)"
/>
</Box>
) : null}
{isBranch ? (
@@ -415,13 +492,23 @@ function renderDropdownItems({
const children = items.reduce((acc: React.ReactNode[], curr: NavItemConfig): React.ReactNode[] => {
const { key, ...item } = curr;
acc.push(<DropdownItem key={key} pathname={pathname} {...item} />);
acc.push(
<DropdownItem
key={key}
pathname={pathname}
{...item}
/>
);
return acc;
}, []);
return (
<Stack component="ul" spacing={1} sx={{ listStyle: 'none', m: 0, p: 0 }}>
<Stack
component="ul"
spacing={1}
sx={{ listStyle: 'none', m: 0, p: 0 }}
>
{children}
</Stack>
);
@@ -444,7 +531,10 @@ function DropdownItem({
const isBranch = Boolean(items);
const element = (
<Box component="li" sx={{ userSelect: 'none' }}>
<Box
component="li"
sx={{ userSelect: 'none' }}
>
<Box
{...(isBranch
? { role: 'button' }

View File

@@ -1,253 +0,0 @@
'use client';
import * as React from 'react';
import Avatar from '@mui/material/Avatar';
import Badge from '@mui/material/Badge';
import Box from '@mui/material/Box';
import Divider from '@mui/material/Divider';
import IconButton from '@mui/material/IconButton';
import Stack from '@mui/material/Stack';
import Tooltip from '@mui/material/Tooltip';
import { Bell as BellIcon } from '@phosphor-icons/react/dist/ssr/Bell';
import { List as ListIcon } from '@phosphor-icons/react/dist/ssr/List';
import { MagnifyingGlass as MagnifyingGlassIcon } from '@phosphor-icons/react/dist/ssr/MagnifyingGlass';
import { Users as UsersIcon } from '@phosphor-icons/react/dist/ssr/Users';
import { useTranslation } from 'next-i18next';
import type { NavItemConfig } from '@/types/nav';
import type { User } from '@/types/user';
import { useDialog } from '@/hooks/use-dialog';
import { usePopover } from '@/hooks/use-popover';
import { ContactsPopover } from '../contacts-popover';
import { languageFlags, LanguagePopover } from '../language-popover';
import type { Language } from '../language-popover';
import { MobileNav } from '../mobile-nav';
import { NotificationsPopover } from '../notifications-popover';
import { SearchDialog } from '../search-dialog';
import { UserPopover } from '../user-popover/user-popover';
export interface MainNavProps {
items: NavItemConfig[];
}
export function MainNav({ items }: MainNavProps): React.JSX.Element {
const [openNav, setOpenNav] = React.useState<boolean>(false);
return (
<React.Fragment>
<Box
component="header"
sx={{
'--MainNav-background': 'var(--mui-palette-background-default)',
'--MainNav-divider': 'var(--mui-palette-divider)',
bgcolor: 'var(--MainNav-background)',
left: 0,
position: 'sticky',
pt: { lg: 'var(--Layout-gap)' },
top: 0,
width: '100%',
zIndex: 'var(--MainNav-zIndex)',
}}
>
<Box
sx={{
borderBottom: '1px solid var(--MainNav-divider)',
display: 'flex',
flex: '1 1 auto',
minHeight: 'var(--MainNav-height)',
px: { xs: 2, lg: 3 },
py: 1,
}}
>
<Stack
direction="row"
spacing={2}
sx={{ alignItems: 'center', flex: '1 1 auto' }}
>
<IconButton
onClick={(): void => {
setOpenNav(true);
}}
sx={{ display: { lg: 'none' } }}
>
<ListIcon />
</IconButton>
<SearchButton />
</Stack>
<Stack
direction="row"
spacing={2}
sx={{ alignItems: 'center', flex: '1 1 auto', justifyContent: 'flex-end' }}
>
<NotificationsButton />
<ContactsButton />
<Divider
flexItem
orientation="vertical"
sx={{ borderColor: 'var(--MainNav-divider)', display: { xs: 'none', lg: 'block' } }}
/>
<LanguageSwitch />
<UserButton />
</Stack>
</Box>
</Box>
<MobileNav
items={items}
onClose={() => {
setOpenNav(false);
}}
open={openNav}
/>
</React.Fragment>
);
}
function SearchButton(): React.JSX.Element {
const dialog = useDialog();
return (
<React.Fragment>
<Tooltip title="Search">
<IconButton
onClick={dialog.handleOpen}
sx={{ display: { xs: 'none', lg: 'inline-flex' } }}
>
<MagnifyingGlassIcon />
</IconButton>
</Tooltip>
<SearchDialog
onClose={dialog.handleClose}
open={dialog.open}
/>
</React.Fragment>
);
}
function ContactsButton(): React.JSX.Element {
const popover = usePopover<HTMLButtonElement>();
return (
<React.Fragment>
<Tooltip title="Contacts">
<IconButton
onClick={popover.handleOpen}
ref={popover.anchorRef}
>
<UsersIcon />
</IconButton>
</Tooltip>
<ContactsPopover
anchorEl={popover.anchorRef.current}
onClose={popover.handleClose}
open={popover.open}
/>
</React.Fragment>
);
}
function NotificationsButton(): React.JSX.Element {
const popover = usePopover<HTMLButtonElement>();
return (
<React.Fragment>
<Tooltip title="Notifications">
<Badge
color="error"
sx={{ '& .MuiBadge-dot': { borderRadius: '50%', height: '10px', right: '6px', top: '6px', width: '10px' } }}
variant="dot"
>
<IconButton
onClick={popover.handleOpen}
ref={popover.anchorRef}
>
<BellIcon />
</IconButton>
</Badge>
</Tooltip>
<NotificationsPopover
anchorEl={popover.anchorRef.current}
onClose={popover.handleClose}
open={popover.open}
/>
</React.Fragment>
);
}
function LanguageSwitch(): React.JSX.Element {
const { i18n } = useTranslation();
const popover = usePopover<HTMLButtonElement>();
const language = (i18n.language || 'en') as Language;
const flag = languageFlags[language];
return (
<React.Fragment>
<Tooltip title="Language">
<IconButton
onClick={popover.handleOpen}
ref={popover.anchorRef}
sx={{ display: { xs: 'none', lg: 'inline-flex' } }}
>
<Box sx={{ height: '24px', width: '24px' }}>
<Box
alt={language}
component="img"
src={flag}
sx={{ height: 'auto', width: '100%' }}
/>
</Box>
</IconButton>
</Tooltip>
<LanguagePopover
anchorEl={popover.anchorRef.current}
onClose={popover.handleClose}
open={popover.open}
/>
</React.Fragment>
);
}
const user = {
id: 'USR-000',
name: 'Sofia Rivers',
avatar: '/assets/avatar.png',
email: 'sofia@devias.io',
} satisfies User;
function UserButton(): React.JSX.Element {
const popover = usePopover<HTMLButtonElement>();
return (
<React.Fragment>
<Box
component="button"
onClick={popover.handleOpen}
ref={popover.anchorRef}
sx={{ border: 'none', background: 'transparent', cursor: 'pointer', p: 0 }}
>
<Badge
anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}
color="success"
sx={{
'& .MuiBadge-dot': {
border: '2px solid var(--MainNav-background)',
borderRadius: '50%',
bottom: '6px',
height: '12px',
right: '6px',
width: '12px',
},
}}
variant="dot"
>
<Avatar src={user.avatar} />
</Badge>
</Box>
<UserPopover
anchorEl={popover.anchorRef.current}
onClose={popover.handleClose}
open={popover.open}
/>
</React.Fragment>
);
}

View File

@@ -0,0 +1,3 @@
# GUIDELINE
- please keep one default `export` per file

View File

@@ -0,0 +1,32 @@
'use client';
import * as React from 'react';
import IconButton from '@mui/material/IconButton';
import Tooltip from '@mui/material/Tooltip';
import { Users as UsersIcon } from '@phosphor-icons/react/dist/ssr/Users';
import { usePopover } from '@/hooks/use-popover';
import { ContactsPopover } from '../../contacts-popover';
export function ContactsButton(): React.JSX.Element {
const popover = usePopover<HTMLButtonElement>();
return (
<React.Fragment>
<Tooltip title="Contacts">
<IconButton
onClick={popover.handleOpen}
ref={popover.anchorRef}
>
<UsersIcon />
</IconButton>
</Tooltip>
<ContactsPopover
anchorEl={popover.anchorRef.current}
onClose={popover.handleClose}
open={popover.open}
/>
</React.Fragment>
);
}

View File

@@ -0,0 +1,94 @@
'use client';
import * as React from 'react';
import Box from '@mui/material/Box';
import Divider from '@mui/material/Divider';
import IconButton from '@mui/material/IconButton';
import Stack from '@mui/material/Stack';
import { List as ListIcon } from '@phosphor-icons/react/dist/ssr/List';
import type { NavItemConfig } from '@/types/nav';
import { MobileNav } from '../../mobile-nav';
// import { NotificationsButton } from './notifications-button';
import { LanguageSwitch } from './language-switch';
import { ContactsButton } from './contacts-button';
import { SearchButton } from './search-button';
import { NotificationsButton } from './notifications-button';
import { UserButton } from './user-button';
export interface MainNavProps {
items: NavItemConfig[];
}
export function MainNav({ items }: MainNavProps): React.JSX.Element {
const [openNav, setOpenNav] = React.useState<boolean>(false);
return (
<React.Fragment>
<Box
component="header"
sx={{
'--MainNav-background': 'var(--mui-palette-background-default)',
'--MainNav-divider': 'var(--mui-palette-divider)',
bgcolor: 'var(--MainNav-background)',
left: 0,
position: 'sticky',
pt: { lg: 'var(--Layout-gap)' },
top: 0,
width: '100%',
zIndex: 'var(--MainNav-zIndex)',
}}
>
<Box
sx={{
borderBottom: '1px solid var(--MainNav-divider)',
display: 'flex',
flex: '1 1 auto',
minHeight: 'var(--MainNav-height)',
px: { xs: 2, lg: 3 },
py: 1,
}}
>
<Stack
direction="row"
spacing={2}
sx={{ alignItems: 'center', flex: '1 1 auto' }}
>
<IconButton
onClick={(): void => {
setOpenNav(true);
}}
sx={{ display: { lg: 'none' } }}
>
<ListIcon />
</IconButton>
<SearchButton />
</Stack>
<Stack
direction="row"
spacing={2}
sx={{ alignItems: 'center', flex: '1 1 auto', justifyContent: 'flex-end' }}
>
<NotificationsButton />
<ContactsButton />
<Divider
flexItem
orientation="vertical"
sx={{ borderColor: 'var(--MainNav-divider)', display: { xs: 'none', lg: 'block' } }}
/>
<LanguageSwitch />
<UserButton />
</Stack>
</Box>
</Box>
<MobileNav
items={items}
onClose={() => {
setOpenNav(false);
}}
open={openNav}
/>
</React.Fragment>
);
}

View File

@@ -0,0 +1,45 @@
'use client';
import * as React from 'react';
import Box from '@mui/material/Box';
import IconButton from '@mui/material/IconButton';
import Tooltip from '@mui/material/Tooltip';
import { useTranslation } from 'next-i18next';
import { usePopover } from '@/hooks/use-popover';
import { languageFlags, LanguagePopover } from '../../language-popover';
import type { Language } from '../../language-popover';
export function LanguageSwitch(): React.JSX.Element {
const { i18n } = useTranslation();
const popover = usePopover<HTMLButtonElement>();
const language = (i18n.language || 'en') as Language;
const flag = languageFlags[language];
return (
<React.Fragment>
<Tooltip title="Language">
<IconButton
onClick={popover.handleOpen}
ref={popover.anchorRef}
sx={{ display: { xs: 'none', lg: 'inline-flex' } }}
>
<Box sx={{ height: '24px', width: '24px' }}>
<Box
alt={language}
component="img"
src={flag}
sx={{ height: 'auto', width: '100%' }}
/>
</Box>
</IconButton>
</Tooltip>
<LanguagePopover
anchorEl={popover.anchorRef.current}
onClose={popover.handleClose}
open={popover.open}
/>
</React.Fragment>
);
}

View File

@@ -0,0 +1,40 @@
'use client';
import * as React from 'react';
import Badge from '@mui/material/Badge';
import IconButton from '@mui/material/IconButton';
import Tooltip from '@mui/material/Tooltip';
import { Bell as BellIcon } from '@phosphor-icons/react/dist/ssr/Bell';
import { usePopover } from '@/hooks/use-popover';
import { NotificationsPopover } from '../../notifications-popover';
// import { NotificationsButton } from './notifications-button';
export function NotificationsButton(): React.JSX.Element {
const popover = usePopover<HTMLButtonElement>();
return (
<React.Fragment>
<Tooltip title="Notifications">
<Badge
color="error"
sx={{ '& .MuiBadge-dot': { borderRadius: '50%', height: '10px', right: '6px', top: '6px', width: '10px' } }}
variant="dot"
>
<IconButton
onClick={popover.handleOpen}
ref={popover.anchorRef}
>
<BellIcon />
</IconButton>
</Badge>
</Tooltip>
<NotificationsPopover
anchorEl={popover.anchorRef.current}
onClose={popover.handleClose}
open={popover.open}
/>
</React.Fragment>
);
}

View File

@@ -0,0 +1,31 @@
'use client';
import * as React from 'react';
import IconButton from '@mui/material/IconButton';
import Tooltip from '@mui/material/Tooltip';
import { MagnifyingGlass as MagnifyingGlassIcon } from '@phosphor-icons/react/dist/ssr/MagnifyingGlass';
import { useDialog } from '@/hooks/use-dialog';
import { SearchDialog } from '../../search-dialog';
export function SearchButton(): React.JSX.Element {
const dialog = useDialog();
return (
<React.Fragment>
<Tooltip title="Search">
<IconButton
onClick={dialog.handleOpen}
sx={{ display: { xs: 'none', lg: 'inline-flex' } }}
>
<MagnifyingGlassIcon />
</IconButton>
</Tooltip>
<SearchDialog
onClose={dialog.handleClose}
open={dialog.open}
/>
</React.Fragment>
);
}

View File

@@ -0,0 +1,57 @@
'use client';
import * as React from 'react';
import Avatar from '@mui/material/Avatar';
import Badge from '@mui/material/Badge';
import Box from '@mui/material/Box';
import type { User } from '@/types/user';
import { usePopover } from '@/hooks/use-popover';
import { UserPopover } from '../../user-popover/user-popover';
// import { NotificationsButton } from './notifications-button';
const user = {
id: 'USR-000',
name: 'Sofia Rivers',
avatar: '/assets/avatar.png',
email: 'sofia@devias.io',
} satisfies User;
export function UserButton(): React.JSX.Element {
const popover = usePopover<HTMLButtonElement>();
return (
<React.Fragment>
<Box
component="button"
onClick={popover.handleOpen}
ref={popover.anchorRef}
sx={{ border: 'none', background: 'transparent', cursor: 'pointer', p: 0 }}
>
<Badge
anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}
color="success"
sx={{
'& .MuiBadge-dot': {
border: '2px solid var(--MainNav-background)',
borderRadius: '50%',
bottom: '6px',
height: '12px',
right: '6px',
width: '12px',
},
}}
variant="dot"
>
<Avatar src={user.avatar} />
</Badge>
</Box>
<UserPopover
anchorEl={popover.anchorRef.current}
onClose={popover.handleClose}
open={popover.open}
/>
</React.Fragment>
);
}

View File

@@ -0,0 +1,9 @@
'use client';
import type { User } from '@/types/user';
export const user = {
id: 'USR-000',
name: 'Sofia Rivers',
avatar: '/assets/avatar.png',
email: 'sofia@devias.io',
} satisfies User;

View File

@@ -20,8 +20,8 @@ import { DropdownPopover } from '@/components/core/dropdown/dropdown-popover';
import { DropdownTrigger } from '@/components/core/dropdown/dropdown-trigger';
import { Logo } from '@/components/core/logo';
import { MobileNav } from './mobile-nav';
import { PagesPopover } from './pages-popover';
import { MobileNav } from '../mobile-nav';
import { PagesPopover } from '../pages-popover';
export function MainNav(): React.JSX.Element {
const [openNav, setOpenNav] = React.useState<boolean>(false);
@@ -41,15 +41,46 @@ export function MainNav(): React.JSX.Element {
zIndex: 'var(--MainNav-zIndex)',
}}
>
<Container maxWidth="lg" sx={{ display: 'flex', minHeight: 'var(--MainNav-height)', py: '16px' }}>
<Stack direction="row" spacing={2} sx={{ alignItems: 'center', flex: '1 1 auto' }}>
<Box component={RouterLink} href={paths.home} sx={{ display: 'inline-flex' }}>
<Logo color="light" height={32} width={122} />
<Container
maxWidth="lg"
sx={{ display: 'flex', minHeight: 'var(--MainNav-height)', py: '16px' }}
>
<Stack
direction="row"
spacing={2}
sx={{ alignItems: 'center', flex: '1 1 auto' }}
>
<Box
component={RouterLink}
href={paths.home}
sx={{ display: 'inline-flex' }}
>
<Logo
color="light"
height={32}
width={122}
/>
</Box>
<Box component="nav" sx={{ display: { xs: 'none', md: 'block' } }}>
<Stack component="ul" direction="row" spacing={1} sx={{ listStyle: 'none', m: 0, p: 0 }}>
<NavItem href={paths.components.index} pathname={pathname} title="Components" />
<NavItem href={paths.docs} pathname={pathname} title="Documentation" />
<Box
component="nav"
sx={{ display: { xs: 'none', md: 'block' } }}
>
<Stack
component="ul"
direction="row"
spacing={1}
sx={{ listStyle: 'none', m: 0, p: 0 }}
>
<NavItem
href={paths.components.index}
pathname={pathname}
title="Components"
/>
<NavItem
href={paths.docs}
pathname={pathname}
title="Documentation"
/>
</Stack>
</Box>
</Stack>
@@ -58,9 +89,20 @@ export function MainNav(): React.JSX.Element {
spacing={2}
sx={{ alignItems: 'center', flex: '1 1 auto', justifyContent: 'flex-end' }}
>
<Box component="nav" sx={{ display: { xs: 'none', md: 'block' } }}>
<Stack component="ul" direction="row" spacing={1} sx={{ listStyle: 'none', m: 0, p: 0 }}>
<NavItem pathname={pathname} title="Pages">
<Box
component="nav"
sx={{ display: { xs: 'none', md: 'block' } }}
>
<Stack
component="ul"
direction="row"
spacing={1}
sx={{ listStyle: 'none', m: 0, p: 0 }}
>
<NavItem
pathname={pathname}
title="Pages"
>
<PagesPopover />
</NavItem>
</Stack>
@@ -113,7 +155,10 @@ export function NavItem({
const hasPopover = Boolean(children);
const element = (
<Box component="li" sx={{ userSelect: 'none' }}>
<Box
component="li"
sx={{ userSelect: 'none' }}
>
<Box
{...(hasPopover
? {
@@ -157,7 +202,10 @@ export function NavItem({
}}
tabIndex={0}
>
<Box component="span" sx={{ flex: '1 1 auto' }}>
<Box
component="span"
sx={{ flex: '1 1 auto' }}
>
<Typography
component="span"
sx={{ color: 'inherit', fontSize: '0.875rem', fontWeight: 500, lineHeight: '28px' }}

View File

@@ -0,0 +1,33 @@
services:
cms:
environment:
- NODE_ENV=development
# command: "sleep infinity"
deploy:
resources:
limits:
cpus: "1"
doc:
environment:
- NODE_ENV=development
deploy:
resources:
limits:
cpus: "1"
ionic_mobile:
environment:
- NODE_ENV=development
deploy:
resources:
limits:
cpus: "1"
api_ts:
environment:
- NODE_ENV=development
deploy:
resources:
limits:
cpus: "1"

View File

@@ -0,0 +1,149 @@
volumes:
shared:
dist:
services:
cms:
image: 192.168.10.61:5000/cms_ubuntu
# build: ./cms
env_file:
- .env
volumes:
- ./cms:/app
ports:
- 3000:3000
working_dir: /app
command: ./scripts/docker/entrypoint.sh
depends_on:
pocketbase:
condition: service_healthy
healthcheck:
#optional (recommended) since v0.10.0
test: wget --no-verbose --tries=1 --spider http://localhost:3000 || exit 1
interval: 5s
timeout: 5s
retries: 5
deploy:
resources:
limits:
cpus: "0.5"
reservations:
cpus: "0.01"
doc:
build: ./doc
env_file:
- .env
volumes:
- ./doc:/app
ports:
- 3001:3000
working_dir: /app
command: ./scripts/docker/entrypoint.sh
healthcheck:
#optional (recommended) since v0.10.0
test: wget --no-verbose --tries=1 --spider http://localhost:3000 || exit 1
interval: 5s
timeout: 5s
retries: 5
deploy:
resources:
limits:
cpus: "0.5"
reservations:
cpus: "0.01"
ionic_mobile:
# image: node:20-bullseye-slim
# build: ./ionic_mobile
image: 192.168.10.61:5000/ionic_mobile_ubuntu
# user: 1000:1000
env_file:
- .env
volumes:
- ./ionic_mobile:/app
ports:
- 5173:5173
working_dir: /app
command: ./scripts/docker/entrypoint.sh
depends_on:
pocketbase:
condition: service_healthy
healthcheck:
#optional (recommended) since v0.10.0
test: wget --no-verbose --tries=1 --spider http://localhost:5173 || exit 1
interval: 5s
timeout: 5s
retries: 5
deploy:
resources:
limits:
cpus: "0.5"
reservations:
cpus: "0.01"
api_ts:
image: 192.168.10.61:5000/api_ts_ubuntu
# build: ./api_ts
volumes:
- ./api_ts:/app
working_dir: /app
# env_file:
# - .env
environment:
- NODE_ENV=production
- PB_HOSTNAME=pocketbase
- PB_USERNAME=admin@123.com
- PB_PASSWORD=Aa12345678
ports:
- 8080:3000
# command: sleep infinity
command: ./entrypoint.sh
# depends_on:
# pocketbase:
# condition: service_healthy
# healthcheck:
# #optional (recommended) since v0.10.0
# test: wget --no-verbose --tries=1 --spider http://localhost:3000 || exit 1
# interval: 5s
# timeout: 5s
# retries: 5
deploy:
resources:
limits:
cpus: 0.5
reservations:
cpus: 0.01
pocketbase:
# image: ghcr.io/muchobien/pocketbase:latest
build:
context: ./pocketbase/docker
args:
- VERSION=0.26.6 # Specify the PocketBase version here
# hostname: pocketbase
restart: always
# environment:
# ENCRYPTION: example #optional
ports:
- 8090:8090
volumes:
- ./pocketbase/volumes/pb_data:/pb_data
- ./pocketbase/pb_hooks:/pb_hooks
- ./pocketbase/pb_migrations:/pb_migrations
# healthcheck:
# #optional (recommended) since v0.10.0
# test: wget --no-verbose --tries=1 --spider http://localhost:8090/api/health || exit 1
# interval: 5s
# timeout: 5s
# retries: 5
deploy:
resources:
limits:
cpus: 0.5
reservations:
cpus: 0.01

View File

@@ -1,3 +1,3 @@
{
"printWidth": 180
"printWidth": 360
}

View File

@@ -0,0 +1,3 @@
# TODO
- [ ] blablabla

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

@@ -18,6 +18,7 @@ $app.rootCmd.addCommand(
require(`${__hooks}/seed/004_clean_users.js`)($app);
require(`${__hooks}/seed/005_Users_teacher.js`)($app);
require(`${__hooks}/seed/006_Users_student.js`)($app);
require(`${__hooks}/seed/007_Users_admin.js`)($app);
require(`${__hooks}/seed/010_Vocabularies.js`)($app);
//
require(`${__hooks}/seed/020_QuizLPCategories.js`)($app);
@@ -30,12 +31,11 @@ $app.rootCmd.addCommand(
require(`${__hooks}/seed/041_QuizCRQuestions.js`)($app);
//
require(`${__hooks}/seed/050_Customers.js`)($app);
require(`${__hooks}/seed/051_Teachers.js`)($app);
// require(`${__hooks}/seed/051_Teachers_xxx.js`)($app);
require(`${__hooks}/seed/052_Students.js`)($app);
//
require(`${__hooks}/seed/060_Notifications.js`)($app);
$app.reloadCachedCollections();
$app.reloadSettings();
},

View File

@@ -1,14 +1,19 @@
module.exports = $app => {
const ASSETS_DIR = '/pb_hooks/assets';
const getAsset = name => $filesystem.fileFromPath(ASSETS_DIR + '/' + name);
const config = require("/pb_hooks/seed/config.js");
const utils = require("/pb_hooks/seed/utils.js");
module.exports = ($app) => {
const { CR_cat_id_news, CR_cat_id_technology } = config;
const { getId, getAsset, dirtyTruncateTable } = utils;
// const ASSETS_DIR = "/pb_hooks/assets";
// const getAsset = (name) => $filesystem.fileFromPath(ASSETS_DIR + "/" + name);
for (let i = 0; i < 3; i++) {
let t1_collection = $app.findCollectionByNameOrId('t1');
let t1_collection = $app.findCollectionByNameOrId("t1");
let record = new Record(t1_collection);
record.set('hello', 'world');
let test_png = getAsset('1.png');
record.set('test_file', test_png);
record.set("hello", "world");
let test_png = getAsset("1.png");
record.set("test_file", test_png);
$app.save(record);
}

View File

@@ -1,12 +1,18 @@
const config = require("/pb_hooks/seed/config.js");
const utils = require("/pb_hooks/seed/utils.js");
module.exports = ($app) => {
const { CR_cat_id_news, CR_cat_id_technology } = config;
const { getId, getAsset, dirtyTruncateTable } = utils;
let draft_lesson_types = [
["1".padStart(15, 0), "Vocabulary", "vocabulary", 0, "visible"],
["2".padStart(15, 0), "Connectives", "connectives", 1, "visible"],
["3".padStart(15, 0), "Testing visible", "testing", 3, "visible"],
["4".padStart(15, 0), "Testing hidden", "testing", 3, "hidden"],
["5".padStart(15, 0), "lesson type 5", "testing", 3, "hidden"],
["6".padStart(15, 0), "中文 6", "testing", 3, "hidden"],
["7".padStart(15, 0), "レッスン7 レッスン7 レッスン7", "testing", 3, "hidden"],
[getId("1"), "Vocabulary", "vocabulary", 0, "visible"],
[getId("2"), "Connectives", "connectives", 1, "visible"],
[getId("3"), "Testing visible", "testing", 3, "visible"],
[getId("4"), "Testing hidden", "testing", 3, "hidden"],
[getId("5"), "lesson type 5", "testing", 3, "hidden"],
[getId("6"), "中文 6", "testing", 3, "hidden"],
[getId("7"), "レッスン7 レッスン7 レッスン7", "testing", 3, "hidden"],
];
dirtyTruncateTable("LessonsTypes");
@@ -28,9 +34,3 @@ module.exports = ($app) => {
}
console.log("001 lesson types seeding done");
};
const dirtyTruncateTable = (COLLECTION_NAME) => {
console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
cmd_to_exec.output();
};

View File

@@ -1,19 +1,25 @@
const config = require("/pb_hooks/seed/config.js");
const utils = require("/pb_hooks/seed/utils.js");
module.exports = ($app) => {
const ASSETS_DIR = "/pb_hooks/assets";
const getAsset = (name) => $filesystem.fileFromPath(ASSETS_DIR + "/" + name);
const id_v = "1".padStart(15, 0); //id_vocabulary
const id_c = "2".padStart(15, 0); //id_connectives
const { CR_cat_id_news, CR_cat_id_technology, id_v, id_c } = config;
const { getId, getAsset, dirtyTruncateTable } = utils;
// const ASSETS_DIR = "/pb_hooks/assets";
// const getAsset = (name) => $filesystem.fileFromPath(ASSETS_DIR + "/" + name);
// const id_v = "1".padStart(15, 0); //id_vocabulary
// const id_c = "2".padStart(15, 0); //id_connectives
let row_array = [
["1".padStart(15, 0), "news", "", getAsset("ci_news.jpg"), 1, "visible", id_v, "desc", "remarks"],
["2".padStart(15, 0), "sports", "", getAsset("ci_sports.jpg"), 1, "visible", id_v, "desc", "remarks"],
["3".padStart(15, 0), "technology", "", getAsset("ci_technology.jpg"), 1, "visible", id_v, "desc", "remarks"],
["4".padStart(15, 0), "art", "", getAsset("ci_art.jpg"), 1, "visible", id_v, "desc", "remarks"],
["5".padStart(15, 0), "basic", "", getAsset("ci_basic.jpg"), 1, "visible", id_v, "desc", "remarks"],
["6".padStart(15, 0), "nature", "", getAsset("ci_nature.jpg"), 1, "visible", id_v, "desc", "remarks"],
["7".padStart(15, 0), "workplace", "", getAsset("ci_workplace.jpg"), 1, "visible", id_v, "desc", "remarks"],
["8".padStart(15, 0), "workplace", "", getAsset("ci_workplace.jpg"), 1, "hidden", id_v, "desc", "remarks"],
["99".padStart(15, 0), "connectives", "", getAsset("1.png"), 1, "visible", id_c, "desc", "remarks"],
[getId("1"), "news", "", getAsset("ci_news.jpg"), 1, "visible", id_v, "desc", "remarks"],
[getId("2"), "sports", "", getAsset("ci_sports.jpg"), 1, "visible", id_v, "desc", "remarks"],
[getId("3"), "technology", "", getAsset("ci_technology.jpg"), 1, "visible", id_v, "desc", "remarks"],
[getId("4"), "art", "", getAsset("ci_art.jpg"), 1, "visible", id_v, "desc", "remarks"],
[getId("5"), "basic", "", getAsset("ci_basic.jpg"), 1, "visible", id_v, "desc", "remarks"],
[getId("6"), "nature", "", getAsset("ci_nature.jpg"), 1, "visible", id_v, "desc", "remarks"],
[getId("7"), "workplace", "", getAsset("ci_workplace.jpg"), 1, "visible", id_v, "desc", "remarks"],
[getId("8"), "workplace", "", getAsset("ci_workplace.jpg"), 1, "hidden", id_v, "desc", "remarks"],
[getId("99"), "connectives", "", getAsset("1.png"), 1, "visible", id_c, "desc", "remarks"],
// ["2".padStart(15, 0), "Connectives", "connectivse", 1, "visible"],
// ["3".padStart(15, 0), "Testing visible", "testing", 3, "visible"],
// ["4".padStart(15, 0), "Testing hidden", "testing", 3, "hidden"],
@@ -41,9 +47,3 @@ module.exports = ($app) => {
console.log("002 lesson categories seeding done");
};
const dirtyTruncateTable = (COLLECTION_NAME) => {
console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
cmd_to_exec.output();
};

View File

@@ -1,18 +1,28 @@
const config = require("/pb_hooks/seed/config.js");
const utils = require("/pb_hooks/seed/utils.js");
module.exports = ($app) => {
const { CR_cat_id_news, CR_cat_id_technology, id_v, id_c } = config;
const { getId, getAsset, dirtyTruncateTable } = utils;
const ASSETS_DIR = "/pb_hooks/assets";
const getAsset = (name) => $filesystem.fileFromPath(ASSETS_DIR + "/" + name);
const id_v = "1".padStart(15, 0); //id_vocabulary
const id_c = "2".padStart(15, 0); //id_connectives
// const getAsset = (name) => $filesystem.fileFromPath(ASSETS_DIR + "/" + name);
// const id_v = "1".padStart(15, 0); //id_vocabulary
// const id_c = "2".padStart(15, 0); //id_connectives
// const getId = (id) => id.padStart(15, 0);
let row_array = [
["1".padStart(15, 0), "news", "", getAsset("ci_news.jpg"), 1, "visible", id_v, "desc", "remarks"],
["2".padStart(15, 0), "sports", "", getAsset("ci_sports.jpg"), 1, "visible", id_v, "desc", "remarks"],
["3".padStart(15, 0), "technology", "", getAsset("ci_technology.jpg"), 1, "visible", id_v, "desc", "remarks"],
["4".padStart(15, 0), "art", "", getAsset("ci_art.jpg"), 1, "visible", id_v, "desc", "remarks"],
["5".padStart(15, 0), "basic", "", getAsset("ci_basic.jpg"), 1, "visible", id_v, "desc", "remarks"],
["6".padStart(15, 0), "nature", "", getAsset("ci_nature.jpg"), 1, "visible", id_v, "desc", "remarks"],
["7".padStart(15, 0), "workplace", "", getAsset("ci_workplace.jpg"), 1, "visible", id_v, "desc", "remarks"],
["99".padStart(15, 0), "connectives", "", getAsset("1.png"), 1, "visible", id_c, "desc", "remarks"],
[getId("1"), "news", "", getAsset("ci_news.jpg"), 1, "visible", id_v, "desc", "remarks"],
[getId("2"), "sports", "", getAsset("ci_sports.jpg"), 1, "visible", id_v, "desc", "remarks"],
[getId("3"), "technology", "", getAsset("ci_technology.jpg"), 1, "visible", id_v, "desc", "remarks"],
[getId("4"), "art", "", getAsset("ci_art.jpg"), 1, "visible", id_v, "desc", "remarks"],
[getId("5"), "basic", "", getAsset("ci_basic.jpg"), 1, "visible", id_v, "desc", "remarks"],
[getId("6"), "nature", "", getAsset("ci_nature.jpg"), 1, "visible", id_v, "desc", "remarks"],
[getId("7"), "workplace", "", getAsset("ci_workplace.jpg"), 1, "visible", id_v, "desc", "remarks"],
[getId("11"), "connectives", "", getAsset("1.png"), 1, "visible", id_c, "desc", "remarks"],
[getId("12"), "connectives_2", "", getAsset("1.png"), 1, "visible", id_c, "desc", "remarks"],
// ["2".padStart(15, 0), "Connectives", "connectivse", 1, "visible"],
// ["3".padStart(15, 0), "Testing visible", "testing", 3, "visible"],
// ["4".padStart(15, 0), "Testing hidden", "testing", 3, "hidden"],
@@ -41,8 +51,8 @@ module.exports = ($app) => {
console.log("003 categories seeding done");
};
const dirtyTruncateTable = (COLLECTION_NAME) => {
console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
cmd_to_exec.output();
};
// const dirtyTruncateTable = (COLLECTION_NAME) => {
// console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
// const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
// cmd_to_exec.output();
// };

View File

@@ -1,4 +1,10 @@
const config = require("/pb_hooks/seed/config.js");
const utils = require("/pb_hooks/seed/utils.js");
module.exports = ($app) => {
const { CR_cat_id_news, CR_cat_id_technology } = config;
const { getId, getAsset, dirtyTruncateTable } = utils;
console.log("004 clean user table start");
dirtyTruncateTable("Users");
@@ -7,8 +13,8 @@ module.exports = ($app) => {
console.log("004 clean user table done");
};
const dirtyTruncateTable = (COLLECTION_NAME) => {
console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
cmd_to_exec.output();
};
// const dirtyTruncateTable = (COLLECTION_NAME) => {
// console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
// const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
// cmd_to_exec.output();
// };

View File

@@ -1,46 +1,21 @@
const config = require("/pb_hooks/seed/config.js");
const utils = require("/pb_hooks/seed/utils.js");
module.exports = ($app) => {
const ASSETS_DIR = "/pb_hooks/assets";
const getAsset = (name) => $filesystem.fileFromPath(ASSETS_DIR + "/" + name);
const id_v = "1".padStart(15, 0); //id_vocabulary
const id_c = "2".padStart(15, 0); //id_connectives
const { CR_cat_id_news, CR_cat_id_technology } = config;
const { getId, getAsset } = utils;
let row_array = [
["11".padStart(15, 0), "teacher1@123.com", "teacher1@123.com", "teacher1@123.com", true, true, "test_user_1"],
["12".padStart(15, 0), "teacher2@123.com", "teacher2@123.com", "teacher2@123.com", true, true, "test_user_2"],
["13".padStart(15, 0), "teacher3@123.com", "teacher3@123.com", "teacher3@123.com", true, true, "test_user_3"],
[getId("11"), "teacher1@123.com", "teacher1@123.com", "teacher1@123.com", true, true, "test_teacher_1"],
[getId("12"), "teacher2@123.com", "teacher2@123.com", "teacher2@123.com", true, true, "test_teacher_2"],
[getId("13"), "teacher3@123.com", "teacher3@123.com", "teacher3@123.com", true, true, "test_teacher_3"],
];
// um = user_meta
let um_row_array = [
[
"11".padStart(15, 0),
"teacher1@123.com",
"active",
"11".padStart(15, 0),
JSON.stringify({}),
getAsset("people1.png"),
"teacher",
//
],
[
"12".padStart(15, 0),
"teacher2@123.com",
"active",
"12".padStart(15, 0),
JSON.stringify({}),
getAsset("people2.png"),
"teacher",
//
],
[
"13".padStart(15, 0),
"teacher3@123.com",
"active",
"13".padStart(15, 0),
JSON.stringify({}),
getAsset("people3.png"),
"teacher",
//
],
[getId("11"), "teacher1@123.com", "active", getId("11"), JSON.stringify({}), getAsset("people1.png"), "teacher", "teacher_1"],
[getId("12"), "teacher2@123.com", "pending", getId("12"), JSON.stringify({}), getAsset("people2.png"), "teacher", "teacher_2"],
[getId("13"), "teacher3@123.com", "blocked", getId("13"), JSON.stringify({}), getAsset("people3.png"), "teacher", "teacher_3"],
];
let users_collection = $app.findCollectionByNameOrId("users");
@@ -63,19 +38,29 @@ module.exports = ($app) => {
let um_record = new Record(user_metas_collection);
um_record.set("id", um[0]);
um_record.set("helloworld", um[1]);
um_record.set("state", um[2]);
um_record.set("status", um[2]);
um_record.set("user_id", um[3]);
um_record.set("meta", um[4]);
// NOTE: obslete "avatar" and use "avatar_file"
um_record.set("avatar", um[5]);
um_record.set("avatar_file", um[5]);
//
um_record.set("role", um[6]);
um_record.set("name", um[7]);
um_record.set("email", user[3]);
um_record.set("phone", "9123456" + i.toString());
$app.save(um_record);
}
console.log("005 add teacher user done");
};
const dirtyTruncateTable = (COLLECTION_NAME) => {
console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
cmd_to_exec.output();
};
// TODO: delete this ?
// const dirtyTruncateTable = (COLLECTION_NAME) => {
// console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
// const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
// cmd_to_exec.output();
// };

View File

@@ -1,23 +1,25 @@
const config = require("/pb_hooks/seed/config.js");
const utils = require("/pb_hooks/seed/utils.js");
module.exports = ($app) => {
const ASSETS_DIR = "/pb_hooks/assets";
const getAsset = (name) => $filesystem.fileFromPath(ASSETS_DIR + "/" + name);
const id_v = "1".padStart(15, 0); //id_vocabulary
const id_c = "2".padStart(15, 0); //id_connectives
const { CR_cat_id_news, CR_cat_id_technology } = config;
const { getId, getAsset } = utils;
let row_array = [
["1".padStart(15, 0), "user1@123.com", "user1@123.com", "user1@123.com", true, true, "test_user_1"],
["2".padStart(15, 0), "user2@123.com", "user2@123.com", "user2@123.com", true, true, "test_user_2"],
["3".padStart(15, 0), "user3@123.com", "user3@123.com", "user3@123.com", true, true, "test_user_3"],
["4".padStart(15, 0), "user4@123.com", "user4@123.com", "user4@123.com", true, true, "test_user_4"],
["5".padStart(15, 0), "user5@123.com", "user5@123.com", "user5@123.com", true, true, "test_user_5"],
[getId("1"), "user1@123.com", "user1@123.com", "user1@123.com", true, true, "test_student_1"],
[getId("2"), "user2@123.com", "user2@123.com", "user2@123.com", true, true, "test_student_2"],
[getId("3"), "user3@123.com", "user3@123.com", "user3@123.com", true, true, "test_student_3"],
[getId("4"), "user4@123.com", "user4@123.com", "user4@123.com", true, true, "test_student_4"],
[getId("5"), "user5@123.com", "user5@123.com", "user5@123.com", true, true, "test_student_5"],
];
// um = user_meta
let um_row_array = [
["1".padStart(15, 0), "user1@123.com", "active", "1".padStart(15, 0), JSON.stringify({}), getAsset("people1.png"), "student"],
["2".padStart(15, 0), "user2@123.com", "active", "2".padStart(15, 0), JSON.stringify({}), getAsset("people2.png"), "student"],
["3".padStart(15, 0), "user3@123.com", "active", "3".padStart(15, 0), JSON.stringify({}), getAsset("people3.png"), "student"],
["4".padStart(15, 0), "user4@123.com", "active", "4".padStart(15, 0), JSON.stringify({}), getAsset("people4.png"), "student"],
["5".padStart(15, 0), "user5@123.com", "active", "5".padStart(15, 0), JSON.stringify({}), getAsset("people5.png"), "student"],
[getId("1"), "user1@123.com", "active", getId("1"), JSON.stringify({}), getAsset("people1.png"), "student", "student_1"],
[getId("2"), "user2@123.com", "pending", getId("2"), JSON.stringify({}), getAsset("people2.png"), "student", "student_2"],
[getId("3"), "user3@123.com", "blocked", getId("3"), JSON.stringify({}), getAsset("people3.png"), "student", "student_3"],
[getId("4"), "user4@123.com", "active", getId("4"), JSON.stringify({}), getAsset("people4.png"), "student", "student_4"],
[getId("5"), "user5@123.com", "pending", getId("5"), JSON.stringify({}), getAsset("people5.png"), "student", "student_5"],
];
let users_collection = $app.findCollectionByNameOrId("users");
@@ -40,19 +42,29 @@ module.exports = ($app) => {
let um_record = new Record(user_metas_collection);
um_record.set("id", um[0]);
um_record.set("helloworld", um[1]);
um_record.set("state", um[2]);
um_record.set("status", um[2]);
um_record.set("user_id", um[3]);
um_record.set("meta", um[4]);
// NOTE: obslete "avatar" and use "avatar_file"
um_record.set("avatar", um[5]);
um_record.set("avatar_file", um[5]);
//
um_record.set("role", um[6]);
um_record.set("name", um[7]);
um_record.set("email", user[3]);
um_record.set("phone", "9123456" + i.toString());
$app.save(um_record);
}
console.log("006 add student user done");
};
const dirtyTruncateTable = (COLLECTION_NAME) => {
console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
cmd_to_exec.output();
};
// TODO: delete this ?
// const dirtyTruncateTable = (COLLECTION_NAME) => {
// console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
// const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
// cmd_to_exec.output();
// };

View File

@@ -0,0 +1,52 @@
const config = require("/pb_hooks/seed/config.js");
const utils = require("/pb_hooks/seed/utils.js");
module.exports = ($app) => {
const { CR_cat_id_news, CR_cat_id_technology } = config;
const { getId, getAsset } = utils;
const ADMIN_USER_ID = getId("999");
let row_array = [[ADMIN_USER_ID, "admin@123.com", "admin@123.com", "admin@123.com", true, true, "test_admin_1"]];
// um = user_meta
let um_row_array = [[ADMIN_USER_ID, "admin@123.com", "active", ADMIN_USER_ID, JSON.stringify({}), getAsset("people1.png"), "admin", "admin_1"]];
let users_collection = $app.findCollectionByNameOrId("users");
let user_metas_collection = $app.findCollectionByNameOrId("UserMetas");
for (let i = 0; i < row_array.length; i++) {
let user = row_array[i];
let um = um_row_array[i];
let record = new Record(users_collection);
record.set("id", user[0]);
record.set("password", user[1]);
record.set("passwordConfirm", user[2]);
record.set("email", user[3]);
record.set("emailVisibility", user[4]);
record.set("verified", user[5]);
record.set("name", user[6]);
$app.save(record);
let um_record = new Record(user_metas_collection);
um_record.set("id", um[0]);
um_record.set("helloworld", um[1]);
um_record.set("status", um[2]);
um_record.set("user_id", um[3]);
um_record.set("meta", um[4]);
// NOTE: obslete "avatar" and use "avatar_file"
um_record.set("avatar", um[5]);
um_record.set("avatar_file", um[5]);
//
um_record.set("role", um[6]);
um_record.set("name", um[7]);
um_record.set("email", user[3]);
um_record.set("phone", "9123456" + i.toString());
$app.save(um_record);
}
console.log("007 add admin user done");
};

View File

@@ -1,40 +1,58 @@
const config = require('/pb_hooks/seed/config.js');
const utils = require('/pb_hooks/seed/utils.js');
const config = require("/pb_hooks/seed/config.js");
const utils = require("/pb_hooks/seed/utils.js");
module.exports = $app => {
const { getAsset } = utils;
const { id_v, id_c, cat_id_tech } = config;
module.exports = ($app) => {
const { getId, getAsset, dirtyTruncateTable } = utils;
const { id_v, id_c, cat_id_news, cat_id_sport, cat_id_tech, cat_id_art, cat_id_basic, cat_id_nature, cat_id_workplace, cat_id_connectives_1 } = config;
// const getId = (id) => id.padStart(15, 0);
let row_datas = [
['1'.padStart(15, 0), getAsset('keyboard.jpg'), getAsset('keyboard.mp3'), 'keyboard', '鍵盤', 'sample_e', 'sample_c', cat_id_tech, '', id_v],
['2'.padStart(15, 0), getAsset('mouse.jpg'), getAsset('mouse.mp3'), 'mouse', '滑鼠', 'sample_e mouse', 'sample_c mouse', cat_id_tech, '', id_v],
[getId("1"), getAsset("keyboard.jpg"), getAsset("keyboard.mp3"), "keyboard", "鍵盤", "sample_e", "sample_c", cat_id_tech, "", id_v, "visible"],
[getId("2"), getAsset("mouse.jpg"), getAsset("mouse.mp3"), "mouse", "滑鼠", "sample_e mouse", "sample_c mouse", cat_id_tech, "", id_v, "visible"],
[getId("3"), getAsset("run.jpg"), getAsset("mouse.mp3"), "run", "跑步", "sample_e run", "sample_c run", cat_id_sport, "", id_v, "visible"],
[getId("4"), getAsset("swim.jpg"), getAsset("mouse.mp3"), "swim", "游泳", "sample_e swim", "sample_c swim", cat_id_sport, "", id_v, "visible"],
//
[getId("5"), getAsset("news1.jpg"), getAsset("news1.mp3"), "news", "新聞", "sample_e news1", "sample_c news1", cat_id_news, "", id_v, "visible"],
[getId("6"), getAsset("news2.jpg"), getAsset("news2.mp3"), "news", "新聞", "sample_e news2", "sample_c news2", cat_id_news, "", id_v, "visible"],
[getId("7"), getAsset("art1.jpg"), getAsset("art1.mp3"), "art", "藝術", "sample_e art1", "sample_c art1", cat_id_art, "", id_v, "visible"],
[getId("8"), getAsset("art2.jpg"), getAsset("art2.mp3"), "art", "藝術", "sample_e art2", "sample_c art2", cat_id_art, "", id_v, "visible"],
[getId("9"), getAsset("basic1.jpg"), getAsset("basic1.mp3"), "basic", "基礎", "sample_e basic1", "sample_c basic1", cat_id_basic, "", id_v, "visible"],
[getId("10"), getAsset("basic2.jpg"), getAsset("basic2.mp3"), "basic", "基礎", "sample_e basic2", "sample_c basic2", cat_id_basic, "", id_v, "visible"],
[getId("11"), getAsset("nature1.jpg"), getAsset("nature1.mp3"), "nature", "自然", "sample_e nature1", "sample_c nature1", cat_id_nature, "", id_v, "visible"],
[getId("12"), getAsset("nature2.jpg"), getAsset("nature2.mp3"), "nature", "自然", "sample_e nature2", "sample_c nature2", cat_id_nature, "", id_v, "visible"],
[getId("13"), getAsset("workplace1.jpg"), getAsset("workplace1.mp3"), "workplace", "工作場所", "sample_e workplace1", "sample_c workplace1", cat_id_workplace, "", id_v, "visible"],
[getId("14"), getAsset("workplace2.jpg"), getAsset("workplace2.mp3"), "workplace", "工作場所", "sample_e workplace2", "sample_c workplace2", cat_id_workplace, "", id_v, "visible"],
//
[getId("21"), getAsset("mouse.jpg"), getAsset("mouse.mp3"), "connectives 1", "連接詞 1", "connective sample_e 1", "connective sample_c 1", cat_id_connectives_1, "", id_c, "visible"],
];
dirtyTruncateTable('Vocabularies');
dirtyTruncateTable("Vocabularies");
for (let i = 0; i < row_datas.length; i++) {
let vocabularies_collection = $app.findCollectionByNameOrId('Vocabularies');
let vocabularies_collection = $app.findCollectionByNameOrId("Vocabularies");
let data = row_datas[i];
let record = new Record(vocabularies_collection);
record.set('id', data[0]);
record.set('image', data[1]);
record.set('sound', data[2]);
record.set('word', data[3]);
record.set('word_c', data[4]);
record.set('sample_e', data[5]);
record.set('sample_c', data[6]);
record.set('cat_id', data[7]);
record.set('category', data[8]);
record.set('lesson_type_id', data[9]);
record.set("id", data[0]);
record.set("image", data[1]);
record.set("sound", data[2]);
record.set("word", data[3]);
record.set("word_c", data[4]);
record.set("sample_e", data[5]);
record.set("sample_c", data[6]);
record.set("cat_id", data[7]);
record.set("category", data[8]);
record.set("lesson_type_id", data[9]);
record.set("visible", data[10]);
$app.save(record);
}
console.log('done ?');
console.log("done ?");
};
const dirtyTruncateTable = COLLECTION_NAME => {
console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
const cmd_to_exec = $os.cmd('sqlite3', '/pb_data/data.db', `DELETE from ${COLLECTION_NAME};`);
cmd_to_exec.output();
};
// TODO: delete me ?
// const dirtyTruncateTable = (COLLECTION_NAME) => {
// console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
// const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
// cmd_to_exec.output();
// };

View File

@@ -1,9 +1,14 @@
const config = require("/pb_hooks/seed/config.js");
const utils = require("/pb_hooks/seed/utils.js");
module.exports = ($app) => {
const ASSETS_DIR = "/pb_hooks/assets";
const getAsset = (name) => $filesystem.fileFromPath(ASSETS_DIR + "/" + name);
const id_v = "1".padStart(15, 0); //id_vocabulary
const id_c = "2".padStart(15, 0); //id_connectives
const getId = (id) => id.padStart(15, 0);
const { getId, getAsset, dirtyTruncateTable } = utils;
// const ASSETS_DIR = "/pb_hooks/assets";
// const getAsset = (name) => $filesystem.fileFromPath(ASSETS_DIR + "/" + name);
// const id_v = "1".padStart(15, 0); //id_vocabulary
// const id_c = "2".padStart(15, 0); //id_connectives
// const getId = (id) => id.padStart(15, 0);
let row_array = [
[getId("1"), "news (listening)", getAsset("ci_news.jpg"), 1, {}, "visible"],
[getId("2"), "sports (listening)", getAsset("ci_sports.jpg"), 2, {}, "visible"],
@@ -36,8 +41,9 @@ module.exports = ($app) => {
console.log(`020_QuizLPCategories done`);
};
const dirtyTruncateTable = (COLLECTION_NAME) => {
console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
cmd_to_exec.output();
};
// TODO: delete me ?
// const dirtyTruncateTable = (COLLECTION_NAME) => {
// console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
// const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
// cmd_to_exec.output();
// };

View File

@@ -1,20 +1,20 @@
const config = require("/pb_hooks/seed/config.js");
const utils = require("/pb_hooks/seed/utils.js");
module.exports = ($app) => {
const ASSETS_DIR = "/pb_hooks/assets";
const getAsset = (name) => $filesystem.fileFromPath(ASSETS_DIR + "/" + name);
const id_v = "1".padStart(15, 0); //id_vocabulary
const id_c = "2".padStart(15, 0); //id_connectives
const cat_id_technology = "3".padStart(15, 0);
const getId = (id) => id.padStart(15, 0);
const { LP_cat_id_news, LP_cat_id_sports, LP_cat_id_technology } = config;
const { getId, getAsset, dirtyTruncateTable } = utils;
let row_array = [
[getId("1") ,"news (LP)" ,getAsset("ci_news.jpg") ,1 ,{} ,"visible" ,"news" ,getAsset("keyboard.mp3") ,cat_id_technology] ,
[getId("2") ,"sports (LP)" ,getAsset("ci_sports.jpg") ,2 ,{} ,"visible" ,"sports" ,getAsset("mouse.mp3") ,cat_id_technology] ,
[getId("3") ,"technology (LP)" ,getAsset("ci_technology.jpg") ,3 ,{} ,"visible" ,"technology" ,getAsset("keyboard.mp3") ,cat_id_technology] ,
[getId("4") ,"art (LP)" ,getAsset("ci_art.jpg") ,4 ,{} ,"visible" ,"art" ,getAsset("mouse.mp3") ,cat_id_technology] ,
[getId("5") ,"basic (LP)" ,getAsset("ci_basic.jpg") ,5 ,{} ,"visible" ,"basic" ,getAsset("keyboard.mp3") ,cat_id_technology] ,
[getId("6") ,"nature (LP)" ,getAsset("ci_nature.jpg") ,6 ,{} ,"visible" ,"nature" ,getAsset("keyboard.mp3") ,cat_id_technology] ,
[getId("7") ,"workplace (LP)" ,getAsset("ci_workplace.jpg") ,7 ,{} ,"visible" ,"workplace" ,getAsset("keyboard.mp3") ,cat_id_technology] ,
[getId("8") ,"workplace (LP)" ,getAsset("ci_workplace.jpg") ,8 ,{} ,"visible" ,"workplace" ,getAsset("keyboard.mp3") ,cat_id_technology] ,
[getId("99") ,"test hidden (LP)" ,getAsset("ci_workplace.jpg") ,9 ,{} ,"hidden" ,"test" ,getAsset("keyboard.mp3") ,cat_id_technology] ,
[getId("1"), "news (LP)", getAsset("ci_news.jpg"), 1, ["A", "B", "C"], "visible", "news", getAsset("keyboard.mp3"), LP_cat_id_news],
[getId("2"), "sports (LP)", getAsset("ci_sports.jpg"), 2, ["A", "B", "C"], "visible", "sports", getAsset("mouse.mp3"), LP_cat_id_news],
[getId("3"), "technology (LP)", getAsset("ci_technology.jpg"), 3, ["A", "B", "C"], "visible", "technology", getAsset("keyboard.mp3"), LP_cat_id_news],
[getId("4"), "art (LP)", getAsset("ci_art.jpg"), 4, ["A", "B", "C"], "visible", "art", getAsset("mouse.mp3"), LP_cat_id_sports],
[getId("5"), "basic (LP)", getAsset("ci_basic.jpg"), 5, ["A", "B", "C"], "visible", "basic", getAsset("keyboard.mp3"), LP_cat_id_sports],
[getId("6"), "nature (LP)", getAsset("ci_nature.jpg"), 6, ["A", "B", "C"], "visible", "nature", getAsset("keyboard.mp3"), LP_cat_id_sports],
[getId("7"), "workplace (LP)", getAsset("ci_workplace.jpg"), 7, ["A", "B", "C"], "visible", "workplace", getAsset("keyboard.mp3"), LP_cat_id_technology],
[getId("8"), "workplace (LP)", getAsset("ci_workplace.jpg"), 8, ["A", "B", "C"], "visible", "workplace", getAsset("keyboard.mp3"), LP_cat_id_technology],
[getId("99"), "test hidden (LP)", getAsset("ci_workplace.jpg"), 9, ["A", "B", "C"], "hidden", "test", getAsset("keyboard.mp3"), LP_cat_id_technology],
];
dirtyTruncateTable("QuizLPQuestions");
@@ -32,7 +32,7 @@ module.exports = ($app) => {
record.set("visible", lesson_type[5]);
record.set("word", lesson_type[6]);
record.set("sound", lesson_type[7]);
record.set("cat_id", lesson_type[7]);
record.set("cat_id", lesson_type[8]);
$app.save(record);
}
@@ -40,8 +40,9 @@ module.exports = ($app) => {
console.log(`021_QuizLPQuestions done`);
};
const dirtyTruncateTable = (COLLECTION_NAME) => {
console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
cmd_to_exec.output();
};
// TODO: remove me
// const dirtyTruncateTable = (COLLECTION_NAME) => {
// console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
// const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
// cmd_to_exec.output();
// };

View File

@@ -1,35 +0,0 @@
module.exports = ($app) => {
const ASSETS_DIR = "/pb_hooks/assets";
const getAsset = (name) => $filesystem.fileFromPath(ASSETS_DIR + "/" + name);
const getId = (id) => id.padStart(15, 0);
const id_v = getId("1"); //id_vocabulary
const id_c = getId("2"); //id_connectives
let row_array = [
[getId("1"), "keyboard", getAsset("keyboard.jpg"), getId("1")],
[getId("2"), "mouse", getAsset("mouse.jpg"), getId("1")],
];
dirtyTruncateTable("QuizLPQuestions");
let lt_collection = $app.findCollectionByNameOrId("QuizLPQuestions");
for (let i = 0; i < row_array.length; i++) {
let lesson_type = row_array[i];
let record = new Record(lt_collection);
record.set("id", lesson_type[0]);
record.set("word", lesson_type[1]);
record.set("sound", lesson_type[2]);
record.set("cat_id", lesson_type[3]);
$app.save(record);
}
console.log(`021 QuizLPQuestions done`);
};
const dirtyTruncateTable = (COLLECTION_NAME) => {
console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
cmd_to_exec.output();
};

View File

@@ -1,9 +1,15 @@
const config = require("/pb_hooks/seed/config.js");
const utils = require("/pb_hooks/seed/utils.js");
module.exports = ($app) => {
const ASSETS_DIR = "/pb_hooks/assets";
const getAsset = (name) => $filesystem.fileFromPath(ASSETS_DIR + "/" + name);
const id_v = "1".padStart(15, 0); //id_vocabulary
const id_c = "2".padStart(15, 0); //id_connectives
const getId = (id) => id.padStart(15, 0);
const { CR_cat_id_news, CR_cat_id_technology } = config;
const { getId, getAsset, dirtyTruncateTable } = utils;
// const ASSETS_DIR = "/pb_hooks/assets";
// const getAsset = (name) => $filesystem.fileFromPath(ASSETS_DIR + "/" + name);
// const id_v = "1".padStart(15, 0); //id_vocabulary
// const id_c = "2".padStart(15, 0); //id_connectives
// const getId = (id) => id.padStart(15, 0);
let row_array = [
[getId("1"), "news (matching)", getAsset("ci_news.jpg"), 1, {}, "visible"],
[getId("2"), "sports (matching)", getAsset("ci_sports.jpg"), 2, {}, "visible"],
@@ -36,8 +42,9 @@ module.exports = ($app) => {
console.log(`030_QuizMFCategories done`);
};
const dirtyTruncateTable = (COLLECTION_NAME) => {
console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
cmd_to_exec.output();
};
// TODO: remove me
// const dirtyTruncateTable = (COLLECTION_NAME) => {
// console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
// const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
// cmd_to_exec.output();
// };

View File

@@ -1,20 +1,20 @@
const config = require("/pb_hooks/seed/config.js");
const utils = require("/pb_hooks/seed/utils.js");
module.exports = ($app) => {
const ASSETS_DIR = "/pb_hooks/assets";
const getAsset = (name) => $filesystem.fileFromPath(ASSETS_DIR + "/" + name);
const id_v = "1".padStart(15, 0); //id_vocabulary
const id_c = "2".padStart(15, 0); //id_connectives
const cat_id_technology = "3".padStart(15, 0);
const getId = (id) => id.padStart(15, 0);
const { MF_cat_id_news, MF_cat_id_sports, MF_cat_id_technology } = config;
const { getId, getAsset, dirtyTruncateTable } = utils;
let row_array = [
[getId("1") ,"news (MF)" ,getAsset("ci_news.jpg") ,1 ,{} ,"visible" ,"news" ,getAsset("keyboard.mp3") ,cat_id_technology] ,
[getId("2") ,"sports (MF)" ,getAsset("ci_sports.jpg") ,2 ,{} ,"visible" ,"sports" ,getAsset("mouse.mp3") ,cat_id_technology] ,
[getId("3") ,"technology (MF)" ,getAsset("ci_technology.jpg") ,3 ,{} ,"visible" ,"technology" ,getAsset("keyboard.mp3") ,cat_id_technology] ,
[getId("4") ,"art (MF)" ,getAsset("ci_art.jpg") ,4 ,{} ,"visible" ,"art" ,getAsset("mouse.mp3") ,cat_id_technology] ,
[getId("5") ,"basic (MF)" ,getAsset("ci_basic.jpg") ,5 ,{} ,"visible" ,"basic" ,getAsset("keyboard.mp3") ,cat_id_technology] ,
[getId("6") ,"nature (MF)" ,getAsset("ci_nature.jpg") ,6 ,{} ,"visible" ,"nature" ,getAsset("keyboard.mp3") ,cat_id_technology] ,
[getId("7") ,"workplace (MF)" ,getAsset("ci_workplace.jpg") ,7 ,{} ,"visible" ,"workplace" ,getAsset("keyboard.mp3") ,cat_id_technology] ,
[getId("8") ,"workplace (MF)" ,getAsset("ci_workplace.jpg") ,8 ,{} ,"visible" ,"workplace" ,getAsset("keyboard.mp3") ,cat_id_technology] ,
[getId("99") ,"test hidden (MF)" ,getAsset("ci_workplace.jpg") ,9 ,{} ,"hidden" ,"test" ,getAsset("keyboard.mp3") ,cat_id_technology] ,
[getId("1"), "news (MF)", getAsset("ci_news.jpg"), 1, ["A", "B", "C"], "visible", "chinese_1", getAsset("keyboard.mp3"), MF_cat_id_news, "中文1"],
[getId("2"), "sports (MF)", getAsset("ci_sports.jpg"), 2, ["A", "B", "C"], "visible", "chinese_2", getAsset("mouse.mp3"), MF_cat_id_news, "中文2"],
[getId("3"), "technology (MF)", getAsset("ci_technology.jpg"), 3, ["A", "B", "C"], "visible", "chinese_3", getAsset("keyboard.mp3"), MF_cat_id_news, "中文3"],
[getId("4"), "art (MF)", getAsset("ci_art.jpg"), 4, ["A", "B", "C"], "visible", "chinese_1", getAsset("mouse.mp3"), MF_cat_id_sports, "中文1"],
[getId("5"), "basic (MF)", getAsset("ci_basic.jpg"), 5, ["A", "B", "C"], "visible", "chinese_2", getAsset("keyboard.mp3"), MF_cat_id_sports, "中文2"],
[getId("6"), "nature (MF)", getAsset("ci_nature.jpg"), 6, ["A", "B", "C"], "visible", "chinese_3", getAsset("keyboard.mp3"), MF_cat_id_sports, "中文3"],
[getId("7"), "workplace (MF)", getAsset("ci_workplace.jpg"), 7, ["A", "B", "C"], "visible", "chinese_1", getAsset("keyboard.mp3"), MF_cat_id_technology, "中文1"],
[getId("8"), "workplace (MF)", getAsset("ci_workplace.jpg"), 8, ["A", "B", "C"], "visible", "chinese_2", getAsset("keyboard.mp3"), MF_cat_id_technology, "中文2"],
[getId("99"), "test hidden (MF)", getAsset("ci_workplace.jpg"), 9, ["A", "B", "C"], "hidden", "chinese_3", getAsset("keyboard.mp3"), MF_cat_id_technology, "中文3"],
];
dirtyTruncateTable("QuizMFQuestions");
@@ -32,7 +32,8 @@ module.exports = ($app) => {
record.set("visible", lesson_type[5]);
record.set("word", lesson_type[6]);
record.set("sound", lesson_type[7]);
record.set("cat_id", lesson_type[7]);
record.set("cat_id", lesson_type[8]);
record.set("word_c", lesson_type[9]);
$app.save(record);
}
@@ -40,8 +41,9 @@ module.exports = ($app) => {
console.log(`031_QuizMFQuestions done`);
};
const dirtyTruncateTable = (COLLECTION_NAME) => {
console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
cmd_to_exec.output();
};
// TODO: remove me
// const dirtyTruncateTable = (COLLECTION_NAME) => {
// console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
// const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
// cmd_to_exec.output();
// };

View File

@@ -1,9 +1,16 @@
const config = require("/pb_hooks/seed/config.js");
const utils = require("/pb_hooks/seed/utils.js");
module.exports = ($app) => {
const ASSETS_DIR = "/pb_hooks/assets";
const getAsset = (name) => $filesystem.fileFromPath(ASSETS_DIR + "/" + name);
const id_v = "1".padStart(15, 0); //id_vocabulary
const id_c = "2".padStart(15, 0); //id_connectives
const getId = (id) => id.padStart(15, 0);
const { CR_cat_id_news, CR_cat_id_technology } = config;
const { getId, getAsset, dirtyTruncateTable } = utils;
// const ASSETS_DIR = "/pb_hooks/assets";
// const getAsset = (name) => $filesystem.fileFromPath(ASSETS_DIR + "/" + name);
// const id_v = "1".padStart(15, 0); //id_vocabulary
// const id_c = "2".padStart(15, 0); //id_connectives
// const getId = (id) => id.padStart(15, 0);
let row_array = [
[getId("1"), "news (connective)", getAsset("ci_news.jpg"), 1, {}, "visible"],
[getId("2"), "sports (connective)", getAsset("ci_sports.jpg"), 2, {}, "visible"],
@@ -36,8 +43,9 @@ module.exports = ($app) => {
console.log(`040_QuizCRCategories done`);
};
const dirtyTruncateTable = (COLLECTION_NAME) => {
console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
cmd_to_exec.output();
};
// TODO: remove me
// const dirtyTruncateTable = (COLLECTION_NAME) => {
// console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
// const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
// cmd_to_exec.output();
// };

View File

@@ -1,155 +1,26 @@
const config = require("/pb_hooks/seed/config.js");
const utils = require("/pb_hooks/seed/utils.js");
module.exports = ($app) => {
const ASSETS_DIR = "/pb_hooks/assets";
const getAsset = (name) => $filesystem.fileFromPath(ASSETS_DIR + "/" + name);
const id_v = "1".padStart(15, 0); //id_vocabulary
const id_c = "2".padStart(15, 0); //id_connectives
const cat_id_technology = "3".padStart(15, 0);
const getId = (id) => id.padStart(15, 0);
const { CR_cat_id_news, CR_cat_id_technology } = config;
const { getId, getAsset, dirtyTruncateTable } = utils;
// const ASSETS_DIR = "/pb_hooks/assets";
// const getAsset = (name) => $filesystem.fileFromPath(ASSETS_DIR + "/" + name);
// const id_v = "1".padStart(15, 0); //id_vocabulary
// const id_c = "2".padStart(15, 0); //id_connectives
// const cat_id_technology = "3".padStart(15, 0);
// const getId = (id) => id.padStart(15, 0);
let row_array = [
[
getId("1"),
"news (CR)",
getAsset("ci_news.jpg"),
1,
["A", "B", "C"],
"visible",
"news",
getAsset("keyboard.mp3"),
cat_id_technology,
"question_fh_1",
"question_sh_1",
"modal_ans_1",
cat_id_technology,
["A", "B", "C"],
],
[
getId("2"),
"sports (CR)",
getAsset("ci_sports.jpg"),
2,
["A", "B", "C"],
"visible",
"sports",
getAsset("mouse.mp3"),
cat_id_technology,
"question_fh_2",
"question_sh_2",
"modal_ans_2",
cat_id_technology,
["A", "B", "C"],
],
[
getId("3"),
"technology (CR)",
getAsset("ci_technology.jpg"),
3,
["A", "B", "C"],
"visible",
"technology",
getAsset("keyboard.mp3"),
cat_id_technology,
"question_fh_3",
"question_sh_3",
"modal_ans_3",
cat_id_technology,
["A", "B", "C"],
],
[
getId("4"),
"art (CR)",
getAsset("ci_art.jpg"),
4,
["A", "B", "C"],
"visible",
"art",
getAsset("mouse.mp3"),
cat_id_technology,
"question_fh_4",
"question_sh_4",
"modal_ans_4",
cat_id_technology,
["A", "B", "C"],
],
[
getId("5"),
"basic (CR)",
getAsset("ci_basic.jpg"),
5,
["A", "B", "C"],
"visible",
"basic",
getAsset("keyboard.mp3"),
cat_id_technology,
"question_fh_5",
"question_sh_5",
"modal_ans_5",
cat_id_technology,
["A", "B", "C"],
],
[
getId("6"),
"nature (CR)",
getAsset("ci_nature.jpg"),
6,
["A", "B", "C"],
"visible",
"nature",
getAsset("keyboard.mp3"),
cat_id_technology,
"question_fh_6",
"question_sh_6",
"modal_ans_6",
cat_id_technology,
["A", "B", "C"],
],
[
getId("7"),
"workplace (CR)",
getAsset("ci_workplace.jpg"),
7,
["A", "B", "C"],
"visible",
"workplace",
getAsset("keyboard.mp3"),
cat_id_technology,
"question_fh_7",
"question_sh_7",
"modal_ans_7",
cat_id_technology,
["A", "B", "C"],
],
[
getId("8"),
"workplace (CR)",
getAsset("ci_workplace.jpg"),
8,
["A", "B", "C"],
"visible",
"workplace",
getAsset("keyboard.mp3"),
cat_id_technology,
"question_fh_8",
"question_sh_8",
"modal_ans_8",
cat_id_technology,
["A", "B", "C"],
],
[
getId("99"),
"test hidden (CR)",
getAsset("ci_workplace.jpg"),
9,
["A", "B", "C"],
"hidden",
"test",
getAsset("keyboard.mp3"),
cat_id_technology,
"question_fh_9",
"question_sh_9",
"modal_ans_9",
cat_id_technology,
["A", "B", "C"],
],
[getId("1"), "news (CR)", getAsset("ci_news.jpg"), 1, ["A", "B", "C"], "visible", "news", getAsset("keyboard.mp3"), CR_cat_id_technology, "question_fh_1", "question_sh_1", "modal_ans_1", CR_cat_id_news, ["A", "B", "C"]],
[getId("2"), "sports (CR)", getAsset("ci_sports.jpg"), 2, ["A", "B", "C"], "visible", "sports", getAsset("mouse.mp3"), CR_cat_id_technology, "question_fh_2", "question_sh_2", "modal_ans_2", CR_cat_id_news, ["A", "B", "C"]],
[getId("3"), "technology (CR)", getAsset("ci_technology.jpg"), 3, ["A", "B", "C"], "visible", "technology", getAsset("keyboard.mp3"), CR_cat_id_technology, "question_fh_3", "question_sh_3", "modal_ans_3", CR_cat_id_news, ["A", "B", "C"]],
[getId("4"), "art (CR)", getAsset("ci_art.jpg"), 4, ["A", "B", "C"], "visible", "art", getAsset("mouse.mp3"), CR_cat_id_technology, "question_fh_4", "question_sh_4", "modal_ans_4", CR_cat_id_news, ["A", "B", "C"]],
[getId("5"), "basic (CR)", getAsset("ci_basic.jpg"), 5, ["A", "B", "C"], "visible", "basic", getAsset("keyboard.mp3"), CR_cat_id_technology, "question_fh_5", "question_sh_5", "modal_ans_5", CR_cat_id_news, ["A", "B", "C"]],
[getId("6"), "nature (CR)", getAsset("ci_nature.jpg"), 6, ["A", "B", "C"], "visible", "nature", getAsset("keyboard.mp3"), CR_cat_id_technology, "question_fh_6", "question_sh_6", "modal_ans_6", CR_cat_id_technology, ["A", "B", "C"]],
[getId("7"), "workplace (CR)", getAsset("ci_workplace.jpg"), 7, ["A", "B", "C"], "visible", "workplace", getAsset("keyboard.mp3"), CR_cat_id_technology, "question_fh_7", "question_sh_7", "modal_ans_7", CR_cat_id_technology, ["A", "B", "C"]],
[getId("8"), "workplace (CR)", getAsset("ci_workplace.jpg"), 8, ["A", "B", "C"], "visible", "workplace", getAsset("keyboard.mp3"), CR_cat_id_technology, "question_fh_8", "question_sh_8", "modal_ans_8", CR_cat_id_technology, ["A", "B", "C"]],
[getId("99"), "test hidden (CR)", getAsset("ci_workplace.jpg"), 9, ["A", "B", "C"], "hidden", "test", getAsset("keyboard.mp3"), CR_cat_id_technology, "question_fh_9", "question_sh_9", "modal_ans_9", CR_cat_id_technology, ["A", "B", "C"]],
];
dirtyTruncateTable("QuizCRQuestions");
@@ -167,7 +38,7 @@ module.exports = ($app) => {
record.set("visible", lesson_type[5]);
record.set("word", lesson_type[6]);
record.set("sound", lesson_type[7]);
record.set("cat_id", lesson_type[7]);
// record.set("cat_id", lesson_type[7]);
record.set("question_fh", lesson_type[9]);
record.set("question_sh", lesson_type[10]);
record.set("modal_ans", lesson_type[11]);
@@ -180,8 +51,9 @@ module.exports = ($app) => {
console.log(`041_QuizCRQuestions done`);
};
const dirtyTruncateTable = (COLLECTION_NAME) => {
console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
cmd_to_exec.output();
};
// TODO: remove me
// const dirtyTruncateTable = (COLLECTION_NAME) => {
// console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
// const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
// cmd_to_exec.output();
// };

View File

@@ -1,17 +1,23 @@
//
// RULES: this is not a normal nodejs engine, it is a nodejs provided by golang, so fakerjs cannot be used here
//
const config = require("/pb_hooks/seed/config.js");
const utils = require("/pb_hooks/seed/utils.js");
//
module.exports = ($app) => {
const ASSETS_DIR = "/pb_hooks/assets";
const getAsset = (name) => $filesystem.fileFromPath(ASSETS_DIR + "/" + name);
const id_v = "1".padStart(15, 0); //id_vocabulary
const id_c = "2".padStart(15, 0); //id_connectives
const getId = (id) => id.padStart(15, 0);
const { CR_cat_id_news, CR_cat_id_technology } = config;
const { getId, getAsset, dirtyTruncateTable } = utils;
// const ASSETS_DIR = "/pb_hooks/assets";
// const getAsset = (name) => $filesystem.fileFromPath(ASSETS_DIR + "/" + name);
// const id_v = "1".padStart(15, 0); //id_vocabulary
// const id_c = "2".padStart(15, 0); //id_connectives
// const getId = (id) => id.padStart(15, 0);
// generate from `./project/001_documentation/Requirements/REQ0006/gen_customer/gen_customer.mjs`
const SAMPLE_CUSTOMER_ARRAY = [
[
"000000000000001",
getId("1"),
"May",
getAsset("customer1.png"),
"June_Wintheiser33@hotmail.com",
@@ -32,7 +38,7 @@ module.exports = ($app) => {
"active",
],
[
"000000000000002",
getId("2"),
"Marilyne",
getAsset("customer2.png"),
"Carol_Blick@yahoo.com",
@@ -53,7 +59,7 @@ module.exports = ($app) => {
"pending",
],
[
"000000000000003",
getId("3"),
"Jacklyn",
getAsset("customer3.png"),
"Tamara_Lynch11@yahoo.com",
@@ -74,7 +80,7 @@ module.exports = ($app) => {
"blocked",
],
[
"000000000000004",
getId("4"),
"Alana",
getAsset("customer4.png"),
"Ahmed_Willms@hotmail.com",
@@ -95,7 +101,7 @@ module.exports = ($app) => {
"active",
],
[
"000000000000005",
getId("5"),
"Rocky",
getAsset("customer5.png"),
"Angela_Kuhic@gmail.com",
@@ -145,8 +151,9 @@ module.exports = ($app) => {
console.log(`050_Customers done`);
};
const dirtyTruncateTable = (COLLECTION_NAME) => {
console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
cmd_to_exec.output();
};
// TODO: remove me
// const dirtyTruncateTable = (COLLECTION_NAME) => {
// console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
// const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
// cmd_to_exec.output();
// };

View File

@@ -1,13 +1,17 @@
//
// RULES: this is not a normal nodejs engine, it is a nodejs provided by golang, so fakerjs cannot be used here
//
const config = require("/pb_hooks/seed/config.js");
const utils = require("/pb_hooks/seed/utils.js");
//
module.exports = ($app) => {
const ASSETS_DIR = "/pb_hooks/assets";
const getAsset = (name) => $filesystem.fileFromPath(ASSETS_DIR + "/" + name);
const id_v = "1".padStart(15, 0); //id_vocabulary
const id_c = "2".padStart(15, 0); //id_connectives
const getId = (id) => id.padStart(15, 0);
const { CR_cat_id_news, CR_cat_id_technology } = config;
const { getId, getAsset, dirtyTruncateTable } = utils;
// const ASSETS_DIR = "/pb_hooks/assets";
// const getAsset = (name) => $filesystem.fileFromPath(ASSETS_DIR + "/" + name);
// const id_v = "1".padStart(15, 0); //id_vocabulary
// const id_c = "2".padStart(15, 0); //id_connectives
// const getId = (id) => id.padStart(15, 0);
// generate from `./project/001_documentation/Requirements/REQ0006/gen_customer/gen_customer.mjs`
const TEACHER_ARRAY = [
[
@@ -145,8 +149,9 @@ module.exports = ($app) => {
console.log(`051_Teacher done`);
};
const dirtyTruncateTable = (COLLECTION_NAME) => {
console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
cmd_to_exec.output();
};
// TODO: remove me
// const dirtyTruncateTable = (COLLECTION_NAME) => {
// console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
// const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
// cmd_to_exec.output();
// };

View File

@@ -1,12 +1,18 @@
//
// RULES: this is not a normal nodejs engine, it is a nodejs provided by golang, so fakerjs cannot be used here
//
const config = require("/pb_hooks/seed/config.js");
const utils = require("/pb_hooks/seed/utils.js");
//
module.exports = ($app) => {
const ASSETS_DIR = "/pb_hooks/assets";
const getAsset = (name) => $filesystem.fileFromPath(ASSETS_DIR + "/" + name);
const id_v = "1".padStart(15, 0); //id_vocabulary
const id_c = "2".padStart(15, 0); //id_connectives
const getId = (id) => id.padStart(15, 0);
const { CR_cat_id_news, CR_cat_id_technology } = config;
const { getId, getAsset, dirtyTruncateTable } = utils;
// const ASSETS_DIR = "/pb_hooks/assets";
// const getAsset = (name) => $filesystem.fileFromPath(ASSETS_DIR + "/" + name);
// const id_v = "1".padStart(15, 0); //id_vocabulary
// const id_c = "2".padStart(15, 0); //id_connectives
// const getId = (id) => id.padStart(15, 0);
// generate from `./project/001_documentation/Requirements/REQ0006/gen_customer/gen_customer.mjs`
const STUDENT_ARRAY = [
@@ -145,8 +151,9 @@ module.exports = ($app) => {
console.log(`052_Students done`);
};
const dirtyTruncateTable = (COLLECTION_NAME) => {
console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
cmd_to_exec.output();
};
// TODO: remove me
// const dirtyTruncateTable = (COLLECTION_NAME) => {
// console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
// const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
// cmd_to_exec.output();
// };

View File

@@ -1,53 +1,25 @@
//
// RULES: this is not a normal nodejs engine, it is a nodejs provided by golang, so fakerjs cannot be used here
//
const config = require("/pb_hooks/seed/config.js");
const utils = require("/pb_hooks/seed/utils.js");
//
module.exports = ($app) => {
const ASSETS_DIR = "/pb_hooks/assets";
const getAsset = (name) => $filesystem.fileFromPath(ASSETS_DIR + "/" + name);
const id_v = "1".padStart(15, 0); //id_vocabulary
const id_c = "2".padStart(15, 0); //id_connectives
const getId = (id) => id.padStart(15, 0);
const { CR_cat_id_news, CR_cat_id_technology } = config;
const { getId, getAsset, dirtyTruncateTable } = utils;
// const ASSETS_DIR = "/pb_hooks/assets";
// const getAsset = (name) => $filesystem.fileFromPath(ASSETS_DIR + "/" + name);
// const id_v = "1".padStart(15, 0); //id_vocabulary
// const id_c = "2".padStart(15, 0); //id_connectives
// const getId = (id) => id.padStart(15, 0);
// generate from `./project/001_documentation/Requirements/REQ0006/gen_customer/gen_customer.mjs`
const SAMPLE_CUSTOMER_ARRAY = [
[
getId('1'),
'EV-004',
false,
'new_job',
{ "id":getId("1"),"name": 'Jie Yan', "avatar": '/assets/avatar-8.png' },
{ "title": 'Remote React / React Native Developer' },
""
],
[
getId('2'),
'EV-003',
true,
'new_job',
{ "id": getId("2"),"name": 'Fran Perez', "avatar": '/assets/avatar-5.png' },
{ "title": 'Senior Golang Backend Engineer' },
""
],
[
getId('3'),
'EV-002',
true,
'new_feature',
'',
'',
'Logistics management is now available'
],
[
getId('4'),
'EV-001',
true,
'new_company',
{"id":getId("3"), "name": 'Jie Yan', "avatar": '/assets/avatar-8.png' },
{ "name": 'Stripe' },
""
],
[getId("1"), "EV-004", false, "new_job", { id: getId("1"), name: "Jie Yan", avatar: "/assets/avatar-8.png" }, { title: "Remote React / React Native Developer" }, ""],
[getId("2"), "EV-003", true, "new_job", { id: getId("2"), name: "Fran Perez", avatar: "/assets/avatar-5.png" }, { title: "Senior Golang Backend Engineer" }, ""],
[getId("3"), "EV-002", true, "new_feature", "", "", "Logistics management is now available"],
[getId("4"), "EV-001", true, "new_company", { id: getId("3"), name: "Jie Yan", avatar: "/assets/avatar-8.png" }, { name: "Stripe" }, ""],
];
let row_array = SAMPLE_CUSTOMER_ARRAY;
@@ -73,8 +45,9 @@ module.exports = ($app) => {
console.log(`060_Notifications done`);
};
const dirtyTruncateTable = (COLLECTION_NAME) => {
console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
cmd_to_exec.output();
};
// TODO: remove me
// const dirtyTruncateTable = (COLLECTION_NAME) => {
// console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
// const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
// cmd_to_exec.output();
// };

View File

@@ -1,6 +1,27 @@
module.exports = {
ASSETS_DIR: '/pb_hooks/assets',
id_v: '1'.padStart(15, 0), //id_vocabulary
id_c: '2'.padStart(15, 0), //id_connectives
cat_id_tech: '3'.padStart(15, 0), // category id of technology
ASSETS_DIR: "/pb_hooks/assets",
id_v: "1".padStart(15, 0), //id_vocabulary
id_c: "2".padStart(15, 0), //id_connectives
//
cat_id_news: "1".padStart(15, 0), // category id of news
cat_id_sport: "2".padStart(15, 0), // category id of sports
cat_id_tech: "3".padStart(15, 0), // category id of technology
cat_id_art: "4".padStart(15, 0), // category id of art
cat_id_basic: "5".padStart(15, 0), // category id of basic
cat_id_nature: "6".padStart(15, 0), // category id of nature
cat_id_workplace: "7".padStart(15, 0), // category id of workplace
//
cat_id_connectives_1: "11".padStart(15, 0), // category id of workplace
//
LP_cat_id_news: "1".padStart(15, 0),
LP_cat_id_sports: "2".padStart(15, 0),
LP_cat_id_technology: "3".padStart(15, 0),
//
MF_cat_id_news: "1".padStart(15, 0),
MF_cat_id_sports: "2".padStart(15, 0),
MF_cat_id_technology: "3".padStart(15, 0),
//
CR_cat_id_news: "1".padStart(15, 0),
CR_cat_id_sports: "2".padStart(15, 0),
CR_cat_id_technology: "3".padStart(15, 0),
};

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,19 @@
const config = require('/pb_hooks/seed/config.js');
const config = require("/pb_hooks/seed/config.js");
module.exports = {
getAsset: name => {
const file_full_path = config.ASSETS_DIR + '/' + name;
getAsset: (name) => {
const file_full_path = config.ASSETS_DIR + "/" + name;
try {
return $filesystem.fileFromPath(file_full_path);
} catch (error) {
console.log('file not found: ' + file_full_path, +'please check if file exist');
console.log("file not found: " + file_full_path, +"please check if file exist");
}
},
getId: (id) => id.padStart(15, 0),
dirtyTruncateTable: (COLLECTION_NAME) => {
console.log(`perform dirty method to truncate table "${COLLECTION_NAME}"`);
const cmd_to_exec = $os.cmd("sqlite3", "/pb_data/data.db", `DELETE from ${COLLECTION_NAME};`);
cmd_to_exec.output();
},
};

View File

@@ -0,0 +1,14 @@
{
"folders": [
{
"path": "."
},
{
"path": "./../../001_documentation"
},
{
"path": "../../000_AI_WORKSPACE"
}
],
"settings": {}
}

19
002_source/scripts/backup.sh Executable file
View File

@@ -0,0 +1,19 @@
#!/usr/bin/env bash
set -ex
# GLOBAL_EXCLUDE="--exclude={'**/.git','**/node_modules','**/.pnpm','**//**'}"
# tar -zcvf _archive/cms/018.tar.gz \
# --exclude "node_modules" \
# --exclude ".next" \
# cms
rsync -avzh \
--exclude ".next" \
--exclude "node_modules" \
--exclude ".pnpm" \
--exclude ".git" \
cms _archive/006_cms_start_categories_edit
echo "done"

36
002_source/scripts/dc_build.sh Executable file
View File

@@ -0,0 +1,36 @@
#!/usr/bin/env bash
set -ex
# cms_ubuntu use nvm docker image
cd ../005_references/nvm
# docker build -t 192.168.10.61:5000/nvm_ubuntu:latest .
# docker tag nvm_ubuntu 192.168.10.61:5000/nvm_ubuntu
# docker build -t nvm_ubuntu:latest .
# docker run -it nvm_ubuntu:latest bash
# docker run -it 192.168.10.61:5000/nvm_ubuntu:latest bash
cd -
cd ./cms
docker build -t 192.168.10.61:5000/cms_ubuntu:latest .
cd -
# ionic_mobile
cd ./ionic_mobile
docker build -t 192.168.10.61:5000/ionic_mobile_ubuntu:latest .
cd -
# api_ts
cd ./api_ts
docker build -t 192.168.10.61:5000/api_ts_ubuntu:latest .
cd -
# # pocketbase
# echo "done"
docker push 192.168.10.61:5000/nvm_ubuntu:latest
docker push 192.168.10.61:5000/cms_ubuntu:latest
docker push 192.168.10.61:5000/api_ts_ubuntu:latest
docker push 192.168.10.61:5000/ionic_mobile_ubuntu:latest

17
002_source/scripts/dc_dev.sh Executable file
View File

@@ -0,0 +1,17 @@
#!/usr/bin/env bash
set -ex
docker compose kill
docker compose down
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d pocketbase api_ts --remove-orphans
# docker compose logs -f pocketbase api_ts
echo "done"
echo "please run yourself !!!!"
echo "nodemon -w /pb_hooks --exec "pocketbase seed""
echo ""
docker compose exec -it pocketbase sh

20
002_source/scripts/dc_up.sh Executable file
View File

@@ -0,0 +1,20 @@
#!/usr/bin/env bash
set -ex
# docker compose build
# cd cms
# # nvm use 18
# npm run build
# cd -
# cd ionic_mobile
# npm run build
# cd -
docker compose up -d
docker compose logs -f
echo "done"

6
002_source/scripts/run.sh Executable file
View File

@@ -0,0 +1,6 @@
#!/usr/bin/env bash
set -ex
docker compose exec -it cms bash
echo "done"

18
TODO.md Normal file
View File

@@ -0,0 +1,18 @@
# TODO
- [ ] quiz -> listening practice content change to use api
- [ ] quiz -> matching frenzy content change to use api
- [ ] quiz -> connective revision content change to use api
- [x] lesson content change to use api
- [ ] rework for dockerfile, docker-compose for nvm
---
last stopped at:
`http://localhost:3000/dashboard/lesson_categories/edit/k17skxdo4j6w39f`
## related
[[001_documentation/Requirements/REQ0002/index.md]]

17
backup.sh Executable file
View File

@@ -0,0 +1,17 @@
#!/usr/bin/env bash
set -ex
# tar -zcvf ./_archive/020_update_fix_edit_page_error.tar.gz \
# --exclude "node_modules" \
# --exclude ".next" \
# --exclude ".git" \
# ./project
rsync -avh \
--exclude ".next" \
--exclude "node_modules" \
--exclude ".git" \
. ../_archive/022_init_lesson_categories
echo "done"

22
scripts/clean.sh Executable file
View File

@@ -0,0 +1,22 @@
#!/usr/bin/env bash
ls **/*Zone.Identifier
ls **/_archive/.next
ls **/_archive/.pnpm
ls **/_archive/node_modules
ls **/_del/.next
ls **/_del/.pnpm
ls **/_del/node_modules
set -e
read -p "Press [Enter] key to clean directories..."
rm -rf **/.next
rm -rf **/.pnpm
rm -rf **/node_modules
rm -rf **/*Zone.Identifier
echo "clean done"