Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
canifa_note
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Vũ Hoàng Anh
canifa_note
Commits
a3a1bbe8
Commit
a3a1bbe8
authored
Dec 19, 2023
by
Steven
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: tweak responsible styles
parent
fe4ec0b1
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
407 additions
and
395 deletions
+407
-395
10002__memo.sql
store/db/sqlite/seed/10002__memo.sql
+1
-2
index.tsx
web/src/components/MemoEditor/index.tsx
+0
-1
MobileHeader.tsx
web/src/components/MobileHeader.tsx
+9
-1
global.css
web/src/css/global.css
+1
-1
Root.tsx
web/src/layouts/Root.tsx
+1
-1
Archived.tsx
web/src/pages/Archived.tsx
+19
-17
Explore.tsx
web/src/pages/Explore.tsx
+2
-2
Home.tsx
web/src/pages/Home.tsx
+7
-5
Inboxes.tsx
web/src/pages/Inboxes.tsx
+24
-22
MemoDetail.tsx
web/src/pages/MemoDetail.tsx
+101
-99
Resources.tsx
web/src/pages/Resources.tsx
+95
-93
Setting.tsx
web/src/pages/Setting.tsx
+75
-73
SignIn.tsx
web/src/pages/SignIn.tsx
+1
-1
SignUp.tsx
web/src/pages/SignUp.tsx
+1
-1
Timeline.tsx
web/src/pages/Timeline.tsx
+63
-61
UserProfile.tsx
web/src/pages/UserProfile.tsx
+7
-15
No files found.
store/db/sqlite/seed/10002__memo.sql
View file @
a3a1bbe8
...
@@ -20,8 +20,7 @@ VALUES
...
@@ -20,8 +20,7 @@ VALUES
'#TODO
'#TODO
- [x] Take more photos about **🌄 sunset**;
- [x] Take more photos about **🌄 sunset**;
- [x] Clean the room;
- [x] Clean the room;
- [ ] Read *📖 The Little Prince*;
- [ ] Read *📖 The Little Prince*;'
,
(👆 click to toggle status)'
,
101
,
101
,
'PROTECTED'
'PROTECTED'
);
);
...
...
web/src/components/MemoEditor/index.tsx
View file @
a3a1bbe8
...
@@ -72,7 +72,6 @@ const MemoEditor = (props: Props) => {
...
@@ -72,7 +72,6 @@ const MemoEditor = (props: Props) => {
useEffect
(()
=>
{
useEffect
(()
=>
{
editorRef
.
current
?.
setContent
(
contentCache
||
""
);
editorRef
.
current
?.
setContent
(
contentCache
||
""
);
handleEditorFocus
();
},
[]);
},
[]);
useEffect
(()
=>
{
useEffect
(()
=>
{
...
...
web/src/components/MobileHeader.tsx
View file @
a3a1bbe8
import
classNames
from
"classnames"
;
import
{
useState
}
from
"react"
;
import
{
useState
}
from
"react"
;
import
{
useWindowScroll
}
from
"react-use"
;
import
useResponsiveWidth
from
"@/hooks/useResponsiveWidth"
;
import
useResponsiveWidth
from
"@/hooks/useResponsiveWidth"
;
import
NavigationDrawer
from
"./NavigationDrawer"
;
import
NavigationDrawer
from
"./NavigationDrawer"
;
...
@@ -10,9 +12,15 @@ const MobileHeader = (props: Props) => {
...
@@ -10,9 +12,15 @@ const MobileHeader = (props: Props) => {
const
{
children
}
=
props
;
const
{
children
}
=
props
;
const
{
sm
}
=
useResponsiveWidth
();
const
{
sm
}
=
useResponsiveWidth
();
const
[
titleText
]
=
useState
(
"MEMOS"
);
const
[
titleText
]
=
useState
(
"MEMOS"
);
const
{
y
:
offsetTop
}
=
useWindowScroll
();
return
(
return
(
<
div
className=
"sticky top-0 pt-4 sm:pt-1 pb-1 mb-1 backdrop-blur flex md:hidden flex-row justify-between items-center w-full h-auto flex-nowrap shrink-0 z-2"
>
<
div
className=
{
classNames
(
"sticky top-0 pt-4 sm:pt-1 px-4 pb-1 mb-1 backdrop-blur flex md:hidden flex-row justify-between items-center w-full h-auto flex-nowrap shrink-0 z-2"
,
offsetTop
>
0
&&
"shadow-md"
)
}
>
<
div
className=
"flex flex-row justify-start items-center mr-2 shrink-0 overflow-hidden"
>
<
div
className=
"flex flex-row justify-start items-center mr-2 shrink-0 overflow-hidden"
>
{
!
sm
&&
<
NavigationDrawer
/>
}
{
!
sm
&&
<
NavigationDrawer
/>
}
<
span
<
span
...
...
web/src/css/global.css
View file @
a3a1bbe8
body
{
body
{
@apply
text-base
w-full
min-h-
full
p-0
m-0
bg-zinc-100
dark
:
bg-zinc-800
;
@apply
text-base
w-full
min-h-
[100svh]
p-0
m-0
bg-zinc-100
dark
:
bg-zinc-800
;
}
}
#root
{
#root
{
...
...
web/src/layouts/Root.tsx
View file @
a3a1bbe8
...
@@ -13,7 +13,7 @@ function Root() {
...
@@ -13,7 +13,7 @@ function Root() {
<
Navigation
/>
<
Navigation
/>
</
div
>
</
div
>
)
}
)
}
<
main
className=
"w-full
sm:px-4
h-auto flex-grow shrink flex flex-col justify-start items-center"
>
<
main
className=
"w-full h-auto flex-grow shrink flex flex-col justify-start items-center"
>
<
Outlet
/>
<
Outlet
/>
</
main
>
</
main
>
</
div
>
</
div
>
...
...
web/src/pages/Archived.tsx
View file @
a3a1bbe8
...
@@ -30,24 +30,26 @@ const Archived = () => {
...
@@ -30,24 +30,26 @@ const Archived = () => {
},
[
memos
]);
},
[
memos
]);
return
(
return
(
<
section
className=
"@container w-full max-w-
3xl min-h-full flex flex-col justify-start items-start px-4 sm:px-2
sm:pt-4 pb-8"
>
<
section
className=
"@container w-full max-w-
4xl min-h-full flex flex-col justify-start items-start
sm:pt-4 pb-8"
>
<
MobileHeader
/>
<
MobileHeader
/>
{
loadingState
.
isLoading
?
(
<
div
className=
"w-full px-4"
>
<
div
className=
"w-full h-32 flex flex-col justify-center items-center"
>
{
loadingState
.
isLoading
?
(
<
p
className=
"opacity-70"
>
{
t
(
"memo.fetching-data"
)
}
</
p
>
<
div
className=
"w-full h-32 flex flex-col justify-center items-center"
>
</
div
>
<
p
className=
"opacity-70"
>
{
t
(
"memo.fetching-data"
)
}
</
p
>
)
:
archivedMemos
.
length
===
0
?
(
</
div
>
<
div
className=
"w-full mt-16 mb-8 flex flex-col justify-center items-center italic"
>
)
:
archivedMemos
.
length
===
0
?
(
<
Empty
/>
<
div
className=
"w-full mt-16 mb-8 flex flex-col justify-center items-center italic"
>
<
p
className=
"mt-4 text-gray-600 dark:text-gray-400"
>
{
t
(
"message.no-data"
)
}
</
p
>
<
Empty
/>
</
div
>
<
p
className=
"mt-4 text-gray-600 dark:text-gray-400"
>
{
t
(
"message.no-data"
)
}
</
p
>
)
:
(
</
div
>
<
div
className=
"w-full flex flex-col justify-start items-start"
>
)
:
(
{
archivedMemos
.
map
((
memo
)
=>
(
<
div
className=
"w-full flex flex-col justify-start items-start"
>
<
ArchivedMemo
key=
{
`${memo.id}-${memo.updatedTs}`
}
memo=
{
memo
}
/>
{
archivedMemos
.
map
((
memo
)
=>
(
))
}
<
ArchivedMemo
key=
{
`${memo.id}-${memo.updatedTs}`
}
memo=
{
memo
}
/>
</
div
>
))
}
)
}
</
div
>
)
}
</
div
>
</
section
>
</
section
>
);
);
};
};
...
...
web/src/pages/Explore.tsx
View file @
a3a1bbe8
...
@@ -54,9 +54,9 @@ const Explore = () => {
...
@@ -54,9 +54,9 @@ const Explore = () => {
};
};
return
(
return
(
<
section
className=
"@container w-full max-w-
3xl min-h-full flex flex-col justify-start items-center px-4 sm:px-2
sm:pt-4 pb-8"
>
<
section
className=
"@container w-full max-w-
4xl min-h-full flex flex-col justify-start items-center
sm:pt-4 pb-8"
>
<
MobileHeader
/>
<
MobileHeader
/>
<
div
className=
"relative w-full h-auto flex flex-col justify-start items-start"
>
<
div
className=
"relative w-full h-auto flex flex-col justify-start items-start
px-4
"
>
<
MemoFilter
/>
<
MemoFilter
/>
{
sortedMemos
.
map
((
memo
)
=>
(
{
sortedMemos
.
map
((
memo
)
=>
(
<
Memo
key=
{
memo
.
id
}
memo=
{
memo
}
lazyRendering
showCreator
showParent
/>
<
Memo
key=
{
memo
.
id
}
memo=
{
memo
}
lazyRendering
showCreator
showParent
/>
...
...
web/src/pages/Home.tsx
View file @
a3a1bbe8
...
@@ -9,14 +9,16 @@ const Home = () => {
...
@@ -9,14 +9,16 @@ const Home = () => {
const
{
md
}
=
useResponsiveWidth
();
const
{
md
}
=
useResponsiveWidth
();
return
(
return
(
<
div
className=
"w-full flex flex-row justify-center items-start"
>
<
div
className=
"w-full
max-w-4xl
flex flex-row justify-center items-start"
>
<
div
className=
"w-full
px-4 max-w-3xl sm:px-2
sm:pt-4"
>
<
div
className=
"w-full sm:pt-4"
>
<
MobileHeader
>
{
!
md
&&
<
HomeSidebarDrawer
/>
}
</
MobileHeader
>
<
MobileHeader
>
{
!
md
&&
<
HomeSidebarDrawer
/>
}
</
MobileHeader
>
<
MemoEditor
className=
"mb-2"
cacheKey=
"home-memo-editor"
/>
<
div
className=
"w-full px-4 md:pr-2"
>
<
MemoList
/>
<
MemoEditor
className=
"mb-2"
cacheKey=
"home-memo-editor"
/>
<
MemoList
/>
</
div
>
</
div
>
</
div
>
{
md
&&
(
{
md
&&
(
<
div
className=
"hidden md:block sticky top-0 left-0 w-56"
>
<
div
className=
"hidden md:block sticky top-0 left-0
shrink-0
w-56"
>
<
HomeSidebar
/>
<
HomeSidebar
/>
</
div
>
</
div
>
)
}
)
}
...
...
web/src/pages/Inboxes.tsx
View file @
a3a1bbe8
...
@@ -20,30 +20,32 @@ const Inboxes = () => {
...
@@ -20,30 +20,32 @@ const Inboxes = () => {
},
[]);
},
[]);
return
(
return
(
<
section
className=
"@container w-full max-w-
3xl min-h-full flex flex-col justify-start items-center px-4 sm:px-2
sm:pt-4 pb-8"
>
<
section
className=
"@container w-full max-w-
4xl min-h-full flex flex-col justify-start items-center
sm:pt-4 pb-8"
>
<
MobileHeader
/>
<
MobileHeader
/>
<
div
className=
"w-full shadow flex flex-col justify-start items-start px-4 py-3 rounded-xl bg-white dark:bg-zinc-700 text-black dark:text-gray-300"
>
<
div
className=
"w-full px-4"
>
<
div
className=
"relative w-full flex flex-row justify-between items-center"
>
<
div
className=
"w-full shadow flex flex-col justify-start items-start px-4 py-3 rounded-xl bg-white dark:bg-zinc-700 text-black dark:text-gray-300"
>
<
p
className=
"px-2 py-1 flex flex-row justify-start items-center select-none opacity-80"
>
<
div
className=
"relative w-full flex flex-row justify-between items-center"
>
<
Icon
.
Bell
className=
"w-5 h-auto mr-1"
/>
{
t
(
"common.inbox"
)
}
<
p
className=
"px-2 py-1 flex flex-row justify-start items-center select-none opacity-80"
>
</
p
>
<
Icon
.
Bell
className=
"w-5 h-auto mr-1"
/>
{
t
(
"common.inbox"
)
}
</
div
>
</
p
>
<
div
className=
"w-full h-auto flex flex-col justify-start items-start px-2 pb-4 bg-white dark:bg-zinc-700"
>
</
div
>
{
inboxes
.
length
===
0
&&
(
<
div
className=
"w-full h-auto flex flex-col justify-start items-start px-2 pb-4 bg-white dark:bg-zinc-700"
>
<
div
className=
"w-full mt-4 mb-8 flex flex-col justify-center items-center italic"
>
{
inboxes
.
length
===
0
&&
(
<
Empty
/>
<
div
className=
"w-full mt-4 mb-8 flex flex-col justify-center items-center italic"
>
<
p
className=
"mt-4 text-gray-600 dark:text-gray-400"
>
{
t
(
"message.no-data"
)
}
</
p
>
<
Empty
/>
<
p
className=
"mt-4 text-gray-600 dark:text-gray-400"
>
{
t
(
"message.no-data"
)
}
</
p
>
</
div
>
)
}
<
div
className=
"flex flex-col justify-start items-start w-full mt-4 gap-4"
>
{
inboxes
.
map
((
inbox
)
=>
{
if
(
inbox
.
type
===
Inbox_Type
.
TYPE_MEMO_COMMENT
)
{
return
<
MemoCommentMessage
key=
{
`${inbox.name}-${inbox.status}`
}
inbox=
{
inbox
}
/>;
}
else
if
(
inbox
.
type
===
Inbox_Type
.
TYPE_VERSION_UPDATE
)
{
return
<
VersionUpdateMessage
key=
{
`${inbox.name}-${inbox.status}`
}
inbox=
{
inbox
}
/>;
}
return
undefined
;
})
}
</
div
>
</
div
>
)
}
<
div
className=
"flex flex-col justify-start items-start w-full mt-4 gap-4"
>
{
inboxes
.
map
((
inbox
)
=>
{
if
(
inbox
.
type
===
Inbox_Type
.
TYPE_MEMO_COMMENT
)
{
return
<
MemoCommentMessage
key=
{
`${inbox.name}-${inbox.status}`
}
inbox=
{
inbox
}
/>;
}
else
if
(
inbox
.
type
===
Inbox_Type
.
TYPE_VERSION_UPDATE
)
{
return
<
VersionUpdateMessage
key=
{
`${inbox.name}-${inbox.status}`
}
inbox=
{
inbox
}
/>;
}
return
undefined
;
})
}
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
...
...
web/src/pages/MemoDetail.tsx
View file @
a3a1bbe8
...
@@ -110,114 +110,116 @@ const MemoDetail = () => {
...
@@ -110,114 +110,116 @@ const MemoDetail = () => {
};
};
return
(
return
(
<
section
className=
"@container w-full max-w-
3xl min-h-full flex flex-col justify-start items-center px-4 sm:px-2
sm:pt-4 pb-8"
>
<
section
className=
"@container w-full max-w-
4xl min-h-full flex flex-col justify-start items-center
sm:pt-4 pb-8"
>
<
MobileHeader
/>
<
MobileHeader
/>
<
div
className=
"relative flex-grow w-full min-h-full flex flex-col justify-start items-start border dark:border-zinc-700 bg-white dark:bg-zinc-700 shadow hover:shadow-xl transition-all p-4 pb-3 rounded-lg"
>
<
div
className=
"w-full px-4"
>
{
memo
.
parent
&&
(
<
div
className=
"relative flex-grow w-full min-h-full flex flex-col justify-start items-start border dark:border-zinc-700 bg-white dark:bg-zinc-700 shadow hover:shadow-xl transition-all p-4 pb-3 rounded-lg"
>
<
div
className=
"w-auto mb-2"
>
{
memo
.
parent
&&
(
<
Link
<
div
className=
"w-auto mb-2"
>
className=
"px-3 py-1 border rounded-full max-w-xs w-auto text-sm flex flex-row justify-start items-center flex-nowrap text-gray-600 dark:text-gray-400 dark:border-gray-500 hover:shadow hover:opacity-80"
<
Link
to=
{
`/m/${memo.parent.id}`
}
className=
"px-3 py-1 border rounded-full max-w-xs w-auto text-sm flex flex-row justify-start items-center flex-nowrap text-gray-600 dark:text-gray-400 dark:border-gray-500 hover:shadow hover:opacity-80"
>
to=
{
`/m/${memo.parent.id}`
}
<
Icon
.
ArrowUpLeftFromCircle
className=
"w-4 h-auto shrink-0 opacity-60"
/>
>
<
span
className=
"mx-1 opacity-60"
>
#
{
memo
.
parent
.
id
}
</
span
>
<
Icon
.
ArrowUpLeftFromCircle
className=
"w-4 h-auto shrink-0 opacity-60"
/>
<
span
className=
"truncate"
>
{
memo
.
parent
.
content
}
</
span
>
<
span
className=
"mx-1 opacity-60"
>
#
{
memo
.
parent
.
id
}
</
span
>
</
Link
>
<
span
className=
"truncate"
>
{
memo
.
parent
.
content
}
</
span
>
</
Link
>
</
div
>
)
}
<
div
className=
"w-full mb-2 flex flex-row justify-start items-center"
>
<
span
className=
"text-gray-400 select-none"
>
{
getDateTimeString
(
memo
.
displayTs
)
}
</
span
>
</
div
>
</
div
>
)
}
<
MemoContentV1
content=
{
memo
.
content
}
/>
<
div
className=
"w-full mb-2 flex flex-row justify-start items-center"
>
<
MemoResourceListView
resourceList=
{
memo
.
resourceList
}
/>
<
span
className=
"text-gray-400 select-none"
>
{
getDateTimeString
(
memo
.
displayTs
)
}
</
span
>
<
MemoRelationListView
memo=
{
memo
}
relationList=
{
referenceRelations
}
/>
</
div
>
<
div
className=
"w-full mt-4 flex flex-col sm:flex-row justify-start sm:justify-between sm:items-center gap-2"
>
<
MemoContentV1
content=
{
memo
.
content
}
/>
<
div
className=
"flex flex-row justify-start items-center"
>
<
MemoResourceListView
resourceList=
{
memo
.
resourceList
}
/>
<
Tooltip
title=
{
"Identifier"
}
placement=
"top"
>
<
MemoRelationListView
memo=
{
memo
}
relationList=
{
referenceRelations
}
/>
<
span
className=
"text-sm text-gray-500 dark:text-gray-400"
>
#
{
memo
.
id
}
</
span
>
<
div
className=
"w-full mt-4 flex flex-col sm:flex-row justify-start sm:justify-between sm:items-center gap-2"
>
<
div
className=
"flex flex-row justify-start items-center"
>
<
Tooltip
title=
{
"Identifier"
}
placement=
"top"
>
<
span
className=
"text-sm text-gray-500 dark:text-gray-400"
>
#
{
memo
.
id
}
</
span
>
</
Tooltip
>
<
Icon
.
Dot
className=
"w-4 h-auto text-gray-400 dark:text-zinc-400"
/>
<
Link
to=
{
`/u/${encodeURIComponent(memo.creatorUsername)}`
}
>
<
Tooltip
title=
{
"Creator"
}
placement=
"top"
>
<
span
className=
"flex flex-row justify-start items-center"
>
<
UserAvatar
className=
"!w-5 !h-5 mr-1"
avatarUrl=
{
creator
?.
avatarUrl
}
/>
<
span
className=
"text-sm text-gray-600 max-w-[8em] truncate dark:text-gray-400"
>
{
creator
?.
nickname
}
</
span
>
</
span
>
</
Tooltip
>
</
Tooltip
>
</
Link
>
<
Icon
.
Dot
className=
"w-4 h-auto text-gray-400 dark:text-zinc-400"
/>
{
allowEdit
&&
(
<
Link
to=
{
`/u/${encodeURIComponent(memo.creatorUsername)}`
}
>
<>
<
Tooltip
title=
{
"Creator"
}
placement=
"top"
>
<
Icon
.
Dot
className=
"w-4 h-auto text-gray-400 dark:text-zinc-400"
/>
<
span
className=
"flex flex-row justify-start items-center"
>
<
Select
<
UserAvatar
className=
"!w-5 !h-5 mr-1"
avatarUrl=
{
creator
?.
avatarUrl
}
/>
className=
"w-auto text-sm"
<
span
className=
"text-sm text-gray-600 max-w-[8em] truncate dark:text-gray-400"
>
{
creator
?.
nickname
}
</
span
>
variant=
"plain"
</
span
>
value=
{
memo
.
visibility
}
</
Tooltip
>
startDecorator=
{
<
VisibilityIcon
visibility=
{
memo
.
visibility
}
/>
}
</
Link
>
onChange=
{
(
_
,
visibility
)
=>
{
{
allowEdit
&&
(
if
(
visibility
)
{
<>
handleMemoVisibilityOptionChanged
(
visibility
);
<
Icon
.
Dot
className=
"w-4 h-auto text-gray-400 dark:text-zinc-400"
/>
}
<
Select
}
}
className=
"w-auto text-sm"
>
variant=
"plain"
{
VISIBILITY_SELECTOR_ITEMS
.
map
((
item
)
=>
(
value=
{
memo
.
visibility
}
<
Option
key=
{
item
}
value=
{
item
}
className=
"whitespace-nowrap"
disabled=
{
disableOption
(
item
)
}
>
startDecorator=
{
<
VisibilityIcon
visibility=
{
memo
.
visibility
}
/>
}
{
t
(
`memo.visibility.${item.toLowerCase() as Lowercase<typeof item>}`
)
}
onChange=
{
(
_
,
visibility
)
=>
{
</
Option
>
if
(
visibility
)
{
))
}
handleMemoVisibilityOptionChanged
(
visibility
);
</
Select
>
}
</>
}
}
)
}
>
</
div
>
{
VISIBILITY_SELECTOR_ITEMS
.
map
((
item
)
=>
(
<
div
className=
"flex flex-row sm:justify-end items-center"
>
<
Option
key=
{
item
}
value=
{
item
}
className=
"whitespace-nowrap"
disabled=
{
disableOption
(
item
)
}
>
{
allowEdit
&&
(
{
t
(
`memo.visibility.${item.toLowerCase() as Lowercase<typeof item>}`
)
}
<
Tooltip
title=
{
"Edit"
}
placement=
"top"
>
</
Option
>
<
IconButton
size=
"sm"
onClick=
{
handleEditMemoClick
}
>
))
}
<
Icon
.
Edit3
className=
"w-4 h-auto text-gray-600 dark:text-gray-400"
/>
</
Select
>
</>
)
}
</
div
>
<
div
className=
"flex flex-row sm:justify-end items-center"
>
{
allowEdit
&&
(
<
Tooltip
title=
{
"Edit"
}
placement=
"top"
>
<
IconButton
size=
"sm"
onClick=
{
handleEditMemoClick
}
>
<
Icon
.
Edit3
className=
"w-4 h-auto text-gray-600 dark:text-gray-400"
/>
</
IconButton
>
</
Tooltip
>
)
}
<
Tooltip
title=
{
"Copy link"
}
placement=
"top"
>
<
IconButton
size=
"sm"
onClick=
{
handleCopyLinkBtnClick
}
>
<
Icon
.
Link
className=
"w-4 h-auto text-gray-600 dark:text-gray-400"
/>
</
IconButton
>
</
IconButton
>
</
Tooltip
>
</
Tooltip
>
)
}
<
Tooltip
title=
{
"Share"
}
placement=
"top"
>
<
Tooltip
title=
{
"Copy link"
}
placement=
"top"
>
<
IconButton
size=
"sm"
onClick=
{
()
=>
showShareMemoDialog
(
memo
)
}
>
<
IconButton
size=
"sm"
onClick=
{
handleCopyLinkBtnClick
}
>
<
Icon
.
Share
className=
"w-4 h-auto text-gray-600 dark:text-gray-400"
/>
<
Icon
.
Link
className=
"w-4 h-auto text-gray-600 dark:text-gray-400"
/>
</
IconButton
>
</
IconButton
>
</
Tooltip
>
</
Tooltip
>
</
div
>
<
Tooltip
title=
{
"Share"
}
placement=
"top"
>
<
IconButton
size=
"sm"
onClick=
{
()
=>
showShareMemoDialog
(
memo
)
}
>
<
Icon
.
Share
className=
"w-4 h-auto text-gray-600 dark:text-gray-400"
/>
</
IconButton
>
</
Tooltip
>
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
<
div
className=
"pt-8 pb-16 w-full"
>
<
div
className=
"pt-8 pb-16 w-full"
>
<
div
className=
"relative mx-auto flex-grow w-full min-h-full flex flex-col justify-start items-start gap-y-1"
>
<
div
className=
"relative mx-auto flex-grow w-full min-h-full flex flex-col justify-start items-start gap-y-1"
>
{
comments
.
length
===
0
?
(
{
comments
.
length
===
0
?
(
<
div
className=
"w-full flex flex-col justify-center items-center py-6 mb-2"
>
<
div
className=
"w-full flex flex-col justify-center items-center py-6 mb-2"
>
<
Icon
.
MessageCircle
strokeWidth=
{
1
}
className=
"w-8 h-auto text-gray-400"
/>
<
Icon
.
MessageCircle
strokeWidth=
{
1
}
className=
"w-8 h-auto text-gray-400"
/>
<
p
className=
"text-gray-400 italic text-sm"
>
{
t
(
"memo.comment.no-comment"
)
}
</
p
>
<
p
className=
"text-gray-400 italic text-sm"
>
{
t
(
"memo.comment.no-comment"
)
}
</
p
>
</
div
>
)
:
(
<>
<
div
className=
"w-full flex flex-row justify-start items-center pl-3 mb-3"
>
<
Icon
.
MessageCircle
className=
"w-5 h-auto text-gray-400 mr-1"
/>
<
span
className=
"text-gray-400 text-sm"
>
{
t
(
"memo.comment.self"
)
}
</
span
>
<
span
className=
"text-gray-400 text-sm ml-0.5"
>
(
{
comments
.
length
}
)
</
span
>
</
div
>
</
div
>
{
comments
.
map
((
comment
)
=>
(
)
:
(
<
Memo
key=
{
comment
.
id
}
memo=
{
comment
}
showCreator
/>
<>
))
}
<
div
className=
"w-full flex flex-row justify-start items-center pl-3 mb-3"
>
</>
<
Icon
.
MessageCircle
className=
"w-5 h-auto text-gray-400 mr-1"
/>
)
}
<
span
className=
"text-gray-400 text-sm"
>
{
t
(
"memo.comment.self"
)
}
</
span
>
<
span
className=
"text-gray-400 text-sm ml-0.5"
>
(
{
comments
.
length
}
)
</
span
>
</
div
>
{
comments
.
map
((
comment
)
=>
(
<
Memo
key=
{
comment
.
id
}
memo=
{
comment
}
showCreator
/>
))
}
</>
)
}
{
/* Only show comment editor when user login */
}
{
/* Only show comment editor when user login */
}
{
currentUser
&&
(
{
currentUser
&&
(
<
MemoEditor
<
MemoEditor
key=
{
memo
.
id
}
key=
{
memo
.
id
}
cacheKey=
{
`comment-editor-${memo.id}`
}
cacheKey=
{
`comment-editor-${memo.id}`
}
relationList=
{
[{
memoId
:
UNKNOWN_ID
,
relatedMemoId
:
memo
.
id
,
type
:
"COMMENT"
}]
}
relationList=
{
[{
memoId
:
UNKNOWN_ID
,
relatedMemoId
:
memo
.
id
,
type
:
"COMMENT"
}]
}
onConfirm=
{
handleCommentCreated
}
onConfirm=
{
handleCommentCreated
}
/>
/>
)
}
)
}
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
</
section
>
</
section
>
...
...
web/src/pages/Resources.tsx
View file @
a3a1bbe8
...
@@ -66,106 +66,108 @@ const Resources = () => {
...
@@ -66,106 +66,108 @@ const Resources = () => {
};
};
return
(
return
(
<
section
className=
"@container w-full max-w-
3xl min-h-full flex flex-col justify-start items-center px-4 sm:px-2
sm:pt-4 pb-8"
>
<
section
className=
"@container w-full max-w-
4xl min-h-full flex flex-col justify-start items-center
sm:pt-4 pb-8"
>
<
MobileHeader
/>
<
MobileHeader
/>
<
div
className=
"w-full shadow flex flex-col justify-start items-start px-4 py-3 rounded-xl bg-white dark:bg-zinc-700 text-black dark:text-gray-300"
>
<
div
className=
"w-full px-4"
>
<
div
className=
"relative w-full flex flex-row justify-between items-center"
>
<
div
className=
"w-full shadow flex flex-col justify-start items-start px-4 py-3 rounded-xl bg-white dark:bg-zinc-700 text-black dark:text-gray-300"
>
<
p
className=
"px-2 py-1 flex flex-row justify-start items-center select-none opacity-80"
>
<
div
className=
"relative w-full flex flex-row justify-between items-center"
>
<
Icon
.
Paperclip
className=
"w-5 h-auto mr-1"
/>
{
t
(
"common.resources"
)
}
<
p
className=
"px-2 py-1 flex flex-row justify-start items-center select-none opacity-80"
>
</
p
>
<
Icon
.
Paperclip
className=
"w-5 h-auto mr-1"
/>
{
t
(
"common.resources"
)
}
<
div
>
</
p
>
<
Input
<
div
>
className=
"max-w-[8rem]"
<
Input
variant=
"plain"
className=
"max-w-[8rem]"
placeholder=
{
t
(
"common.search"
)
}
variant=
"plain"
startDecorator=
{
<
Icon
.
Search
className=
"w-4 h-auto"
/>
}
placeholder=
{
t
(
"common.search"
)
}
value=
{
state
.
searchQuery
}
startDecorator=
{
<
Icon
.
Search
className=
"w-4 h-auto"
/>
}
onChange=
{
(
e
)
=>
setState
({
...
state
,
searchQuery
:
e
.
target
.
value
})
}
value=
{
state
.
searchQuery
}
/>
onChange=
{
(
e
)
=>
setState
({
...
state
,
searchQuery
:
e
.
target
.
value
})
}
</
div
>
/>
</
div
>
<
div
className=
"w-full flex flex-col justify-start items-start mt-4 mb-6"
>
{
loadingState
.
isLoading
?
(
<
div
className=
"w-full h-32 flex flex-col justify-center items-center"
>
<
p
className=
"w-full text-center text-base my-6 mt-8"
>
{
t
(
"resource.fetching-data"
)
}
</
p
>
</
div
>
</
div
>
)
:
(
</
div
>
<>
<
div
className=
"w-full flex flex-col justify-start items-start mt-4 mb-6"
>
{
filteredResources
.
length
===
0
?
(
{
loadingState
.
isLoading
?
(
<
div
className=
"w-full mt-8 mb-8 flex flex-col justify-center items-center italic"
>
<
div
className=
"w-full h-32 flex flex-col justify-center items-center"
>
<
Empty
/>
<
p
className=
"w-full text-center text-base my-6 mt-8"
>
{
t
(
"resource.fetching-data"
)
}
</
p
>
<
p
className=
"mt-4 text-gray-600 dark:text-gray-400"
>
{
t
(
"message.no-data"
)
}
</
p
>
</
div
>
</
div
>
)
:
(
)
:
(
<>
<
div
className=
{
"w-full h-auto px-2 flex flex-col justify-start items-start gap-y-8"
}
>
{
filteredResources
.
length
===
0
?
(
{
Array
.
from
(
groupedResources
.
entries
()).
map
(([
timestamp
,
resources
])
=>
{
<
div
className=
"w-full mt-8 mb-8 flex flex-col justify-center items-center italic"
>
const
date
=
new
Date
(
timestamp
);
<
Empty
/>
return
(
<
p
className=
"mt-4 text-gray-600 dark:text-gray-400"
>
{
t
(
"message.no-data"
)
}
</
p
>
<
div
key=
{
timestamp
}
className=
"w-full flex flex-row justify-start items-start"
>
</
div
>
<
div
className=
"w-16 sm:w-24 pt-4 sm:pl-4 flex flex-col justify-start items-start"
>
)
:
(
<
span
className=
"text-sm opacity-60"
>
{
date
.
getFullYear
()
}
</
span
>
<
div
className=
{
"w-full h-auto px-2 flex flex-col justify-start items-start gap-y-8"
}
>
<
span
className=
"font-medium text-xl"
>
{
date
.
toLocaleString
(
i18n
.
language
,
{
month
:
"short"
})
}
</
span
>
{
Array
.
from
(
groupedResources
.
entries
()).
map
(([
timestamp
,
resources
])
=>
{
</
div
>
const
date
=
new
Date
(
timestamp
);
<
div
className=
"w-full max-w-[calc(100%-4rem)] sm:max-w-[calc(100%-6rem)] flex flex-row justify-start items-start gap-4 flex-wrap"
>
return
(
{
resources
.
map
((
resource
)
=>
{
<
div
key=
{
timestamp
}
className=
"w-full flex flex-row justify-start items-start"
>
return
(
<
div
className=
"w-16 sm:w-24 pt-4 sm:pl-4 flex flex-col justify-start items-start"
>
<
div
key=
{
resource
.
id
}
className=
"w-24 sm:w-32 h-auto flex flex-col justify-start items-start"
>
<
span
className=
"text-sm opacity-60"
>
{
date
.
getFullYear
()
}
</
span
>
<
div
className=
"w-24 h-24 flex justify-center items-center sm:w-32 sm:h-32 border dark:border-zinc-900 overflow-clip rounded-xl cursor-pointer hover:shadow hover:opacity-80"
>
<
span
className=
"font-medium text-xl"
>
{
date
.
toLocaleString
(
i18n
.
language
,
{
month
:
"short"
})
}
</
span
>
<
ResourceIcon
resource=
{
resource
}
strokeWidth=
{
0.5
}
/>
</
div
>
</
div
>
<
div
className=
"w-full max-w-[calc(100%-4rem)] sm:max-w-[calc(100%-6rem)] flex flex-row justify-start items-start gap-4 flex-wrap"
>
<
div
className=
"w-full max-w-full flex flex-row justify-between items-center mt-1 px-1"
>
{
resources
.
map
((
resource
)
=>
{
<
p
className=
"text-xs shrink text-gray-400 truncate"
>
{
resource
.
filename
}
</
p
>
return
(
<
Link
<
div
key=
{
resource
.
id
}
className=
"w-24 sm:w-32 h-auto flex flex-col justify-start items-start"
>
className=
"shrink-0 text-xs ml-1 text-gray-400 hover:underline hover:text-blue-600"
<
div
className=
"w-24 h-24 flex justify-center items-center sm:w-32 sm:h-32 border dark:border-zinc-900 overflow-clip rounded-xl cursor-pointer hover:shadow hover:opacity-80"
>
to=
{
`/m/${resource.memoId}`
}
<
ResourceIcon
resource=
{
resource
}
strokeWidth=
{
0.5
}
/>
target=
"_blank"
</
div
>
>
<
div
className=
"w-full max-w-full flex flex-row justify-between items-center mt-1 px-1"
>
#
{
resource
.
memoId
}
<
p
className=
"text-xs shrink text-gray-400 truncate"
>
{
resource
.
filename
}
</
p
>
</
Link
>
<
Link
className=
"shrink-0 text-xs ml-1 text-gray-400 hover:underline hover:text-blue-600"
to=
{
`/m/${resource.memoId}`
}
target=
"_blank"
>
#
{
resource
.
memoId
}
</
Link
>
</
div
>
</
div
>
</
div
>
</
div
>
);
);
})
}
})
}
</
div
>
</
div
>
</
div
>
</
div
>
);
);
})
}
})
}
{
unusedResources
.
length
>
0
&&
(
{
unusedResources
.
length
>
0
&&
(
<>
<>
<
Divider
/>
<
Divider
/>
<
div
className=
"w-full flex flex-row justify-start items-start"
>
<
div
className=
"w-full flex flex-row justify-start items-start"
>
<
div
className=
"w-16 sm:w-24 sm:pl-4 flex flex-col justify-start items-start"
></
div
>
<
div
className=
"w-16 sm:w-24 sm:pl-4 flex flex-col justify-start items-start"
></
div
>
<
div
className=
"w-full max-w-[calc(100%-4rem)] sm:max-w-[calc(100%-6rem)] flex flex-row justify-start items-start gap-4 flex-wrap"
>
<
div
className=
"w-full max-w-[calc(100%-4rem)] sm:max-w-[calc(100%-6rem)] flex flex-row justify-start items-start gap-4 flex-wrap"
>
<
div
className=
"w-full flex flex-row justify-start items-center gap-2"
>
<
div
className=
"w-full flex flex-row justify-start items-center gap-2"
>
<
span
className=
"text-gray-600 dark:text-gray-400"
>
Unused resources
</
span
>
<
span
className=
"text-gray-600 dark:text-gray-400"
>
Unused resources
</
span
>
<
span
className=
"text-gray-500 dark:text-gray-500 opacity-80"
>
(
{
unusedResources
.
length
}
)
</
span
>
<
span
className=
"text-gray-500 dark:text-gray-500 opacity-80"
>
(
{
unusedResources
.
length
}
)
</
span
>
<
Tooltip
title=
"Delete all"
placement=
"top"
>
<
Tooltip
title=
"Delete all"
placement=
"top"
>
<
IconButton
size=
"sm"
onClick=
{
handleDeleteUnusedResources
}
>
<
IconButton
size=
"sm"
onClick=
{
handleDeleteUnusedResources
}
>
<
Icon
.
Trash
className=
"w-4 h-auto opacity-60"
/>
<
Icon
.
Trash
className=
"w-4 h-auto opacity-60"
/>
</
IconButton
>
</
IconButton
>
</
Tooltip
>
</
Tooltip
>
</
div
>
</
div
>
{
unusedResources
.
map
((
resource
)
=>
{
{
unusedResources
.
map
((
resource
)
=>
{
return
(
return
(
<
div
key=
{
resource
.
id
}
className=
"w-24 sm:w-32 h-auto flex flex-col justify-start items-start"
>
<
div
key=
{
resource
.
id
}
className=
"w-24 sm:w-32 h-auto flex flex-col justify-start items-start"
>
<
div
className=
"w-24 h-24 flex justify-center items-center sm:w-32 sm:h-32 border dark:border-zinc-900 overflow-clip rounded-xl cursor-pointer hover:shadow hover:opacity-80"
>
<
div
className=
"w-24 h-24 flex justify-center items-center sm:w-32 sm:h-32 border dark:border-zinc-900 overflow-clip rounded-xl cursor-pointer hover:shadow hover:opacity-80"
>
<
ResourceIcon
resource=
{
resource
}
strokeWidth=
{
0.5
}
/>
<
ResourceIcon
resource=
{
resource
}
strokeWidth=
{
0.5
}
/>
</
div
>
</
div
>
<
div
className=
"w-full max-w-full flex flex-row justify-between items-center mt-1 px-1"
>
<
div
className=
"w-full max-w-full flex flex-row justify-between items-center mt-1 px-1"
>
<
p
className=
"text-xs shrink text-gray-400 truncate"
>
{
resource
.
filename
}
</
p
>
<
p
className=
"text-xs shrink text-gray-400 truncate"
>
{
resource
.
filename
}
</
p
>
</
div
>
</
div
>
</
div
>
</
div
>
);
);
})
}
})
}
</
div
>
</
div
>
</
div
>
</
div
>
</>
</>
)
}
)
}
</
div
>
</
div
>
)
}
)
}
</>
</>
)
}
)
}
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
</
section
>
</
section
>
...
...
web/src/pages/Setting.tsx
View file @
a3a1bbe8
...
@@ -42,82 +42,84 @@ const Setting = () => {
...
@@ -42,82 +42,84 @@ const Setting = () => {
};
};
return
(
return
(
<
section
className=
"@container w-full max-w-
3xl min-h-full flex flex-col justify-start items-start px-4 sm:px-2
sm:pt-4 pb-8"
>
<
section
className=
"@container w-full max-w-
4xl min-h-full flex flex-col justify-start items-start
sm:pt-4 pb-8"
>
<
MobileHeader
/>
<
MobileHeader
/>
<
div
className=
"setting-page-wrapper"
>
<
div
className=
"w-full px-4"
>
<
div
className=
"section-selector-container"
>
<
div
className=
"setting-page-wrapper"
>
<
span
className=
"section-title"
>
{
t
(
"common.basic"
)
}
</
span
>
<
div
className=
"section-selector-container"
>
<
div
className=
"section-items-container"
>
<
span
className=
"section-title"
>
{
t
(
"common.basic"
)
}
</
span
>
<
span
<
div
className=
"section-items-container"
>
onClick=
{
()
=>
handleSectionSelectorItemClick
(
"my-account"
)
}
<
span
className=
{
`section-item ${state.selectedSection === "my-account" ? "selected" : ""}`
}
onClick=
{
()
=>
handleSectionSelectorItemClick
(
"my-account"
)
}
>
className=
{
`section-item ${state.selectedSection === "my-account" ? "selected" : ""}`
}
<
Icon
.
User
className=
"w-4 h-auto mr-2 opacity-80"
/>
{
t
(
"setting.my-account"
)
}
>
</
span
>
<
Icon
.
User
className=
"w-4 h-auto mr-2 opacity-80"
/>
{
t
(
"setting.my-account"
)
}
<
span
</
span
>
onClick=
{
()
=>
handleSectionSelectorItemClick
(
"preference"
)
}
<
span
className=
{
`section-item ${state.selectedSection === "preference" ? "selected" : ""}`
}
onClick=
{
()
=>
handleSectionSelectorItemClick
(
"preference"
)
}
className=
{
`section-item ${state.selectedSection === "preference" ? "selected" : ""}`
}
>
<
Icon
.
Cog
className=
"w-4 h-auto mr-2 opacity-80"
/>
{
t
(
"setting.preference"
)
}
</
span
>
</
div
>
{
isHost
?
(
<>
<
span
className=
"section-title"
>
{
t
(
"common.admin"
)
}
</
span
>
<
div
className=
"section-items-container"
>
<
span
onClick=
{
()
=>
handleSectionSelectorItemClick
(
"member"
)
}
className=
{
`section-item ${state.selectedSection === "member" ? "selected" : ""}`
}
>
<
Icon
.
Users
className=
"w-4 h-auto mr-2 opacity-80"
/>
{
t
(
"setting.member"
)
}
</
span
>
<
span
onClick=
{
()
=>
handleSectionSelectorItemClick
(
"system"
)
}
className=
{
`section-item ${state.selectedSection === "system" ? "selected" : ""}`
}
>
<
Icon
.
Settings2
className=
"w-4 h-auto mr-2 opacity-80"
/>
{
t
(
"setting.system"
)
}
</
span
>
<
span
onClick=
{
()
=>
handleSectionSelectorItemClick
(
"storage"
)
}
className=
{
`section-item ${state.selectedSection === "storage" ? "selected" : ""}`
}
>
<
Icon
.
Database
className=
"w-4 h-auto mr-2 opacity-80"
/>
{
t
(
"setting.storage"
)
}
</
span
>
<
span
onClick=
{
()
=>
handleSectionSelectorItemClick
(
"sso"
)
}
className=
{
`section-item ${state.selectedSection === "sso" ? "selected" : ""}`
}
>
<
Icon
.
Key
className=
"w-4 h-auto mr-2 opacity-80"
/>
{
t
(
"setting.sso"
)
}
</
span
>
</
div
>
</>
)
:
null
}
</
div
>
<
div
className=
"section-content-container sm:max-w-[calc(100%-12rem)]"
>
<
Select
className=
"block mb-2 sm:!hidden"
value=
{
state
.
selectedSection
}
onChange=
{
(
_
,
value
)
=>
handleSectionSelectorItemClick
(
value
as
SettingSection
)
}
>
>
<
Icon
.
Cog
className=
"w-4 h-auto mr-2 opacity-80"
/>
{
t
(
"setting.preference"
)
}
{
getSettingSectionList
().
map
((
settingSection
)
=>
(
</
span
>
<
Option
key=
{
settingSection
}
value=
{
settingSection
}
>
{
t
(
`setting.${settingSection}`
)
}
</
Option
>
))
}
</
Select
>
{
state
.
selectedSection
===
"my-account"
?
(
<
MyAccountSection
/>
)
:
state
.
selectedSection
===
"preference"
?
(
<
PreferencesSection
/>
)
:
state
.
selectedSection
===
"member"
?
(
<
MemberSection
/>
)
:
state
.
selectedSection
===
"system"
?
(
<
SystemSection
/>
)
:
state
.
selectedSection
===
"storage"
?
(
<
StorageSection
/>
)
:
state
.
selectedSection
===
"sso"
?
(
<
SSOSection
/>
)
:
null
}
</
div
>
</
div
>
{
isHost
?
(
<>
<
span
className=
"section-title"
>
{
t
(
"common.admin"
)
}
</
span
>
<
div
className=
"section-items-container"
>
<
span
onClick=
{
()
=>
handleSectionSelectorItemClick
(
"member"
)
}
className=
{
`section-item ${state.selectedSection === "member" ? "selected" : ""}`
}
>
<
Icon
.
Users
className=
"w-4 h-auto mr-2 opacity-80"
/>
{
t
(
"setting.member"
)
}
</
span
>
<
span
onClick=
{
()
=>
handleSectionSelectorItemClick
(
"system"
)
}
className=
{
`section-item ${state.selectedSection === "system" ? "selected" : ""}`
}
>
<
Icon
.
Settings2
className=
"w-4 h-auto mr-2 opacity-80"
/>
{
t
(
"setting.system"
)
}
</
span
>
<
span
onClick=
{
()
=>
handleSectionSelectorItemClick
(
"storage"
)
}
className=
{
`section-item ${state.selectedSection === "storage" ? "selected" : ""}`
}
>
<
Icon
.
Database
className=
"w-4 h-auto mr-2 opacity-80"
/>
{
t
(
"setting.storage"
)
}
</
span
>
<
span
onClick=
{
()
=>
handleSectionSelectorItemClick
(
"sso"
)
}
className=
{
`section-item ${state.selectedSection === "sso" ? "selected" : ""}`
}
>
<
Icon
.
Key
className=
"w-4 h-auto mr-2 opacity-80"
/>
{
t
(
"setting.sso"
)
}
</
span
>
</
div
>
</>
)
:
null
}
</
div
>
<
div
className=
"section-content-container sm:max-w-[calc(100%-12rem)]"
>
<
Select
className=
"block mb-2 sm:!hidden"
value=
{
state
.
selectedSection
}
onChange=
{
(
_
,
value
)
=>
handleSectionSelectorItemClick
(
value
as
SettingSection
)
}
>
{
getSettingSectionList
().
map
((
settingSection
)
=>
(
<
Option
key=
{
settingSection
}
value=
{
settingSection
}
>
{
t
(
`setting.${settingSection}`
)
}
</
Option
>
))
}
</
Select
>
{
state
.
selectedSection
===
"my-account"
?
(
<
MyAccountSection
/>
)
:
state
.
selectedSection
===
"preference"
?
(
<
PreferencesSection
/>
)
:
state
.
selectedSection
===
"member"
?
(
<
MemberSection
/>
)
:
state
.
selectedSection
===
"system"
?
(
<
SystemSection
/>
)
:
state
.
selectedSection
===
"storage"
?
(
<
StorageSection
/>
)
:
state
.
selectedSection
===
"sso"
?
(
<
SSOSection
/>
)
:
null
}
</
div
>
</
div
>
</
div
>
</
div
>
</
section
>
</
section
>
...
...
web/src/pages/SignIn.tsx
View file @
a3a1bbe8
...
@@ -104,7 +104,7 @@ const SignIn = () => {
...
@@ -104,7 +104,7 @@ const SignIn = () => {
};
};
return
(
return
(
<
div
className=
"p
t-12 pb-8 w-80 max-w-full h-auto
mx-auto flex flex-col justify-start items-center"
>
<
div
className=
"p
y-8 w-80 max-w-full min-h-[100svh]
mx-auto flex flex-col justify-start items-center"
>
<
div
className=
"w-full py-4 grow flex flex-col justify-center items-center"
>
<
div
className=
"w-full py-4 grow flex flex-col justify-center items-center"
>
<
div
className=
"w-full flex flex-row justify-center items-center mb-6"
>
<
div
className=
"w-full flex flex-row justify-center items-center mb-6"
>
<
img
className=
"h-14 w-auto rounded-full shadow"
src=
{
systemStatus
.
customizedProfile
.
logoUrl
}
alt=
""
/>
<
img
className=
"h-14 w-auto rounded-full shadow"
src=
{
systemStatus
.
customizedProfile
.
logoUrl
}
alt=
""
/>
...
...
web/src/pages/SignUp.tsx
View file @
a3a1bbe8
...
@@ -70,7 +70,7 @@ const SignUp = () => {
...
@@ -70,7 +70,7 @@ const SignUp = () => {
};
};
return
(
return
(
<
div
className=
"p
t-12 pb-8 w-80 max-w-full h-auto
mx-auto flex flex-col justify-start items-center"
>
<
div
className=
"p
y-8 w-80 max-w-full min-h-[100svh]
mx-auto flex flex-col justify-start items-center"
>
<
div
className=
"w-full py-4 grow flex flex-col justify-center items-center"
>
<
div
className=
"w-full py-4 grow flex flex-col justify-center items-center"
>
<
div
className=
"w-full flex flex-row justify-center items-center mb-6"
>
<
div
className=
"w-full flex flex-row justify-center items-center mb-6"
>
<
img
className=
"h-14 w-auto rounded-full shadow"
src=
{
systemStatus
.
customizedProfile
.
logoUrl
}
alt=
""
/>
<
img
className=
"h-14 w-auto rounded-full shadow"
src=
{
systemStatus
.
customizedProfile
.
logoUrl
}
alt=
""
/>
...
...
web/src/pages/Timeline.tsx
View file @
a3a1bbe8
...
@@ -64,73 +64,75 @@ const Timeline = () => {
...
@@ -64,73 +64,75 @@ const Timeline = () => {
};
};
return
(
return
(
<
section
className=
"@container w-full max-w-
3xl min-h-full flex flex-col justify-start items-center px-4 sm:px-2
sm:pt-4 pb-8"
>
<
section
className=
"@container w-full max-w-
4xl min-h-full flex flex-col justify-start items-center
sm:pt-4 pb-8"
>
<
MobileHeader
/>
<
MobileHeader
/>
<
div
className=
"w-full shadow flex flex-col justify-start items-start px-4 py-3 rounded-xl bg-white dark:bg-zinc-700 text-black dark:text-gray-300"
>
<
div
className=
"w-full px-4"
>
<
div
className=
"relative w-full flex flex-row justify-start items-center"
>
<
div
className=
"w-full shadow flex flex-col justify-start items-start px-4 py-3 rounded-xl bg-white dark:bg-zinc-700 text-black dark:text-gray-300"
>
<
p
<
div
className=
"relative w-full flex flex-row justify-start items-center"
>
className=
"px-2 py-1 mr-2 flex flex-row justify-start items-center cursor-pointer select-none rounded opacity-80 hover:bg-gray-100 dark:hover:bg-zinc-700"
<
p
onClick=
{
()
=>
toggleShowDatePicker
()
}
className=
"px-2 py-1 mr-2 flex flex-row justify-start items-center cursor-pointer select-none rounded opacity-80 hover:bg-gray-100 dark:hover:bg-zinc-700"
>
onClick=
{
()
=>
toggleShowDatePicker
()
}
<
Icon
.
Calendar
className=
"w-5 h-auto mr-2"
/>
<
span
className=
"font-mono mt-0.5"
>
{
new
Date
(
selectedDateStamp
).
toLocaleDateString
()
}
</
span
>
</
p
>
{
selectedDateStamp
!==
currentDateStamp
&&
(
<
Button
variant=
"outlined"
startDecorator=
{
<
Icon
.
Undo2
className=
"w-5 h-auto"
/>
}
onClick=
{
()
=>
setSelectedDateStamp
(
currentDateStamp
)
}
>
>
{
"Back to today"
}
<
Icon
.
Calendar
className=
"w-5 h-auto mr-2"
/>
</
Button
>
<
span
className=
"font-mono mt-0.5"
>
{
new
Date
(
selectedDateStamp
).
toLocaleDateString
()
}
</
span
>
)
}
</
p
>
<
DatePicker
{
selectedDateStamp
!==
currentDateStamp
&&
(
className=
{
`absolute top-8 mt-2 z-20 mx-auto border bg-white shadow dark:bg-zinc-800 dark:border-zinc-800 rounded-lg mb-6 ${
<
Button
showDatePicker ? "" : "!hidden"
variant=
"outlined"
}`
}
startDecorator=
{
<
Icon
.
Undo2
className=
"w-5 h-auto"
/>
}
datestamp=
{
selectedDateStamp
}
onClick=
{
()
=>
setSelectedDateStamp
(
currentDateStamp
)
}
isFutureDateDisabled
handleDateStampChange=
{
handleDataPickerChange
}
handleClickAway=
{
()
=>
toggleShowDatePicker
(
false
)
}
/>
</
div
>
<
div
className=
"w-full h-auto flex flex-col justify-start items-start px-2 pb-4 bg-white dark:bg-zinc-700"
>
{
dailyMemos
.
length
===
0
&&
(
<
div
className=
"w-full mt-4 mb-8 flex flex-col justify-center items-center italic"
>
<
Empty
/>
<
p
className=
"mt-4 text-gray-600 dark:text-gray-400"
>
{
t
(
"message.no-data"
)
}
</
p
>
</
div
>
)
}
<
div
className=
"flex flex-col justify-start items-start w-full mt-2"
>
{
dailyMemos
.
map
((
memo
,
index
)
=>
(
<
div
key=
{
`${memo.id}-${memo.displayTs}`
}
className=
"relative w-full flex flex-col justify-start items-start pl-8 sm:pl-12 pt-2 pb-4"
>
>
<
div
className=
"w-full flex flex-row justify-start items-center mt-0.5 mb-1 text-sm font-mono text-gray-500 dark:text-gray-400"
>
{
"Back to today"
}
<
span
className=
"opacity-80"
>
{
getTimeString
(
memo
.
displayTs
)
}
</
span
>
</
Button
>
<
Icon
.
Dot
className=
"w-5 h-auto opacity-60"
/>
)
}
<
span
className=
"opacity-60"
>
#
{
memo
.
id
}
</
span
>
<
DatePicker
</
div
>
className=
{
`absolute top-8 mt-2 z-20 mx-auto border bg-white shadow dark:bg-zinc-800 dark:border-zinc-800 rounded-lg mb-6 ${
<
MemoContentV1
content=
{
memo
.
content
}
/>
showDatePicker ? "" : "!hidden"
<
MemoResourceListView
resourceList=
{
memo
.
resourceList
}
/>
}`
}
<
MemoRelationListView
memo=
{
memo
}
relationList=
{
memo
.
relationList
.
filter
((
relation
)
=>
relation
.
type
===
"REFERENCE"
)
}
/>
datestamp=
{
selectedDateStamp
}
<
div
className=
"absolute left-1 sm:left-2 top-3 h-full"
>
isFutureDateDisabled
{
index
!==
dailyMemos
.
length
-
1
&&
(
handleDateStampChange=
{
handleDataPickerChange
}
<
div
className=
"absolute top-2 left-[7px] h-full w-0.5 bg-gray-400 dark:bg-gray-500 block"
></
div
>
handleClickAway=
{
()
=>
toggleShowDatePicker
(
false
)
}
)
}
/>
<
div
className=
"border-4 rounded-full border-white relative dark:border-zinc-700"
>
</
div
>
<
Icon
.
Circle
className=
"w-2 h-auto bg-gray-400 text-gray-400 dark:bg-gray-500 dark:text-gray-500 rounded-full"
/>
<
div
className=
"w-full h-auto flex flex-col justify-start items-start px-2 pb-4 bg-white dark:bg-zinc-700"
>
{
dailyMemos
.
length
===
0
&&
(
<
div
className=
"w-full mt-4 mb-8 flex flex-col justify-center items-center italic"
>
<
Empty
/>
<
p
className=
"mt-4 text-gray-600 dark:text-gray-400"
>
{
t
(
"message.no-data"
)
}
</
p
>
</
div
>
)
}
<
div
className=
"flex flex-col justify-start items-start w-full mt-2"
>
{
dailyMemos
.
map
((
memo
,
index
)
=>
(
<
div
key=
{
`${memo.id}-${memo.displayTs}`
}
className=
"relative w-full flex flex-col justify-start items-start pl-8 sm:pl-12 pt-2 pb-4"
>
<
div
className=
"w-full flex flex-row justify-start items-center mt-0.5 mb-1 text-sm font-mono text-gray-500 dark:text-gray-400"
>
<
span
className=
"opacity-80"
>
{
getTimeString
(
memo
.
displayTs
)
}
</
span
>
<
Icon
.
Dot
className=
"w-5 h-auto opacity-60"
/>
<
span
className=
"opacity-60"
>
#
{
memo
.
id
}
</
span
>
</
div
>
<
MemoContentV1
content=
{
memo
.
content
}
/>
<
MemoResourceListView
resourceList=
{
memo
.
resourceList
}
/>
<
MemoRelationListView
memo=
{
memo
}
relationList=
{
memo
.
relationList
.
filter
((
relation
)
=>
relation
.
type
===
"REFERENCE"
)
}
/>
<
div
className=
"absolute left-1 sm:left-2 top-3 h-full"
>
{
index
!==
dailyMemos
.
length
-
1
&&
(
<
div
className=
"absolute top-2 left-[7px] h-full w-0.5 bg-gray-400 dark:bg-gray-500 block"
></
div
>
)
}
<
div
className=
"border-4 rounded-full border-white relative dark:border-zinc-700"
>
<
Icon
.
Circle
className=
"w-2 h-auto bg-gray-400 text-gray-400 dark:bg-gray-500 dark:text-gray-500 rounded-full"
/>
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
))
}
))
}
{
selectedDateStamp
===
currentDateStamp
&&
(
{
selectedDateStamp
===
currentDateStamp
&&
(
<
div
className=
"w-full pl-0 sm:pl-12 sm:mt-4"
>
<
div
className=
"w-full pl-0 sm:pl-12 sm:mt-4"
>
<
MemoEditor
cacheKey=
"timeline-editor"
/>
<
MemoEditor
cacheKey=
"timeline-editor"
/>
</
div
>
</
div
>
)
}
)
}
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
...
...
web/src/pages/UserProfile.tsx
View file @
a3a1bbe8
...
@@ -35,28 +35,20 @@ const UserProfile = () => {
...
@@ -35,28 +35,20 @@ const UserProfile = () => {
},
[
params
.
username
]);
},
[
params
.
username
]);
return
(
return
(
<
section
className=
"
relative top-0 w-full min-h-full overflow-x-hidden
"
>
<
section
className=
"
w-full max-w-4xl min-h-full flex flex-col justify-start items-center sm:pt-4 pb-8
"
>
<
MobileHeader
/>
<
MobileHeader
/>
<
div
className=
"
relative w-full min-h-full mx-auto
flex flex-col justify-start items-center"
>
<
div
className=
"
w-full px-4
flex flex-col justify-start items-center"
>
{
!
loadingState
.
isLoading
&&
{
!
loadingState
.
isLoading
&&
(
user
?
(
(
user
?
(
<>
<>
<
div
className=
"relative flex-grow max-w-2xl w-full min-h-full flex flex-col justify-start items-start px-4"
>
<
div
className=
"w-full flex flex-col justify-start items-center py-8"
>
<
div
className=
"w-full flex flex-row justify-start items-start"
>
<
UserAvatar
className=
"!w-20 !h-20 mb-2 drop-shadow"
avatarUrl=
{
user
?.
avatarUrl
}
/>
<
div
className=
"flex-grow shrink w-full"
>
<
p
className=
"text-3xl text-black opacity-80 dark:text-gray-200"
>
{
user
?.
nickname
}
</
p
>
<
div
className=
"w-full flex flex-col justify-start items-center py-8"
>
<
UserAvatar
className=
"!w-20 !h-20 mb-2 drop-shadow"
avatarUrl=
{
user
?.
avatarUrl
}
/>
<
p
className=
"text-3xl text-black opacity-80 dark:text-gray-200"
>
{
user
?.
nickname
}
</
p
>
</
div
>
<
MemoList
/>
</
div
>
</
div
>
</
div
>
</
div
>
<
MemoList
/>
</>
</>
)
:
(
)
:
(
<>
<
p
>
Not found
</
p
>
<
p
>
Not found
</
p
>
</>
))
}
))
}
</
div
>
</
div
>
</
section
>
</
section
>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment