1
- import { Badge , createStyles , Divider , Grid , Group , Image , LoadingOverlay , Text , Title , Tooltip } from '@mantine/core' ;
1
+ import {
2
+ ActionIcon ,
3
+ Badge ,
4
+ createStyles ,
5
+ Divider ,
6
+ Grid ,
7
+ Group ,
8
+ Image ,
9
+ LoadingOverlay ,
10
+ Popover ,
11
+ Text ,
12
+ TextInput ,
13
+ Title ,
14
+ Tooltip ,
15
+ } from '@mantine/core' ;
2
16
import { UseFormReturnType } from '@mantine/form' ;
17
+ import { getHotkeyHandler } from '@mantine/hooks' ;
18
+ import { IconCheck , IconEdit , IconGitMerge } from '@tabler/icons' ;
19
+ import { useState } from 'react' ;
3
20
import { trpc } from '../../../utils/trpc' ;
4
21
import type { FormType } from '../form' ;
5
22
@@ -11,6 +28,9 @@ const useStyles = createStyles((_theme) => ({
11
28
} ) ) ;
12
29
13
30
export function ReviewStep ( { form } : { form : UseFormReturnType < FormType > } ) {
31
+ const [ anilistId , setAnilistId ] = useState < string > ( ) ;
32
+ const [ opened , setOpened ] = useState ( false ) ;
33
+ const bindMutation = trpc . manga . bind . useMutation ( ) ;
14
34
const query = trpc . manga . detail . useQuery (
15
35
{
16
36
source : form . values . source ,
@@ -26,9 +46,23 @@ export function ReviewStep({ form }: { form: UseFormReturnType<FormType> }) {
26
46
27
47
const manga = query . data ;
28
48
49
+ const handleBind = async ( ) => {
50
+ setOpened ( false ) ;
51
+ if ( ! anilistId || ! manga ?. Name ) {
52
+ return ;
53
+ }
54
+ await bindMutation . mutateAsync ( {
55
+ anilistId,
56
+ title : manga . Name ,
57
+ } ) ;
58
+
59
+ query . refetch ( ) ;
60
+ setAnilistId ( '' ) ;
61
+ } ;
62
+
29
63
return (
30
64
< >
31
- < LoadingOverlay visible = { query . isLoading } />
65
+ < LoadingOverlay visible = { query . isLoading || bindMutation . isLoading } />
32
66
33
67
{ manga && (
34
68
< Grid >
@@ -55,7 +89,67 @@ export function ReviewStep({ form }: { form: UseFormReturnType<FormType> }) {
55
89
/>
56
90
</ Grid . Col >
57
91
< Grid . Col span = { 8 } >
58
- < Divider mb = "xs" labelPosition = "center" label = { < Title order = { 3 } > { manga . Name } </ Title > } />
92
+ < Divider
93
+ mb = "xs"
94
+ labelPosition = "center"
95
+ label = {
96
+ < >
97
+ < Title order = { 3 } > { manga . Name } </ Title >
98
+ < Popover
99
+ width = { 300 }
100
+ trapFocus
101
+ position = "bottom"
102
+ withArrow
103
+ shadow = "md"
104
+ opened = { opened }
105
+ onChange = { setOpened }
106
+ >
107
+ < Popover . Target >
108
+ < Tooltip inline label = "Fix the wrong match" >
109
+ < ActionIcon
110
+ ml = { 4 }
111
+ color = "blue"
112
+ variant = "transparent"
113
+ size = "lg"
114
+ radius = "xl"
115
+ onClick = { ( ) => setOpened ( ( o ) => ! o ) }
116
+ >
117
+ < IconEdit size = { 18 } />
118
+ </ ActionIcon >
119
+ </ Tooltip >
120
+ </ Popover . Target >
121
+ < Popover . Dropdown
122
+ sx = { ( theme ) => ( {
123
+ background : theme . colorScheme === 'dark' ? theme . colors . dark [ 7 ] : theme . white ,
124
+ } ) }
125
+ >
126
+ < TextInput
127
+ data-autofocus
128
+ mb = "xl"
129
+ size = "md"
130
+ radius = "xl"
131
+ value = { anilistId }
132
+ onChange = { ( event ) => setAnilistId ( event . currentTarget . value ) }
133
+ onKeyDown = { getHotkeyHandler ( [ [ 'Enter' , handleBind ] ] ) }
134
+ icon = { < IconGitMerge size = { 18 } stroke = { 1.5 } /> }
135
+ rightSection = {
136
+ < ActionIcon size = { 32 } radius = "xl" color = "blue" variant = "filled" onClick = { handleBind } >
137
+ < IconCheck size = { 18 } stroke = { 1.5 } />
138
+ </ ActionIcon >
139
+ }
140
+ rightSectionWidth = { 42 }
141
+ label = {
142
+ < Text size = "sm" mb = "xs" >
143
+ Please enter a new AniList id for { manga . Name }
144
+ </ Text >
145
+ }
146
+ placeholder = "AniList Id"
147
+ />
148
+ </ Popover . Dropdown >
149
+ </ Popover >
150
+ </ >
151
+ }
152
+ />
59
153
{ manga . Metadata . Synonyms && (
60
154
< Group spacing = "xs" >
61
155
{ manga . Metadata . Synonyms . map ( ( synonym ) => (
0 commit comments