Merge branch 'staging' into transformers
This commit is contained in:
commit
43ccb464b1
40 changed files with 666 additions and 289 deletions
|
|
@ -26,7 +26,7 @@ const AboutHead = ({ page }: Props) => {
|
|||
name="description"
|
||||
content={t(`page.descriptions.${currentPage}`)}
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
|
||||
<link rel="icon" type="image/x-icon" href="/images/favicon.png" />
|
||||
|
||||
{/* OpenGraph */}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,14 @@
|
|||
color: inherit;
|
||||
z-index: 10;
|
||||
|
||||
@include breakpoint(phone) {
|
||||
place-items: flex-end;
|
||||
overflow-y: hidden;
|
||||
|
||||
&.filter {
|
||||
}
|
||||
}
|
||||
|
||||
.dialogContent {
|
||||
$multiplier: 4;
|
||||
|
||||
|
|
@ -51,11 +59,11 @@
|
|||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
min-width: inherit;
|
||||
min-height: 90vh;
|
||||
min-height: inherit;
|
||||
transform: initial;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 5vh;
|
||||
top: $unit-10x;
|
||||
height: auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
|
@ -101,110 +109,6 @@
|
|||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
|
||||
&.Conflict {
|
||||
$weapon-diameter: 14rem;
|
||||
|
||||
.Content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $unit-4x;
|
||||
padding: $unit-4x $unit-4x $unit-2x $unit-4x;
|
||||
|
||||
& > p {
|
||||
font-size: $font-regular;
|
||||
line-height: 1.4;
|
||||
|
||||
strong {
|
||||
font-weight: $bold;
|
||||
}
|
||||
|
||||
&:lang(ja) {
|
||||
line-height: 1.4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.weapon,
|
||||
.character {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $unit;
|
||||
text-align: center;
|
||||
width: $weapon-diameter;
|
||||
font-weight: $medium;
|
||||
|
||||
img {
|
||||
border-radius: 1rem;
|
||||
width: $weapon-diameter;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
span {
|
||||
line-height: 1.3;
|
||||
}
|
||||
}
|
||||
|
||||
.Diagram {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto 1fr;
|
||||
align-items: flex-start;
|
||||
|
||||
&.CharacterDiagram {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
ul {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $unit-2x;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.arrow {
|
||||
align-items: center;
|
||||
color: $grey-55;
|
||||
display: flex;
|
||||
font-size: 4rem;
|
||||
text-align: center;
|
||||
height: $weapon-diameter;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
footer {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: $unit;
|
||||
|
||||
.Button {
|
||||
font-size: $font-regular;
|
||||
padding: ($unit * 1.5) ($unit * 2);
|
||||
width: 100%;
|
||||
|
||||
&.btn-disabled {
|
||||
background: $grey-90;
|
||||
color: $grey-70;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
&:not(.btn-disabled) {
|
||||
background: $grey-90;
|
||||
color: $grey-50;
|
||||
|
||||
&:hover {
|
||||
background: $grey-80;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes openModalDesktop {
|
||||
|
|
@ -221,11 +125,20 @@
|
|||
|
||||
@keyframes slideUp {
|
||||
0% {
|
||||
transform: translate(0%, 100%);
|
||||
transform: translateY(400px);
|
||||
animation-timing-function: ease-out;
|
||||
}
|
||||
60% {
|
||||
transform: translateY(-30px);
|
||||
animation-timing-function: ease-in;
|
||||
}
|
||||
80% {
|
||||
transform: translateY(10px);
|
||||
animation-timing-function: ease-out;
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translate(0, 0%);
|
||||
transform: translateY(0px);
|
||||
animation-timing-function: ease-in;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ interface Props
|
|||
React.DialogHTMLAttributes<HTMLDivElement>,
|
||||
HTMLDivElement
|
||||
> {
|
||||
wrapperClassName?: string
|
||||
headerref?: React.RefObject<HTMLDivElement>
|
||||
footerref?: React.RefObject<HTMLDivElement>
|
||||
scrollable?: boolean
|
||||
|
|
@ -127,7 +128,16 @@ const DialogContent = React.forwardRef<HTMLDivElement, Props>(function Dialog(
|
|||
|
||||
return (
|
||||
<DialogPrimitive.Portal>
|
||||
<dialog className={styles.dialog}>
|
||||
<dialog
|
||||
className={classNames(
|
||||
{
|
||||
[styles.dialog]: true,
|
||||
},
|
||||
props.wrapperClassName
|
||||
?.split(' ')
|
||||
.map((className) => styles[className])
|
||||
)}
|
||||
>
|
||||
<DialogPrimitive.Content
|
||||
{...props}
|
||||
className={classes}
|
||||
|
|
|
|||
|
|
@ -16,4 +16,11 @@
|
|||
display: flex;
|
||||
gap: $unit;
|
||||
}
|
||||
|
||||
@include breakpoint(phone) {
|
||||
position: fixed;
|
||||
bottom: $unit-14x;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,14 @@
|
|||
outline: none;
|
||||
}
|
||||
|
||||
p.empty:first-child::before {
|
||||
color: var(--text-tertiary);
|
||||
content: attr(data-placeholder);
|
||||
float: left;
|
||||
height: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&.bound {
|
||||
background-color: var(--input-bound-bg);
|
||||
|
||||
|
|
@ -61,6 +69,45 @@
|
|||
font-style: italic;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding: 0 $unit-2x;
|
||||
list-style-type: disc;
|
||||
}
|
||||
|
||||
ol {
|
||||
padding: 0 $unit-2x;
|
||||
list-style-type: decimal;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: $font-xlarge;
|
||||
font-weight: $medium;
|
||||
margin: $unit-2x 0;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: $font-large;
|
||||
font-weight: $medium;
|
||||
margin: $unit-2x 0;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: $font-regular;
|
||||
font-weight: $medium;
|
||||
margin: $unit-2x 0;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
mark {
|
||||
border-radius: $item-corner-small;
|
||||
background: var(--highlight-bg);
|
||||
color: var(--highlight-text);
|
||||
font-weight: $normal;
|
||||
padding: 1px $unit-fourth;
|
||||
}
|
||||
|
||||
iframe {
|
||||
background: var(--input-bound-bg);
|
||||
border-radius: $card-corner;
|
||||
|
|
@ -78,15 +125,18 @@
|
|||
.mention {
|
||||
border-radius: $item-corner-small;
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25),
|
||||
0 1px 0px rgba(0, 0, 0, 0.25);
|
||||
background: var(--card-bg);
|
||||
0 1px 0px var(--null-shadow);
|
||||
background: var(--null-bg);
|
||||
color: var(--text-primary);
|
||||
font-weight: $medium;
|
||||
font-size: 15px;
|
||||
padding: 1px $unit-half;
|
||||
transition: all 0.1s ease-out;
|
||||
|
||||
&:hover {
|
||||
background: var(--card-bg-hover);
|
||||
background: var(--null-bg-hover);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25),
|
||||
0 1px 0px var(--null-shadow-hover);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
|
@ -98,6 +148,7 @@
|
|||
color: var(--fire-text);
|
||||
|
||||
&:hover {
|
||||
background: var(--fire-bg-hover);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25),
|
||||
0 1px 0px var(--fire-shadow-hover);
|
||||
color: var(--fire-text-hover);
|
||||
|
|
@ -111,6 +162,7 @@
|
|||
color: var(--water-text);
|
||||
|
||||
&:hover {
|
||||
background: var(--water-bg-hover);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25),
|
||||
0 1px 0px var(--water-shadow-hover);
|
||||
color: var(--water-text-hover);
|
||||
|
|
@ -124,6 +176,7 @@
|
|||
color: var(--earth-text);
|
||||
|
||||
&:hover {
|
||||
background: var(--earth-bg-hover);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25),
|
||||
0 1px 0px var(--earth-shadow-hover);
|
||||
color: var(--earth-text-hover);
|
||||
|
|
@ -150,6 +203,7 @@
|
|||
color: var(--dark-text);
|
||||
|
||||
&:hover {
|
||||
background: var(--dark-bg-hover);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25),
|
||||
0 1px 0px var(--dark-shadow-hover);
|
||||
color: var(--dark-text-hover);
|
||||
|
|
@ -163,6 +217,7 @@
|
|||
color: var(--light-text);
|
||||
|
||||
&:hover {
|
||||
background: var(--light-bg-hover);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25),
|
||||
0 1px 0px var(--light-shadow-hover);
|
||||
color: var(--light-text-hover);
|
||||
|
|
@ -180,26 +235,6 @@
|
|||
padding: $unit;
|
||||
z-index: 10;
|
||||
|
||||
button {
|
||||
background: var(--toolbar-item-bg);
|
||||
border-radius: $bubble-menu-item-corner;
|
||||
color: var(--toolbar-item-text);
|
||||
font-weight: $medium;
|
||||
font-size: $font-small;
|
||||
padding: $unit-half $unit;
|
||||
|
||||
&:hover {
|
||||
background: var(--toolbar-item-bg-hover);
|
||||
color: var(--toolbar-item-text-hover);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: var(--toolbar-item-bg-active);
|
||||
color: var(--toolbar-item-text-active);
|
||||
}
|
||||
}
|
||||
|
||||
.divider {
|
||||
background: var(--toolbar-divider-bg);
|
||||
border-radius: $full-corner;
|
||||
|
|
|
|||
|
|
@ -1,15 +1,32 @@
|
|||
import { ComponentProps, useCallback } from 'react'
|
||||
import { useRouter } from 'next/router'
|
||||
import { ComponentProps, useCallback, useEffect } from 'react'
|
||||
import { useEditor, EditorContent } from '@tiptap/react'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
|
||||
import StarterKit from '@tiptap/starter-kit'
|
||||
import Link from '@tiptap/extension-link'
|
||||
import Highlight from '@tiptap/extension-highlight'
|
||||
import Placeholder from '@tiptap/extension-placeholder'
|
||||
import Typography from '@tiptap/extension-typography'
|
||||
import Youtube from '@tiptap/extension-youtube'
|
||||
import CustomMention from '~extensions/CustomMention'
|
||||
import classNames from 'classnames'
|
||||
|
||||
import { mentionSuggestionOptions } from '~utils/mentionSuggestions'
|
||||
import type { JSONContent } from '@tiptap/core'
|
||||
import ToolbarButton from '~components/common/ToolbarButton'
|
||||
|
||||
import BoldIcon from 'remixicon-react/BoldIcon'
|
||||
import ItalicIcon from 'remixicon-react/ItalicIcon'
|
||||
import StrikethroughIcon from 'remixicon-react/StrikethroughIcon'
|
||||
import UnorderedListIcon from 'remixicon-react/ListUnorderedIcon'
|
||||
import OrderedListIcon from '~public/icons/remix/list-ordered-2.svg'
|
||||
import PaintbrushIcon from 'remixicon-react/PaintBrushLineIcon'
|
||||
import H1Icon from 'remixicon-react/H1Icon'
|
||||
import H2Icon from 'remixicon-react/H2Icon'
|
||||
import H3Icon from 'remixicon-react/H3Icon'
|
||||
import LinkIcon from 'remixicon-react/LinkIcon'
|
||||
import YoutubeIcon from 'remixicon-react/YoutubeLineIcon'
|
||||
import styles from './index.module.scss'
|
||||
|
||||
interface Props extends ComponentProps<'div'> {
|
||||
|
|
@ -27,9 +44,68 @@ const Editor = ({
|
|||
onUpdate,
|
||||
...props
|
||||
}: Props) => {
|
||||
// Hooks: Router
|
||||
const router = useRouter()
|
||||
const locale = router.locale || 'en'
|
||||
|
||||
const { t } = useTranslation('common')
|
||||
|
||||
useEffect(() => {
|
||||
editor?.commands.setContent(formatContent(content))
|
||||
}, [content])
|
||||
|
||||
// Setup: Editor
|
||||
const editor = useEditor({
|
||||
content: formatContent(content),
|
||||
editable: editable,
|
||||
editorProps: {
|
||||
attributes: {
|
||||
class: classNames(
|
||||
{
|
||||
[styles.editor]: true,
|
||||
[styles.bound]: bound,
|
||||
},
|
||||
className?.split(' ').map((c) => styles[c])
|
||||
),
|
||||
},
|
||||
},
|
||||
extensions: [
|
||||
StarterKit.configure({
|
||||
heading: {
|
||||
levels: [1, 2, 3],
|
||||
},
|
||||
}),
|
||||
Link,
|
||||
Highlight,
|
||||
Placeholder.configure({
|
||||
emptyEditorClass: styles.empty,
|
||||
placeholder: t('modals.edit_team.placeholders.description'),
|
||||
}),
|
||||
Typography,
|
||||
CustomMention.configure({
|
||||
renderLabel({ options, node }) {
|
||||
return `${node.attrs.id.name[locale] ?? node.attrs.id.granblue_en}`
|
||||
},
|
||||
suggestion: mentionSuggestionOptions,
|
||||
HTMLAttributes: {
|
||||
class: classNames({
|
||||
[styles.mention]: true,
|
||||
}),
|
||||
},
|
||||
}),
|
||||
Youtube.configure({
|
||||
inline: false,
|
||||
modestBranding: true,
|
||||
interfaceLanguage: locale,
|
||||
}),
|
||||
],
|
||||
onUpdate: ({ editor }) => {
|
||||
const json = editor.getJSON()
|
||||
if (onUpdate) onUpdate(json)
|
||||
},
|
||||
})
|
||||
|
||||
// Methods: Convenience
|
||||
function isJSON(content?: string) {
|
||||
if (!content) return false
|
||||
|
||||
|
|
@ -59,46 +135,7 @@ const Editor = ({
|
|||
}
|
||||
}
|
||||
|
||||
const editor = useEditor({
|
||||
content: formatContent(content),
|
||||
editable: editable,
|
||||
editorProps: {
|
||||
attributes: {
|
||||
class: classNames(
|
||||
{
|
||||
[styles.editor]: true,
|
||||
[styles.bound]: bound,
|
||||
},
|
||||
className?.split(' ').map((c) => styles[c])
|
||||
),
|
||||
},
|
||||
},
|
||||
extensions: [
|
||||
StarterKit,
|
||||
Link,
|
||||
CustomMention.configure({
|
||||
renderLabel({ options, node }) {
|
||||
return `${node.attrs.id.name[locale] ?? node.attrs.id.granblue_en}`
|
||||
},
|
||||
suggestion: mentionSuggestionOptions,
|
||||
HTMLAttributes: {
|
||||
class: classNames({
|
||||
[styles.mention]: true,
|
||||
}),
|
||||
},
|
||||
}),
|
||||
Youtube.configure({
|
||||
inline: false,
|
||||
modestBranding: true,
|
||||
interfaceLanguage: locale,
|
||||
}),
|
||||
],
|
||||
onUpdate: ({ editor }) => {
|
||||
const json = editor.getJSON()
|
||||
if (onUpdate) onUpdate(json)
|
||||
},
|
||||
})
|
||||
|
||||
// Methods: Actions
|
||||
const setLink = useCallback(() => {
|
||||
const previousUrl = editor?.getAttributes('link').href
|
||||
const url = window.prompt('URL', previousUrl)
|
||||
|
|
@ -131,6 +168,7 @@ const Editor = ({
|
|||
}
|
||||
}
|
||||
|
||||
// Methods: Rendering
|
||||
if (!editor) {
|
||||
return null
|
||||
}
|
||||
|
|
@ -139,32 +177,84 @@ const Editor = ({
|
|||
<section className={styles.wrapper}>
|
||||
{editor && editable === true && (
|
||||
<nav className={styles.toolbar}>
|
||||
<button
|
||||
<ToolbarButton
|
||||
editor={editor}
|
||||
action="bold"
|
||||
icon={<BoldIcon />}
|
||||
onClick={() => editor.chain().focus().toggleBold().run()}
|
||||
className={editor.isActive('bold') ? styles.active : ''}
|
||||
>
|
||||
bold
|
||||
</button>
|
||||
<button
|
||||
/>
|
||||
<ToolbarButton
|
||||
editor={editor}
|
||||
action="italic"
|
||||
icon={<ItalicIcon />}
|
||||
onClick={() => editor.chain().focus().toggleItalic().run()}
|
||||
className={editor.isActive('italic') ? styles.active : ''}
|
||||
>
|
||||
italic
|
||||
</button>
|
||||
<button
|
||||
/>
|
||||
<ToolbarButton
|
||||
editor={editor}
|
||||
action="strike"
|
||||
icon={<StrikethroughIcon />}
|
||||
onClick={() => editor.chain().focus().toggleStrike().run()}
|
||||
className={editor.isActive('strike') ? styles.active : ''}
|
||||
>
|
||||
strike
|
||||
</button>
|
||||
/>
|
||||
<ToolbarButton
|
||||
editor={editor}
|
||||
action="highlight"
|
||||
icon={<PaintbrushIcon />}
|
||||
onClick={() => editor.chain().focus().toggleHighlight().run()}
|
||||
/>
|
||||
<div className={styles.divider} />
|
||||
<button
|
||||
<ToolbarButton
|
||||
editor={editor}
|
||||
action="heading"
|
||||
level={1}
|
||||
icon={<H1Icon />}
|
||||
onClick={() =>
|
||||
editor.chain().focus().toggleHeading({ level: 1 }).run()
|
||||
}
|
||||
/>
|
||||
<ToolbarButton
|
||||
editor={editor}
|
||||
action="heading"
|
||||
level={2}
|
||||
icon={<H2Icon />}
|
||||
onClick={() =>
|
||||
editor.chain().focus().toggleHeading({ level: 2 }).run()
|
||||
}
|
||||
/>
|
||||
<ToolbarButton
|
||||
editor={editor}
|
||||
action="heading"
|
||||
level={3}
|
||||
icon={<H3Icon />}
|
||||
onClick={() =>
|
||||
editor.chain().focus().toggleHeading({ level: 3 }).run()
|
||||
}
|
||||
/>
|
||||
<div className={styles.divider} />
|
||||
<ToolbarButton
|
||||
editor={editor}
|
||||
action="bulletList"
|
||||
icon={<UnorderedListIcon />}
|
||||
onClick={() => editor.chain().focus().toggleBulletList().run()}
|
||||
/>
|
||||
<ToolbarButton
|
||||
editor={editor}
|
||||
action="orderedList"
|
||||
icon={<OrderedListIcon />}
|
||||
onClick={() => editor.chain().focus().toggleOrderedList().run()}
|
||||
/>
|
||||
<div className={styles.divider} />
|
||||
<ToolbarButton
|
||||
editor={editor}
|
||||
action="link"
|
||||
icon={<LinkIcon />}
|
||||
onClick={setLink}
|
||||
className={editor.isActive('link') ? styles.active : ''}
|
||||
>
|
||||
+ link
|
||||
</button>
|
||||
<button onClick={addYoutubeVideo}>+ youtube</button>
|
||||
/>
|
||||
<ToolbarButton
|
||||
editor={editor}
|
||||
action="youtube"
|
||||
icon={<YoutubeIcon />}
|
||||
onClick={addYoutubeVideo}
|
||||
/>
|
||||
</nav>
|
||||
)}
|
||||
<EditorContent editor={editor} />
|
||||
|
|
|
|||
|
|
@ -21,12 +21,6 @@
|
|||
&.flush {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.Arrow {
|
||||
fill: var(--dialog-bg);
|
||||
filter: drop-shadow(0px 1px 1px rgb(0 0 0 / 0.18));
|
||||
margin-top: -1px;
|
||||
}
|
||||
}
|
||||
|
||||
.trigger {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
.arrow {
|
||||
fill: var(--dialog-bg);
|
||||
filter: drop-shadow(0px 1px 1px rgb(0 0 0 / 0.18));
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
|
@ -63,6 +63,10 @@
|
|||
|
||||
&.table {
|
||||
min-width: $unit * 30;
|
||||
|
||||
@include breakpoint(phone) {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&.hidden {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,10 @@
|
|||
border-radius: 9999px;
|
||||
height: 3px;
|
||||
}
|
||||
|
||||
&.table {
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.range {
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ const SliderTableField = (props: Props) => {
|
|||
max={props.max}
|
||||
step={props.step}
|
||||
value={[props.value ? props.value : 0]}
|
||||
className="table"
|
||||
onValueChange={handleValueChange}
|
||||
onValueCommit={handleValueCommit}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -36,6 +36,14 @@
|
|||
}
|
||||
}
|
||||
|
||||
&.switch {
|
||||
@include breakpoint(phone) {
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
|
||||
.left {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
|
|
|
|||
36
components/common/ToolbarButton/index.module.scss
Normal file
36
components/common/ToolbarButton/index.module.scss
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
.button {
|
||||
background: var(--toolbar-item-bg);
|
||||
border-radius: $bubble-menu-item-corner;
|
||||
color: var(--toolbar-item-text);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-weight: $medium;
|
||||
font-size: $font-small;
|
||||
padding: $unit-half;
|
||||
|
||||
&:hover {
|
||||
background: var(--toolbar-item-bg-hover);
|
||||
color: var(--toolbar-item-text-hover);
|
||||
cursor: pointer;
|
||||
|
||||
svg {
|
||||
fill: var(--text-primary);
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: var(--toolbar-item-bg-active);
|
||||
color: var(--toolbar-item-text-active);
|
||||
|
||||
svg {
|
||||
fill: white;
|
||||
}
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: var(--text-tertiary);
|
||||
height: $unit-2x;
|
||||
width: $unit-2x;
|
||||
}
|
||||
}
|
||||
41
components/common/ToolbarButton/index.tsx
Normal file
41
components/common/ToolbarButton/index.tsx
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
import { useTranslation } from 'next-i18next'
|
||||
import classNames from 'classnames'
|
||||
|
||||
import { Editor } from '@tiptap/react'
|
||||
import Tooltip from '~components/common/Tooltip'
|
||||
|
||||
import styles from './index.module.scss'
|
||||
|
||||
interface Props {
|
||||
editor: Editor
|
||||
action: string
|
||||
level?: number
|
||||
icon: React.ReactNode
|
||||
onClick: () => void
|
||||
}
|
||||
|
||||
const ToolbarIcon = ({ editor, action, level, icon, onClick }: Props) => {
|
||||
const { t } = useTranslation('common')
|
||||
const classes = classNames({
|
||||
[styles.button]: true,
|
||||
[styles.active]: level
|
||||
? editor.isActive(action, { level: level })
|
||||
: editor.isActive(action),
|
||||
})
|
||||
|
||||
return (
|
||||
<Tooltip
|
||||
content={
|
||||
level
|
||||
? t(`toolbar.tooltips.${action}`, { level: level })
|
||||
: t(`toolbar.tooltips.${action}`)
|
||||
}
|
||||
>
|
||||
<button onClick={onClick} className={classes}>
|
||||
{icon}
|
||||
</button>
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
|
||||
export default ToolbarIcon
|
||||
|
|
@ -39,5 +39,6 @@
|
|||
|
||||
@include breakpoint(phone) {
|
||||
gap: $unit-4x;
|
||||
margin-bottom: $unit * 24;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -402,7 +402,8 @@ const FilterModal = (props: Props) => {
|
|||
<Dialog open={open} onOpenChange={openChange}>
|
||||
<DialogTrigger asChild>{props.children}</DialogTrigger>
|
||||
<DialogContent
|
||||
className="Filter"
|
||||
className="filter"
|
||||
wrapperClassName="filter"
|
||||
headerref={headerRef}
|
||||
footerref={footerRef}
|
||||
onEscapeKeyDown={onEscapeKeyDown}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ const NewHead = () => {
|
|||
{/* HTML */}
|
||||
<title>{t('page.titles.new')}</title>
|
||||
<meta name="description" content={t('page.descriptions.new')} />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
|
||||
<link rel="icon" type="image/x-icon" href="/images/favicon.png" />
|
||||
|
||||
{/* OpenGraph */}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ const ProfileHead = ({ user }: Props) => {
|
|||
username: user.username,
|
||||
})}
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
|
||||
<link rel="icon" type="image/x-icon" href="/images/favicon.png" />
|
||||
|
||||
{/* OpenGraph */}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ const SavedHead = () => {
|
|||
return (
|
||||
<Head>
|
||||
<title>{t('page.titles.saved')}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
|
||||
<link rel="icon" type="image/x-icon" href="/images/favicon.png" />
|
||||
|
||||
<meta property="og:title" content={t('page.titles.saved')} />
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ const TeamsHead = () => {
|
|||
{/* HTML */}
|
||||
<title>{t('page.titles.discover')}</title>
|
||||
<meta name="description" content={t('page.descriptions.discover')} />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="icon" type="image/x-icon" href="/images/favicon.png" />
|
||||
|
||||
{/* OpenGraph */}
|
||||
|
|
|
|||
|
|
@ -297,7 +297,8 @@ const EditPartyModal = ({
|
|||
// Methods: Modification checking
|
||||
function hasBeenModified() {
|
||||
const nameChanged =
|
||||
name !== party.name && !(name === '' && party.name === undefined)
|
||||
name !== party.name &&
|
||||
!(name === '' && (party.name === undefined || party.name === null))
|
||||
const descriptionChanged =
|
||||
description !== party.description &&
|
||||
!(description === '' && party.description === undefined)
|
||||
|
|
@ -433,7 +434,7 @@ const EditPartyModal = ({
|
|||
const nameField = (
|
||||
<Input
|
||||
name="name"
|
||||
placeholder="Name your team"
|
||||
placeholder={t('modals.edit_team.placeholders.name')}
|
||||
autoFocus={true}
|
||||
value={name}
|
||||
maxLength={50}
|
||||
|
|
@ -466,22 +467,12 @@ const EditPartyModal = ({
|
|||
}
|
||||
}
|
||||
|
||||
const descriptionField = (
|
||||
<Textarea
|
||||
className="editParty"
|
||||
bound={true}
|
||||
placeholder={t('modals.edit_team.placeholders.description')}
|
||||
value={description}
|
||||
onInput={handleTextAreaChanged}
|
||||
ref={descriptionInput}
|
||||
/>
|
||||
)
|
||||
|
||||
const editorField = (
|
||||
<Editor
|
||||
bound={true}
|
||||
content={description}
|
||||
content={props.party?.description}
|
||||
editable={true}
|
||||
key={props.party?.shortcode}
|
||||
onUpdate={handleEditorUpdate}
|
||||
/>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ const Party = (props: Props) => {
|
|||
|
||||
// Set up states
|
||||
const { party } = useSnapshot(appState)
|
||||
const [updatedParty, setUpdatedParty] = useState<Party | undefined>()
|
||||
const [editable, setEditable] = useState(false)
|
||||
const [refresh, setRefresh] = useState(false)
|
||||
const [errorMessage, setErrorMessage] = useState('')
|
||||
|
|
@ -57,7 +58,10 @@ const Party = (props: Props) => {
|
|||
useEffect(() => {
|
||||
const resetState = clonedeep(initialAppState)
|
||||
appState.grid = resetState.grid
|
||||
if (props.team) storeParty(props.team)
|
||||
if (props.team) {
|
||||
storeParty(props.team)
|
||||
setUpdatedParty(props.team)
|
||||
}
|
||||
}, [])
|
||||
|
||||
// Subscribe to app state to listen for account changes and
|
||||
|
|
@ -108,9 +112,11 @@ const Party = (props: Props) => {
|
|||
let payload = {}
|
||||
if (details) payload = formatDetailsObject(details)
|
||||
|
||||
return await api.endpoints.parties
|
||||
.create(payload)
|
||||
.then((response) => storeParty(response.data.party))
|
||||
return await api.endpoints.parties.create(payload).then((response) => {
|
||||
storeParty(response.data.party)
|
||||
setUpdatedParty(response.data.party)
|
||||
return Promise.resolve(response.data.party)
|
||||
})
|
||||
}
|
||||
|
||||
async function updateParty(details: DetailsObject) {
|
||||
|
|
@ -119,7 +125,11 @@ const Party = (props: Props) => {
|
|||
if (props.team && props.team.id) {
|
||||
return await api.endpoints.parties
|
||||
.update(props.team.id, payload)
|
||||
.then((response) => storeParty(response.data.party))
|
||||
.then((response) => {
|
||||
storeParty(response.data.party)
|
||||
setUpdatedParty(response.data.party)
|
||||
return Promise.resolve(response.data.party)
|
||||
})
|
||||
.catch((error) => {
|
||||
const data = error.response.data
|
||||
if (data.errors && Object.keys(data.errors).includes('guidebooks')) {
|
||||
|
|
@ -438,7 +448,7 @@ const Party = (props: Props) => {
|
|||
{errorAlert()}
|
||||
|
||||
<PartyHeader
|
||||
party={props.team}
|
||||
party={updatedParty}
|
||||
new={props.new || false}
|
||||
editable={props.new ? true : party.editable}
|
||||
raidGroups={props.raidGroups}
|
||||
|
|
@ -452,7 +462,7 @@ const Party = (props: Props) => {
|
|||
<section id="Party">{currentGrid()}</section>
|
||||
|
||||
<PartyFooter
|
||||
party={props.team}
|
||||
party={updatedParty}
|
||||
new={props.new || false}
|
||||
editable={party.editable}
|
||||
raidGroups={props.raidGroups}
|
||||
|
|
|
|||
|
|
@ -208,10 +208,13 @@ const PartyFooter = (props: Props) => {
|
|||
|
||||
const descriptionSection = (
|
||||
<>
|
||||
{partySnapshot &&
|
||||
partySnapshot.description &&
|
||||
partySnapshot.description.length > 0 && (
|
||||
<Editor content={appState.party.description} />
|
||||
{props.party &&
|
||||
props.party.description &&
|
||||
props.party.description.length > 0 && (
|
||||
<Editor
|
||||
content={props.party.description}
|
||||
key={props.party?.shortcode}
|
||||
/>
|
||||
)}
|
||||
{(!partySnapshot || !partySnapshot.description) && (
|
||||
<section className={styles.noDescription}>
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ const PartyHead = ({ party, meta }: Props) => {
|
|||
raidName: party.raid ? party.raid.name[locale] : '',
|
||||
})}
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
|
||||
<link rel="icon" type="image/x-icon" href="/images/favicon.png" />
|
||||
|
||||
{/* OpenGraph */}
|
||||
|
|
|
|||
|
|
@ -261,9 +261,7 @@ const SummonGrid = (props: Props) => {
|
|||
|
||||
try {
|
||||
if (stage != previousTranscendenceStages[position])
|
||||
await api.endpoints.grid_summons
|
||||
.update(id, payload)
|
||||
.then((response) => {
|
||||
await api.updateTranscendence('summon', id, stage).then((response) => {
|
||||
storeGridSummon(response.data.grid_summon)
|
||||
})
|
||||
} catch (error) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
.Fragment {
|
||||
.fragment {
|
||||
$degrees: 72deg;
|
||||
|
||||
$origWidth: 29px;
|
||||
|
|
@ -28,11 +28,11 @@
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
&.Visible {
|
||||
&.visible {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&.Stage1 {
|
||||
&.stage1 {
|
||||
top: 3px;
|
||||
left: 18px;
|
||||
|
||||
|
|
@ -41,7 +41,7 @@
|
|||
// }
|
||||
}
|
||||
|
||||
&.Stage2 {
|
||||
&.stage2 {
|
||||
top: 10px;
|
||||
left: 27px;
|
||||
transform: rotate($degrees);
|
||||
|
|
@ -51,7 +51,7 @@
|
|||
// }
|
||||
}
|
||||
|
||||
&.Stage3 {
|
||||
&.stage3 {
|
||||
top: 21px;
|
||||
left: 24px;
|
||||
transform: rotate($degrees * 2);
|
||||
|
|
@ -61,7 +61,7 @@
|
|||
// }
|
||||
}
|
||||
|
||||
&.Stage4 {
|
||||
&.stage4 {
|
||||
top: 21px;
|
||||
left: 12px;
|
||||
transform: rotate($degrees * 3);
|
||||
|
|
@ -71,7 +71,7 @@
|
|||
// }
|
||||
}
|
||||
|
||||
&.Stage5 {
|
||||
&.stage5 {
|
||||
top: 10px;
|
||||
left: 8px;
|
||||
transform: rotate($degrees * 4);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react'
|
||||
import classnames from 'classnames'
|
||||
import classNames from 'classnames'
|
||||
|
||||
import styles from './index.module.scss'
|
||||
|
||||
|
|
@ -18,14 +18,14 @@ const TranscendenceFragment = ({
|
|||
onClick,
|
||||
onHover,
|
||||
}: Props) => {
|
||||
const classes = classnames({
|
||||
Fragment: true,
|
||||
Visible: visible,
|
||||
Stage1: stage === 1,
|
||||
Stage2: stage === 2,
|
||||
Stage3: stage === 3,
|
||||
Stage4: stage === 4,
|
||||
Stage5: stage === 5,
|
||||
const classes = classNames({
|
||||
[styles.fragment]: true,
|
||||
[styles.visible]: visible,
|
||||
[styles.stage1]: stage === 1,
|
||||
[styles.stage2]: stage === 2,
|
||||
[styles.stage3]: stage === 3,
|
||||
[styles.stage4]: stage === 4,
|
||||
[styles.stage5]: stage === 5,
|
||||
})
|
||||
|
||||
function handleClick() {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,20 @@
|
|||
.Transcendence.Popover {
|
||||
align-items: center;
|
||||
.transcendence {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $unit-half;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: $unit-10x;
|
||||
height: $unit-10x;
|
||||
justify-content: center;
|
||||
|
||||
animation: scaleIn $duration-zoom ease-out;
|
||||
background: var(--dialog-bg);
|
||||
border-radius: $card-corner;
|
||||
border: 0.5px solid rgba(0, 0, 0, 0.18);
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.24);
|
||||
outline: none;
|
||||
padding: $unit;
|
||||
transform-origin: var(--radix-popover-content-transform-origin);
|
||||
z-index: 32;
|
||||
|
||||
&.open {
|
||||
|
|
@ -18,7 +27,50 @@
|
|||
font-weight: $medium;
|
||||
}
|
||||
|
||||
.Pending {
|
||||
.pending {
|
||||
color: $yellow;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes scaleIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: scale(0);
|
||||
}
|
||||
20% {
|
||||
opacity: 0.2;
|
||||
transform: scale(0.4);
|
||||
}
|
||||
40% {
|
||||
opacity: 0.4;
|
||||
transform: scale(0.8);
|
||||
}
|
||||
60% {
|
||||
opacity: 0.6;
|
||||
transform: scale(1);
|
||||
}
|
||||
65% {
|
||||
opacity: 0.65;
|
||||
transform: scale(1.1);
|
||||
}
|
||||
70% {
|
||||
opacity: 0.7;
|
||||
transform: scale(1);
|
||||
}
|
||||
75% {
|
||||
opacity: 0.75;
|
||||
transform: scale(0.98);
|
||||
}
|
||||
80% {
|
||||
opacity: 0.8;
|
||||
transform: scale(1.02);
|
||||
}
|
||||
90% {
|
||||
opacity: 0.9;
|
||||
transform: scale(0.96);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ import React, { PropsWithChildren, useEffect, useState } from 'react'
|
|||
import { useTranslation } from 'next-i18next'
|
||||
import classNames from 'classnames'
|
||||
|
||||
import { Popover } from '@radix-ui/react-popover'
|
||||
import {
|
||||
Popover,
|
||||
PopoverAnchor,
|
||||
PopoverContent,
|
||||
} from '~components/common/PopoverContent'
|
||||
|
|
@ -40,12 +40,8 @@ const TranscendencePopover = ({
|
|||
|
||||
const popoverRef = React.createRef<HTMLDivElement>()
|
||||
|
||||
const classes = classNames({
|
||||
Transcendence: true,
|
||||
})
|
||||
|
||||
const levelClasses = classNames({
|
||||
Pending: stage != currentStage,
|
||||
[styles.pending]: stage != currentStage,
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -77,16 +73,20 @@ const TranscendencePopover = ({
|
|||
return (
|
||||
<Popover open={open} onOpenChange={onOpenChange}>
|
||||
<PopoverAnchor>{children}</PopoverAnchor>
|
||||
<PopoverContent className={classes} ref={popoverRef} tabIndex={tabIndex}>
|
||||
<PopoverContent
|
||||
className={styles.transcendence}
|
||||
ref={popoverRef}
|
||||
tabIndex={tabIndex}
|
||||
>
|
||||
<TranscendenceStar
|
||||
className="Interactive Base"
|
||||
className="interactive base"
|
||||
editable={true}
|
||||
interactive={true}
|
||||
stage={stage}
|
||||
onFragmentClick={handleFragmentClicked}
|
||||
onFragmentHover={handleFragmentHovered}
|
||||
/>
|
||||
<h4>
|
||||
<h4 className="name">
|
||||
<span>{t('level')} </span>
|
||||
<span className={levelClasses}>{baseLevel + 10 * currentStage}</span>
|
||||
</h4>
|
||||
|
|
|
|||
|
|
@ -46,9 +46,12 @@ const TranscendenceStar = ({
|
|||
[styles.stage5]: stage === 5,
|
||||
})
|
||||
|
||||
const baseImageClasses = classnames(className, {
|
||||
const baseImageClasses = classnames(
|
||||
{
|
||||
[styles.figure]: true,
|
||||
})
|
||||
},
|
||||
className?.split(' ').map((c) => styles[c])
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
setVisibleStage(stage)
|
||||
|
|
@ -87,7 +90,7 @@ const TranscendenceStar = ({
|
|||
onMouseLeave={interactive ? handleMouseLeave : () => {}}
|
||||
tabIndex={tabIndex}
|
||||
>
|
||||
<div className="Fragments">
|
||||
<div className={styles.fragments}>
|
||||
{[...Array(NUM_FRAGMENTS)].map((e, i) => {
|
||||
const loopStage = i + 1
|
||||
return interactive ? (
|
||||
|
|
|
|||
49
package-lock.json
generated
49
package-lock.json
generated
|
|
@ -20,8 +20,11 @@
|
|||
"@radix-ui/react-tooltip": "^1.0.3",
|
||||
"@svgr/webpack": "^6.2.0",
|
||||
"@tiptap/extension-bubble-menu": "^2.0.3",
|
||||
"@tiptap/extension-highlight": "^2.0.3",
|
||||
"@tiptap/extension-link": "^2.0.3",
|
||||
"@tiptap/extension-mention": "^2.0.3",
|
||||
"@tiptap/extension-placeholder": "^2.0.3",
|
||||
"@tiptap/extension-typography": "^2.0.3",
|
||||
"@tiptap/extension-youtube": "^2.0.3",
|
||||
"@tiptap/pm": "^2.0.3",
|
||||
"@tiptap/react": "^2.0.3",
|
||||
|
|
@ -56,6 +59,7 @@
|
|||
"react-lite-youtube-embed": "^2.3.52",
|
||||
"react-scroll": "^1.8.5",
|
||||
"react-string-replace": "^1.1.0",
|
||||
"remixicon-react": "^1.0.0",
|
||||
"resolve-url-loader": "^5.0.0",
|
||||
"sanitize-html": "^2.8.1",
|
||||
"sass": "^1.61.0",
|
||||
|
|
@ -7229,6 +7233,18 @@
|
|||
"@tiptap/core": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-highlight": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-highlight/-/extension-highlight-2.0.3.tgz",
|
||||
"integrity": "sha512-NrtibY8cZkIjZMQuHRrKd4php+plOvAoSo8g3uVFu275I/Ixt5HqJ53R4voCXs8W8BOBRs2HS2QX8Cjh79XhtA==",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-history": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-2.0.3.tgz",
|
||||
|
|
@ -7333,6 +7349,19 @@
|
|||
"@tiptap/core": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-placeholder": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-placeholder/-/extension-placeholder-2.0.3.tgz",
|
||||
"integrity": "sha512-Z42jo0termRAf0S0L8oxrts94IWX5waU4isS2CUw8xCUigYyCFslkhQXkWATO1qRbjNFLKN2C9qvCgGf4UeBrw==",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.0.0",
|
||||
"@tiptap/pm": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-strike": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.0.3.tgz",
|
||||
|
|
@ -7357,6 +7386,18 @@
|
|||
"@tiptap/core": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-typography": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-typography/-/extension-typography-2.0.3.tgz",
|
||||
"integrity": "sha512-5U91O2dffYOvwenWG+zT1N/pnt+RppSlocxs1KaNWFLlI2fgzDTyUyjzygIHGmskStqay2MuvmPnfVABoC+1Gw==",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-youtube": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-youtube/-/extension-youtube-2.0.3.tgz",
|
||||
|
|
@ -19306,6 +19347,14 @@
|
|||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/remixicon-react": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/remixicon-react/-/remixicon-react-1.0.0.tgz",
|
||||
"integrity": "sha512-KOXlc8EdKdujr2f/2idyFSQRjUB8p0HNiWZYBBzRsTRlTXFuSAFfnGq9culNjhCGmc92Jbtfr9OP0MXWvTMdsQ==",
|
||||
"peerDependencies": {
|
||||
"react": ">=0.14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/renderkid": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz",
|
||||
|
|
|
|||
|
|
@ -27,8 +27,11 @@
|
|||
"@radix-ui/react-tooltip": "^1.0.3",
|
||||
"@svgr/webpack": "^6.2.0",
|
||||
"@tiptap/extension-bubble-menu": "^2.0.3",
|
||||
"@tiptap/extension-highlight": "^2.0.3",
|
||||
"@tiptap/extension-link": "^2.0.3",
|
||||
"@tiptap/extension-mention": "^2.0.3",
|
||||
"@tiptap/extension-placeholder": "^2.0.3",
|
||||
"@tiptap/extension-typography": "^2.0.3",
|
||||
"@tiptap/extension-youtube": "^2.0.3",
|
||||
"@tiptap/pm": "^2.0.3",
|
||||
"@tiptap/react": "^2.0.3",
|
||||
|
|
@ -63,6 +66,7 @@
|
|||
"react-lite-youtube-embed": "^2.3.52",
|
||||
"react-scroll": "^1.8.5",
|
||||
"react-string-replace": "^1.1.0",
|
||||
"remixicon-react": "^1.0.0",
|
||||
"resolve-url-loader": "^5.0.0",
|
||||
"sanitize-html": "^2.8.1",
|
||||
"sass": "^1.61.0",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { appWithTranslation } from 'next-i18next'
|
||||
import Head from 'next/head'
|
||||
import Link from 'next/link'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { get } from 'local-storage'
|
||||
|
|
@ -131,6 +132,13 @@ function MyApp({ Component, pageProps }: AppProps) {
|
|||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<meta
|
||||
name="viewport"
|
||||
content="viewport-fit=cover, width=device-width, initial-scale=1.0"
|
||||
/>
|
||||
</Head>
|
||||
<ThemeProvider>
|
||||
<ToastProvider swipeDirection="right">
|
||||
<TooltipProvider>
|
||||
|
|
@ -145,6 +153,7 @@ function MyApp({ Component, pageProps }: AppProps) {
|
|||
</TooltipProvider>
|
||||
</ToastProvider>
|
||||
</ThemeProvider>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -90,8 +90,8 @@ const PartyRoute: React.FC<Props> = ({
|
|||
break
|
||||
}
|
||||
|
||||
if (router.asPath !== '/new' && router.asPath !== '/')
|
||||
router.replace(path, undefined, { shallow: true })
|
||||
// if (router.asPath !== '/new' && router.asPath !== '/')
|
||||
// router.replace(path, undefined, { shallow: true })
|
||||
}
|
||||
|
||||
// Set the initial data from props
|
||||
|
|
|
|||
1
public/icons/remix/list-ordered-2.svg
Normal file
1
public/icons/remix/list-ordered-2.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M5.75024 3.5H4.71733L3.25 3.89317V5.44582L4.25002 5.17782L4.25018 8.5H3V10H7V8.5H5.75024V3.5ZM10 4H21V6H10V4ZM10 11H21V13H10V11ZM10 18H21V20H10V18ZM2.875 15.625C2.875 14.4514 3.82639 13.5 5 13.5C6.17361 13.5 7.125 14.4514 7.125 15.625C7.125 16.1106 6.96183 16.5587 6.68747 16.9167L6.68271 16.9229L5.31587 18.5H7V20H3.00012L2.99959 18.8786L5.4717 16.035C5.5673 15.9252 5.625 15.7821 5.625 15.625C5.625 15.2798 5.34518 15 5 15C4.67378 15 4.40573 15.2501 4.37747 15.5688L4.3651 15.875H2.875V15.625Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 579 B |
|
|
@ -557,6 +557,19 @@
|
|||
"tokens": {
|
||||
"remix": "Remixed"
|
||||
},
|
||||
"toolbar": {
|
||||
"tooltips": {
|
||||
"bold": "Bold",
|
||||
"italic": "Italic",
|
||||
"strike": "Strikethrough",
|
||||
"highlight": "Highlight",
|
||||
"link": "Add a link",
|
||||
"youtube": "Add a Youtube video",
|
||||
"heading": "Heading {{level}}",
|
||||
"bulletList": "Bullet list",
|
||||
"orderedList": "Numbered list"
|
||||
}
|
||||
},
|
||||
"tooltips": {
|
||||
"copy_url": "Copy the URL to this team",
|
||||
"new": "Create a new team",
|
||||
|
|
|
|||
|
|
@ -555,6 +555,19 @@
|
|||
"tokens": {
|
||||
"remix": "リミックスされた"
|
||||
},
|
||||
"toolbar": {
|
||||
"tooltips": {
|
||||
"bold": "太字",
|
||||
"italic": "斜体",
|
||||
"strike": "取り消し線",
|
||||
"highlight": "ハイライト",
|
||||
"link": "リンクを挿入",
|
||||
"youtube": "Youtube動画を埋め込む",
|
||||
"heading": "見出し {{level}}",
|
||||
"bulletList": "箇条書き",
|
||||
"orderedList": "番号リスト"
|
||||
}
|
||||
},
|
||||
"tooltips": {
|
||||
"copy_url": "この編成のURLをコピーする",
|
||||
"new": "新しい編成を作成する",
|
||||
|
|
|
|||
|
|
@ -63,6 +63,12 @@
|
|||
--toolbar-item-text-hover: #{$toolbar--item--text--light--hover};
|
||||
--toolbar-item-text-active: #{$toolbar--item--text--light--active};
|
||||
|
||||
// Light - Highlights
|
||||
--highlight-bg: #{$highlight--bg--light};
|
||||
--highlight-bg-hover: #{$highlight--bg--light--hover};
|
||||
--highlight-text: #{$highlight--text--light};
|
||||
--highlight-text-hover: #{$highlight--text--light--hover};
|
||||
|
||||
// Light - Placeholders
|
||||
--placeholder-bound-bg: #{$placeholder--bound--bg--light};
|
||||
--placeholder-bound-bg-hover: #{$placeholder--bound--bg--light--hover};
|
||||
|
|
@ -153,6 +159,14 @@
|
|||
--grid-border-color: #{$grid--border--color--light};
|
||||
|
||||
// Light - Element theming
|
||||
--null-bg: #{$null--bg--light};
|
||||
--null-bg-hover: #{$null--bg--hover--light};
|
||||
--null-text: #{$null--text--light};
|
||||
--null-raid-text: #{$null--text--raid--light};
|
||||
--null-text-hover: #{$null--text--hover--light};
|
||||
--null-shadow: #{$null--shadow--light};
|
||||
--null-shadow-hover: #{$null--shadow--light--hover};
|
||||
|
||||
--wind-bg: #{$wind--bg--light};
|
||||
--wind-bg-hover: #{$wind--bg--hover--light};
|
||||
--wind-text: #{$wind--text--light};
|
||||
|
|
@ -271,6 +285,12 @@
|
|||
--toolbar-item-text-hover: #{$toolbar--item--text--dark--hover};
|
||||
--toolbar-item-text-active: #{$toolbar--item--text--dark--active};
|
||||
|
||||
// Dark - Highlights
|
||||
--highlight-bg: #{$highlight--bg--dark};
|
||||
--highlight-bg-hover: #{$highlight--bg--dark--hover};
|
||||
--highlight-text: #{$highlight--text--dark};
|
||||
--highlight-text-hover: #{$highlight--text--dark--hover};
|
||||
|
||||
// Dark - Placeholders
|
||||
--placeholder-bound-bg: #{$placeholder--bound--bg--dark};
|
||||
--placeholder-bound-bg-hover: #{$placeholder--bound--bg--dark--hover};
|
||||
|
|
@ -361,6 +381,14 @@
|
|||
--grid-border-color: #{$grid--border--color--dark};
|
||||
|
||||
// Dark - Element theming
|
||||
--null-bg: #{$null--bg--dark};
|
||||
--null-bg-hover: #{$null--bg--hover--dark};
|
||||
--null-text: #{$null--text--dark};
|
||||
--null-raid-text: #{$null--text--raid--dark};
|
||||
--null-text-hover: #{$null--text--hover--dark};
|
||||
--null-shadow: #{$null--shadow--dark};
|
||||
--null-shadow-hover: #{$null--shadow--dark--hover};
|
||||
|
||||
--wind-bg: #{$wind--bg--dark};
|
||||
--wind-bg-hover: #{$wind--bg--hover--dark};
|
||||
--wind-text: #{$wind--text--dark};
|
||||
|
|
|
|||
|
|
@ -79,6 +79,13 @@ $orange-75: #ffb461;
|
|||
$orange-80: #facea7;
|
||||
$orange-90: #ffebd9;
|
||||
|
||||
// Yellow -- Highlights
|
||||
$yellow-10: #4d3703;
|
||||
$yellow-30: #956d11;
|
||||
$yellow-50: #c8a657;
|
||||
$yellow-70: #fedc8d;
|
||||
$yellow-90: #ffed4c;
|
||||
|
||||
// Colors -- Interface
|
||||
$blue: #275dc5;
|
||||
$red: #ff6161;
|
||||
|
|
@ -96,6 +103,7 @@ $accent--yellow--light: #c89d39;
|
|||
$accent--yellow--dark: #f9cc64;
|
||||
$yellow-text-10: #a39200;
|
||||
$yellow-text-20: #ffed4c;
|
||||
$highlight-yellow: #ffed4c55;
|
||||
|
||||
$accent--yellow--00: #463805;
|
||||
$accent--yellow--20: #7f6a00;
|
||||
|
|
@ -383,6 +391,19 @@ $toolbar--item--text--dark--hover: $grey-90;
|
|||
$toolbar--item--text--light--active: $grey-100;
|
||||
$toolbar--item--text--dark--active: $grey-00;
|
||||
|
||||
// Color Definitions: Highlights
|
||||
$highlight--bg--light: $yellow-70;
|
||||
$highlight--bg--dark: $yellow-50;
|
||||
|
||||
$highlight--bg--light--hover: $yellow-50;
|
||||
$highlight--bg--dark--hover: $yellow-70;
|
||||
|
||||
$highlight--text--light: $yellow-30;
|
||||
$highlight--text--dark: $yellow-10;
|
||||
|
||||
$highlight--text--light--hover: $yellow-10;
|
||||
$highlight--text--dark--hover: $yellow-30;
|
||||
|
||||
// Color Definitions: Element Toggle
|
||||
$toggle--bg--light: $grey-90;
|
||||
$toggle--bg--dark: $grey-15;
|
||||
|
|
@ -443,6 +464,28 @@ $wind--shadow--dark: fade-out($wind-text-20, 0.3);
|
|||
$wind--shadow--light--hover: fade-out($wind-text-00, 0.3);
|
||||
$wind--shadow--dark--hover: fade-out($wind-text-00, 0.3);
|
||||
|
||||
// Color Definitions: Element / Null
|
||||
$null--bg--light: $grey-75;
|
||||
$null--bg--dark: $grey-40;
|
||||
|
||||
$null--bg--hover--light: $grey-70;
|
||||
$null--bg--hover--dark: $grey-30;
|
||||
|
||||
$null--text--light: $grey-40;
|
||||
$null--text--dark: $grey-90;
|
||||
|
||||
$null--text--raid--light: $grey-40;
|
||||
$null--text--raid--dark: $grey-90;
|
||||
|
||||
$null--text--hover--light: $grey-20;
|
||||
$null--text--hover--dark: $grey-90;
|
||||
|
||||
$null--shadow--light: fade-out($grey-60, 0.3);
|
||||
$null--shadow--dark: fade-out($grey-25, 0.3);
|
||||
|
||||
$null--shadow--light--hover: fade-out($grey-50, 0.3);
|
||||
$null--shadow--dark--hover: fade-out($grey-10, 0.3);
|
||||
|
||||
// Color Definitions: Element / Fire
|
||||
$fire--bg--light: $fire-bg-10;
|
||||
$fire--bg--dark: $fire-bg-10;
|
||||
|
|
|
|||
|
|
@ -180,6 +180,17 @@ class Api {
|
|||
})
|
||||
}
|
||||
|
||||
updateTranscendence(resource: 'character'|'summon', id: string, value: number) {
|
||||
const pluralized = resource + 's'
|
||||
const resourceUrl = `${this.url}/${pluralized}/update_uncap`
|
||||
return axios.post(resourceUrl, {
|
||||
[resource]: {
|
||||
id: id,
|
||||
transcendence_step: value
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
userInfo(id: string) {
|
||||
const resourceUrl = `${this.url}/users/info/${id}`
|
||||
return axios.get(resourceUrl)
|
||||
|
|
|
|||
Loading…
Reference in a new issue