Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wiki-js
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
wiki-js
Commits
7fe7fbb3
Unverified
Commit
7fe7fbb3
authored
Jul 31, 2022
by
Nicolas Giard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: admin api keys
parent
6625267b
Show whitespace changes
Inline
Side-by-side
Showing
30 changed files
with
727 additions
and
406 deletions
+727
-406
3.0.0.js
server/db/migrations/3.0.0.js
+1
-1
authentication.js
server/graph/resolvers/authentication.js
+5
-3
authentication.graphql
server/graph/schemas/authentication.graphql
+9
-10
apiKeys.js
server/models/apiKeys.js
+14
-10
authentication.js
server/models/authentication.js
+1
-1
package.json
ux/package.json
+10
-11
fluent-downloading-updates.svg
ux/public/_assets/icons/fluent-downloading-updates.svg
+2
-0
fluent-key-2.svg
ux/public/_assets/icons/fluent-key-2.svg
+2
-0
fluent-unavailable.svg
ux/public/_assets/icons/fluent-unavailable.svg
+2
-0
ultraviolet-binary-file.svg
ux/public/_assets/icons/ultraviolet-binary-file.svg
+2
-0
ultraviolet-schedule.svg
ux/public/_assets/icons/ultraviolet-schedule.svg
+2
-0
undraw_going_up.svg
ux/public/_assets/illustrations/undraw_going_up.svg
+2
-0
undraw_icon_design.svg
ux/public/_assets/illustrations/undraw_icon_design.svg
+2
-0
undraw_settings.svg
ux/public/_assets/illustrations/undraw_settings.svg
+2
-0
undraw_world.svg
ux/public/_assets/illustrations/undraw_world.svg
+2
-0
apollo.js
ux/src/boot/apollo.js
+0
-8
ApiKeyCopyDialog.vue
ux/src/components/ApiKeyCopyDialog.vue
+63
-0
ApiKeyCreateDialog.vue
ux/src/components/ApiKeyCreateDialog.vue
+253
-0
ApiKeyRevokeDialog.vue
ux/src/components/ApiKeyRevokeDialog.vue
+104
-0
CheckUpdateDialog.vue
ux/src/components/CheckUpdateDialog.vue
+101
-0
app.scss
ux/src/css/app.scss
+21
-0
en.json
ux/src/i18n/locales/en.json
+19
-2
AdminApi.vue
ux/src/pages/AdminApi.vue
+72
-120
AdminApiCreate.vue
ux/src/pages/AdminApiCreate.vue
+0
-236
AdminAuth.vue
ux/src/pages/AdminAuth.vue
+2
-1
AdminDashboard.vue
ux/src/pages/AdminDashboard.vue
+9
-2
AdminFlags.vue
ux/src/pages/AdminFlags.vue
+4
-0
AdminLocale.vue
ux/src/pages/AdminLocale.vue
+3
-0
AdminSystem.vue
ux/src/pages/AdminSystem.vue
+18
-1
yarn.lock
ux/yarn.lock
+0
-0
No files found.
server/db/migrations/3.0.0.js
View file @
7fe7fbb3
...
...
@@ -29,7 +29,7 @@ exports.up = async knex => {
table
.
uuid
(
'id'
).
notNullable
().
primary
().
defaultTo
(
knex
.
raw
(
'gen_random_uuid()'
))
table
.
string
(
'name'
).
notNullable
()
table
.
text
(
'key'
).
notNullable
()
table
.
string
(
'expiration'
).
notNullable
(
)
table
.
timestamp
(
'expiration'
).
notNullable
().
defaultTo
(
knex
.
fn
.
now
()
)
table
.
boolean
(
'isRevoked'
).
notNullable
().
defaultTo
(
false
)
table
.
timestamp
(
'createdAt'
).
notNullable
().
defaultTo
(
knex
.
fn
.
now
())
table
.
timestamp
(
'updatedAt'
).
notNullable
().
defaultTo
(
knex
.
fn
.
now
())
...
...
server/graph/resolvers/authentication.js
View file @
7fe7fbb3
...
...
@@ -12,6 +12,7 @@ module.exports = {
*/
async
apiKeys
(
obj
,
args
,
context
)
{
const
keys
=
await
WIKI
.
models
.
apiKeys
.
query
().
orderBy
([
'isRevoked'
,
'name'
])
console
.
info
(
keys
)
return
keys
.
map
(
k
=>
({
id
:
k
.
id
,
name
:
k
.
name
,
...
...
@@ -78,9 +79,10 @@ module.exports = {
WIKI
.
events
.
outbound
.
emit
(
'reloadApiKeys'
)
return
{
key
,
responseResult
:
graphHelper
.
generateSuccess
(
'API Key created successfully'
)
operation
:
graphHelper
.
generateSuccess
(
'API Key created successfully'
)
}
}
catch
(
err
)
{
WIKI
.
logger
.
warn
(
err
)
return
graphHelper
.
generateError
(
err
)
}
},
...
...
@@ -165,7 +167,7 @@ module.exports = {
WIKI
.
config
.
api
.
isEnabled
=
args
.
enabled
await
WIKI
.
configSvc
.
saveToDb
([
'api'
])
return
{
responseResult
:
graphHelper
.
generateSuccess
(
'API State changed successfully'
)
operation
:
graphHelper
.
generateSuccess
(
'API State changed successfully'
)
}
}
catch
(
err
)
{
return
graphHelper
.
generateError
(
err
)
...
...
@@ -182,7 +184,7 @@ module.exports = {
await
WIKI
.
auth
.
reloadApiKeys
()
WIKI
.
events
.
outbound
.
emit
(
'reloadApiKeys'
)
return
{
responseResult
:
graphHelper
.
generateSuccess
(
'API Key revoked successfully'
)
operation
:
graphHelper
.
generateSuccess
(
'API Key revoked successfully'
)
}
}
catch
(
err
)
{
return
graphHelper
.
generateError
(
err
)
...
...
server/graph/schemas/authentication.graphql
View file @
7fe7fbb3
...
...
@@ -21,8 +21,7 @@ extend type Mutation {
createApiKey
(
name
:
String
!
expiration
:
String
!
fullAccess
:
Boolean
!
group
:
Int
groups
:
[
UUID
]!
):
AuthenticationCreateApiKeyResponse
login
(
...
...
@@ -53,7 +52,7 @@ extend type Mutation {
):
AuthenticationRegisterResponse
revokeApiKey
(
id
:
Int
!
id
:
UUID
!
):
DefaultResponse
setApiState
(
...
...
@@ -135,13 +134,13 @@ input AuthenticationStrategyInput {
}
type
AuthenticationApiKey
{
id
:
Int
!
name
:
String
!
keyShort
:
String
!
expiration
:
Date
!
createdAt
:
Date
!
updatedAt
:
Date
!
isRevoked
:
Boolean
!
id
:
UUID
name
:
String
keyShort
:
String
expiration
:
Date
createdAt
:
Date
updatedAt
:
Date
isRevoked
:
Boolean
}
type
AuthenticationCreateApiKeyResponse
{
...
...
server/models/apiKeys.js
View file @
7fe7fbb3
/* global WIKI */
const
Model
=
require
(
'objection'
).
Model
const
moment
=
require
(
'moment
'
)
const
{
DateTime
}
=
require
(
'luxon
'
)
const
ms
=
require
(
'ms'
)
const
jwt
=
require
(
'jsonwebtoken'
)
...
...
@@ -17,7 +17,7 @@ module.exports = class ApiKey extends Model {
required
:
[
'name'
,
'key'
],
properties
:
{
id
:
{
type
:
'
integer
'
},
id
:
{
type
:
'
string
'
},
name
:
{
type
:
'string'
},
key
:
{
type
:
'string'
},
expiration
:
{
type
:
'string'
},
...
...
@@ -31,29 +31,33 @@ module.exports = class ApiKey extends Model {
async
$beforeUpdate
(
opt
,
context
)
{
await
super
.
$beforeUpdate
(
opt
,
context
)
this
.
updatedAt
=
moment
.
utc
().
toISOString
()
this
.
updatedAt
=
new
Date
().
toISOString
()
}
async
$beforeInsert
(
context
)
{
await
super
.
$beforeInsert
(
context
)
this
.
createdAt
=
moment
.
utc
().
toISOString
()
this
.
updatedAt
=
moment
.
utc
().
toISOString
()
this
.
createdAt
=
new
Date
().
toISOString
()
this
.
updatedAt
=
new
Date
().
toISOString
()
}
static
async
createNewKey
({
name
,
expiration
,
fullAccess
,
group
})
{
static
async
createNewKey
({
name
,
expiration
,
groups
})
{
console
.
info
(
DateTime
.
utc
().
plus
(
ms
(
expiration
)).
toISO
())
const
entry
=
await
WIKI
.
models
.
apiKeys
.
query
().
insert
({
name
,
key
:
'pending'
,
expiration
:
moment
.
utc
().
add
(
ms
(
expiration
),
'ms'
).
toISOString
(),
expiration
:
DateTime
.
utc
().
plus
(
ms
(
expiration
)).
toISO
(),
isRevoked
:
true
})
console
.
info
(
entry
)
const
key
=
jwt
.
sign
({
api
:
entry
.
id
,
grp
:
fullAccess
?
1
:
group
grp
:
groups
},
{
key
:
WIKI
.
config
.
certs
.
private
,
passphrase
:
WIKI
.
config
.
sessionS
ecret
key
:
WIKI
.
config
.
auth
.
certs
.
private
,
passphrase
:
WIKI
.
config
.
auth
.
s
ecret
},
{
algorithm
:
'RS256'
,
expiresIn
:
expiration
,
...
...
server/models/authentication.js
View file @
7fe7fbb3
...
...
@@ -35,7 +35,7 @@ module.exports = class Authentication extends Model {
}
static
async
getStrategies
()
{
const
strategies
=
await
WIKI
.
models
.
authentication
.
query
()
.
orderBy
(
'order'
)
const
strategies
=
await
WIKI
.
models
.
authentication
.
query
()
return
strategies
.
map
(
str
=>
({
...
str
,
domainWhitelist
:
_
.
get
(
str
.
domainWhitelist
,
'v'
,
[]),
...
...
ux/package.json
View file @
7fe7fbb3
...
...
@@ -32,7 +32,7 @@
"@codemirror/tooltip"
:
"0.19.16"
,
"@codemirror/view"
:
"6.0.2"
,
"@lezer/common"
:
"1.0.0"
,
"@quasar/extras"
:
"1.1
4.2
"
,
"@quasar/extras"
:
"1.1
5.0
"
,
"@tiptap/core"
:
"2.0.0-beta.176"
,
"@tiptap/extension-code-block"
:
"2.0.0-beta.37"
,
"@tiptap/extension-code-block-lowlight"
:
"2.0.0-beta.68"
,
...
...
@@ -57,9 +57,8 @@
"@tiptap/extension-typography"
:
"2.0.0-beta.20"
,
"@tiptap/starter-kit"
:
"2.0.0-beta.185"
,
"@tiptap/vue-3"
:
"2.0.0-beta.91"
,
"@vue/apollo-option"
:
"4.0.0-alpha.17"
,
"apollo-upload-client"
:
"17.0.0"
,
"browser-fs-access"
:
"0.3
0.2
"
,
"browser-fs-access"
:
"0.3
1.0
"
,
"clipboard"
:
"2.0.11"
,
"codemirror"
:
"6.0.1"
,
"filesize"
:
"9.0.11"
,
...
...
@@ -69,31 +68,31 @@
"js-cookie"
:
"3.0.1"
,
"jwt-decode"
:
"3.1.2"
,
"lodash-es"
:
"4.17.21"
,
"luxon"
:
"
2.5.0
"
,
"pinia"
:
"2.0.1
4
"
,
"luxon"
:
"
3.0.1
"
,
"pinia"
:
"2.0.1
7
"
,
"pug"
:
"3.0.2"
,
"quasar"
:
"2.7.5"
,
"tippy.js"
:
"6.3.7"
,
"uuid"
:
"8.3.2"
,
"v-network-graph"
:
"0.6.
3
"
,
"v-network-graph"
:
"0.6.
5
"
,
"vue"
:
"3.2.37"
,
"vue-codemirror"
:
"6.0.
0
"
,
"vue-codemirror"
:
"6.0.
2
"
,
"vue-i18n"
:
"9.1.10"
,
"vue-router"
:
"4.1.
1
"
,
"vue-router"
:
"4.1.
3
"
,
"vuedraggable"
:
"4.1.0"
,
"zxcvbn"
:
"4.4.2"
},
"devDependencies"
:
{
"@intlify/vite-plugin-vue-i18n"
:
"
3.4.0
"
,
"@intlify/vite-plugin-vue-i18n"
:
"
5.0.1
"
,
"@quasar/app-vite"
:
"1.0.5"
,
"@types/lodash"
:
"4.14.182"
,
"browserlist"
:
"latest"
,
"eslint"
:
"8.
19
.0"
,
"eslint"
:
"8.
20
.0"
,
"eslint-config-standard"
:
"17.0.0"
,
"eslint-plugin-import"
:
"2.26.0"
,
"eslint-plugin-n"
:
"15.2.4"
,
"eslint-plugin-promise"
:
"6.0.0"
,
"eslint-plugin-vue"
:
"9.
2
.0"
"eslint-plugin-vue"
:
"9.
3
.0"
},
"engines"
:
{
"node"
:
"^18 || ^16"
,
...
...
ux/public/_assets/icons/fluent-downloading-updates.svg
0 → 100644
View file @
7fe7fbb3
<svg
xmlns=
"http://www.w3.org/2000/svg"
viewBox=
"0 0 48 48"
width=
"96px"
height=
"96px"
><linearGradient
id=
"Gx4Hql1L2mKhvP9291EBWa"
x1=
"19.53"
x2=
"28.032"
y1=
"12.426"
y2=
"32.179"
gradientUnits=
"userSpaceOnUse"
><stop
offset=
"0"
stop-color=
"#32bdef"
/><stop
offset=
"1"
stop-color=
"#1ea2e4"
/></linearGradient><path
fill=
"url(#Gx4Hql1L2mKhvP9291EBWa)"
d=
"M31.19,22H27v-8c0-0.552-0.448-1-1-1h-4c-0.552,0-1,0.448-1,1v8h-4.19 c-0.72,0-1.08,0.87-0.571,1.379l6.701,6.701c0.586,0.586,1.536,0.586,2.121,0l6.701-6.701C32.271,22.87,31.91,22,31.19,22z"
/><linearGradient
id=
"Gx4Hql1L2mKhvP9291EBWb"
x1=
"39.761"
x2=
"43.605"
y1=
"31.57"
y2=
"42.462"
gradientUnits=
"userSpaceOnUse"
><stop
offset=
"0"
stop-color=
"#32bdef"
/><stop
offset=
"1"
stop-color=
"#1ea2e4"
/></linearGradient><path
fill=
"url(#Gx4Hql1L2mKhvP9291EBWb)"
d=
"M39,33v10l4.828-4.828c0.75-0.75,1.172-1.768,1.172-2.828V33c0-0.552-0.448-1-1-1h-4 C39.448,32,39,32.448,39,33z"
/><linearGradient
id=
"Gx4Hql1L2mKhvP9291EBWc"
x1=
"9"
x2=
"39"
y1=
"40"
y2=
"40"
gradientUnits=
"userSpaceOnUse"
><stop
offset=
"0"
stop-color=
"#0362b0"
/><stop
offset=
".112"
stop-color=
"#036abd"
/><stop
offset=
".258"
stop-color=
"#036fc5"
/><stop
offset=
".5"
stop-color=
"#0370c8"
/><stop
offset=
".742"
stop-color=
"#036fc5"
/><stop
offset=
".888"
stop-color=
"#036abd"
/><stop
offset=
"1"
stop-color=
"#0362b0"
/></linearGradient><rect
width=
"30"
height=
"6"
x=
"9"
y=
"37"
fill=
"url(#Gx4Hql1L2mKhvP9291EBWc)"
/><linearGradient
id=
"Gx4Hql1L2mKhvP9291EBWd"
x1=
"332.761"
x2=
"336.605"
y1=
"31.57"
y2=
"42.462"
gradientTransform=
"matrix(-1 0 0 1 341 0)"
gradientUnits=
"userSpaceOnUse"
><stop
offset=
"0"
stop-color=
"#32bdef"
/><stop
offset=
"1"
stop-color=
"#1ea2e4"
/></linearGradient><path
fill=
"url(#Gx4Hql1L2mKhvP9291EBWd)"
d=
"M9,33v10l-4.828-4.828C3.421,37.421,3,36.404,3,35.343V33c0-0.552,0.448-1,1-1h4 C8.552,32,9,32.448,9,33z"
/><linearGradient
id=
"Gx4Hql1L2mKhvP9291EBWe"
x1=
"23.174"
x2=
"24.956"
y1=
"4.081"
y2=
"8.222"
gradientUnits=
"userSpaceOnUse"
><stop
offset=
"0"
stop-color=
"#32bdef"
/><stop
offset=
"1"
stop-color=
"#1ea2e4"
/></linearGradient><path
fill=
"url(#Gx4Hql1L2mKhvP9291EBWe)"
d=
"M26,7h-4c-0.552,0-1-0.448-1-1v0c0-0.552,0.448-1,1-1h4c0.552,0,1,0.448,1,1v0 C27,6.552,26.552,7,26,7z"
/><linearGradient
id=
"Gx4Hql1L2mKhvP9291EBWf"
x1=
"23.174"
x2=
"24.956"
y1=
"8.081"
y2=
"12.222"
gradientUnits=
"userSpaceOnUse"
><stop
offset=
"0"
stop-color=
"#32bdef"
/><stop
offset=
"1"
stop-color=
"#1ea2e4"
/></linearGradient><path
fill=
"url(#Gx4Hql1L2mKhvP9291EBWf)"
d=
"M26,11h-4c-0.552,0-1-0.448-1-1v0c0-0.552,0.448-1,1-1h4c0.552,0,1,0.448,1,1v0 C27,10.552,26.552,11,26,11z"
/></svg>
\ No newline at end of file
ux/public/_assets/icons/fluent-key-2.svg
0 → 100644
View file @
7fe7fbb3
<svg
xmlns=
"http://www.w3.org/2000/svg"
viewBox=
"0 0 48 48"
width=
"96px"
height=
"96px"
><linearGradient
id=
"XED_QU6xiox5XDw0HU_eba"
x1=
"20.958"
x2=
"5.741"
y1=
"26.758"
y2=
"42.622"
gradientUnits=
"userSpaceOnUse"
><stop
offset=
"0"
stop-color=
"#e5a505"
/><stop
offset=
".01"
stop-color=
"#e9a804"
/><stop
offset=
".06"
stop-color=
"#f4b102"
/><stop
offset=
".129"
stop-color=
"#fbb600"
/><stop
offset=
".323"
stop-color=
"#fdb700"
/></linearGradient><path
fill=
"url(#XED_QU6xiox5XDw0HU_eba)"
d=
"M12,41.5c0-1.381,1.119-2.5,2.5-2.5c0.156,0,0.307,0.019,0.454,0.046l1.186-1.186 C16.058,37.586,16,37.301,16,37c0-1.657,1.343-3,3-3c0.301,0,0.586,0.058,0.86,0.14L24,30l-6-6L4.586,37.414 C4.211,37.789,4,38.298,4,38.828v1.343c0,0.53,0.211,1.039,0.586,1.414l1.828,1.828C6.789,43.789,7.298,44,7.828,44h1.343 c0.53,0,1.039-0.211,1.414-0.586l1.46-1.46C12.019,41.807,12,41.656,12,41.5z"
/><linearGradient
id=
"XED_QU6xiox5XDw0HU_ebb"
x1=
"21.64"
x2=
"36.971"
y1=
"7.073"
y2=
"29.362"
gradientUnits=
"userSpaceOnUse"
><stop
offset=
"0"
stop-color=
"#fede00"
/><stop
offset=
"1"
stop-color=
"#ffd000"
/></linearGradient><path
fill=
"url(#XED_QU6xiox5XDw0HU_ebb)"
d=
"M29.5,5C22.044,5,16,11.044,16,18.5S22.044,32,29.5,32S43,25.956,43,18.5S36.956,5,29.5,5z M33,19c-2.209,0-4-1.791-4-4s1.791-4,4-4s4,1.791,4,4S35.209,19,33,19z"
/></svg>
\ No newline at end of file
ux/public/_assets/icons/fluent-unavailable.svg
0 → 100644
View file @
7fe7fbb3
<svg
xmlns=
"http://www.w3.org/2000/svg"
viewBox=
"0 0 48 48"
width=
"96px"
height=
"96px"
><linearGradient
id=
"GCWVriy4rQhfclYQVzRmda"
x1=
"9.812"
x2=
"38.361"
y1=
"9.812"
y2=
"38.361"
gradientUnits=
"userSpaceOnUse"
><stop
offset=
"0"
stop-color=
"#f44f5a"
/><stop
offset=
".443"
stop-color=
"#ee3d4a"
/><stop
offset=
"1"
stop-color=
"#e52030"
/></linearGradient><path
fill=
"url(#GCWVriy4rQhfclYQVzRmda)"
d=
"M24,4C12.955,4,4,12.955,4,24s8.955,20,20,20s20-8.955,20-20C44,12.955,35.045,4,24,4z M24,38 c-7.732,0-14-6.268-14-14s6.268-14,14-14s14,6.268,14,14S31.732,38,24,38z"
/><linearGradient
id=
"GCWVriy4rQhfclYQVzRmdb"
x1=
"6.821"
x2=
"41.08"
y1=
"6.321"
y2=
"40.58"
gradientTransform=
"translate(-.146 .354)"
gradientUnits=
"userSpaceOnUse"
><stop
offset=
"0"
stop-color=
"#f44f5a"
/><stop
offset=
".443"
stop-color=
"#ee3d4a"
/><stop
offset=
"1"
stop-color=
"#e52030"
/></linearGradient><polygon
fill=
"url(#GCWVriy4rQhfclYQVzRmdb)"
points=
"13.371,38.871 9.129,34.629 34.629,9.129 38.871,13.371"
/></svg>
\ No newline at end of file
ux/public/_assets/icons/ultraviolet-binary-file.svg
0 → 100644
View file @
7fe7fbb3
<svg
xmlns=
"http://www.w3.org/2000/svg"
viewBox=
"0 0 40 40"
width=
"80px"
height=
"80px"
><path
fill=
"#fff"
d=
"M6.5 37.5L6.5 2.5 24.793 2.5 33.5 11.207 33.5 37.5z"
/><path
fill=
"#4788c7"
d=
"M24.586,3L33,11.414V37H7V3H24.586 M25,2H6v36h28V11L25,2L25,2z"
/><path
fill=
"#dff0fe"
d=
"M24.5 11.5L24.5 2.5 24.793 2.5 33.5 11.207 33.5 11.5z"
/><path
fill=
"#4788c7"
d=
"M25,3.414L32.586,11H25V3.414 M25,2h-1v10h10v-1L25,2L25,2z"
/><path
fill=
"none"
stroke=
"#4788c7"
stroke-miterlimit=
"10"
d=
"M13.5 18.5L14.5 18.5 14.5 23M19.5 22.5L19.5 22.5c-.552 0-1-.448-1-1v-2c0-.552.448-1 1-1h0c.552 0 1 .448 1 1v2C20.5 22.052 20.052 22.5 19.5 22.5zM25.5 22.5L25.5 22.5c-.552 0-1-.448-1-1v-2c0-.552.448-1 1-1h0c.552 0 1 .448 1 1v2C26.5 22.052 26.052 22.5 25.5 22.5zM25.5 25.5L26.5 25.5 26.5 30M20.5 29.5L20.5 29.5c-.552 0-1-.448-1-1v-2c0-.552.448-1 1-1h0c.552 0 1 .448 1 1v2C21.5 29.052 21.052 29.5 20.5 29.5zM14.5 29.5L14.5 29.5c-.552 0-1-.448-1-1v-2c0-.552.448-1 1-1h0c.552 0 1 .448 1 1v2C15.5 29.052 15.052 29.5 14.5 29.5z"
/></svg>
\ No newline at end of file
ux/public/_assets/icons/ultraviolet-schedule.svg
0 → 100644
View file @
7fe7fbb3
<svg
xmlns=
"http://www.w3.org/2000/svg"
viewBox=
"0 0 40 40"
width=
"80px"
height=
"80px"
><path
fill=
"#fff"
d=
"M2.5,37.5V8.985C2.5,5.409,5.409,2.5,8.985,2.5H37.5v35H2.5z"
/><path
fill=
"#4788c7"
d=
"M37,3v34H3V8.985C3,5.685,5.685,3,8.985,3H37 M38,2H8.985C5.127,2,2,5.127,2,8.985V38h36V2L38,2z"
/><path
fill=
"#b6dcfe"
d=
"M2.522,7.5c0.253-2.8,2.613-5,5.478-5h29.5v5H2.522z"
/><path
fill=
"#4788c7"
d=
"M37,3v4H3.1C3.565,4.721,5.585,3,8,3H37 M38,2H8C4.686,2,2,4.686,2,8h36V2L38,2z"
/><path
fill=
"#b6dcfe"
d=
"M13 14H15V16H13zM21 14H23V16H21zM25 14H27V16H25zM29 14H31V16H29zM9 18H11V20H9zM13 18H15V20H13zM21 18H23V20H21zM25 18H27V20H25zM29 18H31V20H29zM9 26H11V28H9zM13 26H15V28H13zM21 26H23V28H21zM17 14H19V16H17zM17 18H19V20H17zM9 22H11V24H9zM13 22H15V24H13zM21 22H23V24H21zM25 22H27V24H25zM29 22H31V24H29zM17 22H19V24H17zM17 26H19V28H17zM25 26H27V28H25zM3 34H37V37H3z"
/><path
fill=
"#98ccfd"
d=
"M12,23.5C5.659,23.5,0.5,18.341,0.5,12S5.659,0.5,12,0.5S23.5,5.659,23.5,12S18.341,23.5,12,23.5z"
/><path
fill=
"#4788c7"
d=
"M12,1c6.065,0,11,4.935,11,11s-4.935,11-11,11S1,18.065,1,12S5.935,1,12,1 M12,0 C5.373,0,0,5.373,0,12s5.373,12,12,12s12-5.373,12-12S18.627,0,12,0L12,0z"
/><g><path
fill=
"#fff"
d=
"M12 3A9 9 0 1 0 12 21A9 9 0 1 0 12 3Z"
/></g><path
fill=
"none"
stroke=
"#4788c7"
stroke-linecap=
"round"
stroke-miterlimit=
"10"
d=
"M14.5 5.5L12 12 15.5 15.5"
/><g><path
fill=
"#4788c7"
d=
"M12 10.667A1.333 1.333 0 1 0 12 13.333A1.333 1.333 0 1 0 12 10.667Z"
/></g></svg>
\ No newline at end of file
ux/public/_assets/illustrations/undraw_going_up.svg
0 → 100644
View file @
7fe7fbb3
<svg
xmlns=
"http://www.w3.org/2000/svg"
data-name=
"Layer 1"
width=
"667.44532"
height=
"589.48587"
viewBox=
"0 0 667.44532 589.48587"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
><path
d=
"M783.23262,532.89214a7.72132,7.72132,0,0,1,4.04472-11.12741l-.39756-27.43609,12.016,7.67645L797.4311,526.882a7.76317,7.76317,0,0,1-14.19848,6.01015Z"
transform=
"translate(-266.27734 -155.25706)"
fill=
"#a0616a"
/><path
d=
"M768.75126,383.9362A15.63963,15.63963,0,0,0,755.837,398.99425c-.174,8.02961,2.50557,11.02363,6.29215,12.10551,7,2,18.14816,42.44832,18.14816,42.44832s1.18325,37.72571,3.09163,35.86286-.25137,2.4842.3285,3.81067-2.74888,3.313.4155,4.81973,1.16437,13.50674,1.16437,13.50674l14-1s-2.32454-9.77573.83773-10.38786,1.72534-3.39426.44381-5.5032,2.26732-5.11484.49289-6.11189,3.22557-39.997,3.22557-39.997L784.7285,391.02842a15.64187,15.64187,0,0,0-15.97722-7.09223Z"
transform=
"translate(-266.27734 -155.25706)"
fill=
"#1976d2"
/><polygon
points=
"460 230.943 470.071 213.291 483.677 213.291 493.882 231.943 460 230.943"
fill=
"#1976d2"
/><path
d=
"M699.18878,227.46306c-8.04694-26.95441-30.7807-44.551-58.25122-48.41126-.30219-.0426-.589.01367-.8899-.00574a8.68011,8.68011,0,0,0-1.18756-.27349c-37.778-4.88251-79.0177,3.86193-111.84076,24.3988-31.46228,19.68549-67.61309,30.793-104.72552,30.5462q-1.72879-.01145-3.47113.075c-28.56079,1.42511-53.76636,22.21533-61.48755,49.5606-1.01331,3.58777.75244,6.79352,3.59186,8.82673,4.98932,3.57348,8.3974,6.078,14.53607,7.37841q16.43014,3.48075,32.9726,6.40137V262.03075a15.70447,15.70447,0,0,1,15.68627-15.68628H639.59106a15.70448,15.70448,0,0,1,15.68628,15.68628V316.738a64.51829,64.51829,0,0,0,8.63245-3.39789,66.83714,66.83714,0,0,0,25.76849-22.487C702.15289,272.75279,705.44769,248.42662,699.18878,227.46306Z"
transform=
"translate(-266.27734 -155.25706)"
fill=
"#f2f2f2"
/><path
d=
"M608.4671,484.54808H417.99a16.59835,16.59835,0,0,1-16.57911-16.5791V394.05852a172.96506,172.96506,0,0,0-71.7163-6.286,8.68011,8.68011,0,0,0-1.18756.27349c-.30085.01941-.58771-.03686-.8899.00574-27.47052,3.86029-50.20428,21.45685-58.25122,48.41126-6.25891,20.96356-2.96411,45.28973,9.5105,63.39a66.83714,66.83714,0,0,0,25.76849,22.487c14.28736,6.88226,29.32532,7.39972,44.91919,7.88568a1018.27653,1018.27653,0,0,0,140.261-5.30163q34.38208-3.68766,68.47858-9.63837,17.4516-3.0541,34.788-6.72742c6.13867-1.30041,9.54675-3.80493,14.53607-7.37841,2.83942-2.03321,4.60517-5.239,3.59186-8.82673A65.80907,65.80907,0,0,0,608.4671,484.54808Z"
transform=
"translate(-266.27734 -155.25706)"
fill=
"#f2f2f2"
/><path
d=
"M625.32431,462.62108H438.38871a13.62481,13.62481,0,0,1-13.609-13.609V275.28913a13.62481,13.62481,0,0,1,13.609-13.609h186.9356a13.6248,13.6248,0,0,1,13.609,13.609V449.01205A13.6248,13.6248,0,0,1,625.32431,462.62108Z"
transform=
"translate(-266.27734 -155.25706)"
fill=
"#e6e6e6"
/><path
d=
"M585.97983,453.4416H447.57038a13.62481,13.62481,0,0,1-13.609-13.609V284.47592a13.62481,13.62481,0,0,1,13.609-13.609H616.14483a13.62481,13.62481,0,0,1,13.609,13.609V409.66757A43.82338,43.82338,0,0,1,585.97983,453.4416Z"
transform=
"translate(-266.27734 -155.25706)"
fill=
"#fff"
/><circle
cx=
"265.58027"
cy=
"206.89718"
r=
"61"
fill=
"#1976d2"
/><path
d=
"M557.5542,359.08519l-20.356-24.75391a6.00075,6.00075,0,0,0-9.14014-.15136l-21.76855,24.7539a6.00029,6.00029,0,0,0,9.01172,7.92481L526.564,354.05119v32.115a6,6,0,0,0,12,0V354.8853l9.72168,11.822a6,6,0,0,0,9.26856-7.62207Z"
transform=
"translate(-266.27734 -155.25706)"
fill=
"#fff"
/><polygon
points=
"528.453 578.324 519.404 578.323 515.099 543.416 528.456 543.417 528.453 578.324"
fill=
"#a0616a"
/><path
d=
"M795.04973,743.0215l-27.82942-.001v-.35195a10.83258,10.83258,0,0,1,10.832-10.83181h.00067l5.0834-3.85654,9.4845,3.85712,2.42932.00009Z"
transform=
"translate(-266.27734 -155.25706)"
fill=
"#2f2e41"
/><polygon
points=
"460.453 578.324 451.404 578.323 447.099 543.416 460.456 543.417 460.453 578.324"
fill=
"#a0616a"
/><path
d=
"M727.04973,743.0215l-27.82942-.001v-.35195a10.83258,10.83258,0,0,1,10.832-10.83181h.00067l5.0834-3.85654,9.4845,3.85712,2.42932.00009Z"
transform=
"translate(-266.27734 -155.25706)"
fill=
"#2f2e41"
/><path
d=
"M797.61645,704.6906c3.30164-2.1576,1.38892-2.01752,1.38892-2.01752s-7.383-59.85993-13-78l-6.49994-88.33655s-.41266,1.76215,0-2.52069,3.41266-1.28284.41266-4.28284-5-4.52868-3-6.76434,7.51721-6.75861,4.2586-9.49713-9.67126-20.59845-9.67126-20.59845l-62.50006.5,2.5-.5s-7.80182-2.89459-4.228.875-2,13-4,22c-1.65643,7.454-6.57379,9.43207,0,11,6.57379,1.56787.62476,6.01092.62476,6.01092s-9.89673,47.11408-2.39673,78.11408c0,0,5.17413,76.67175,7.79339,83.26587,2.61933,6.59405,3.61933,2.59405,2.61933,6.59405s-3-3-1,4a92.51269,92.51269,0,0,1,2.58728,11.14008l13.56231-1s3.1496-9.92743,0-12.53375-.97491,5,2.43775-.80316-.58734-3.80317-1.58734-11.80317,8.17468-45.2677,1.58734-68.13385l12.17328-64.16278,19.32666,66.43671s10.25128,81.14014,13.582,84.00006c3.33069,2.85986,1.9856-4.08209,3.33069,2.85986,1.35925,7.01508,4.44653,5.15515,4.35925,6.01508-.93127,9.17242,15.33911.125,15.33911.125a51.36513,51.36513,0,0,1,0-6.99994C797.91809,707.533,794.31482,706.84813,797.61645,704.6906Z"
transform=
"translate(-266.27734 -155.25706)"
fill=
"#2f2e41"
/><path
d=
"M715.27734,513.54808c-4,0-15-5.41732-13-7.70866s2-9.89764,2-12.09449,9-83.19685,9-83.19685l-.68388-19.83247a8.86212,8.86212,0,0,1,8.85686-9.16753l8.827-3,25-1,12.46645,4A7.22686,7.22686,0,0,1,774.181,392.0598l0,0a65.07422,65.07422,0,0,1,9.55278,35.95453c-.28682,9.47129-5.08528,21.038-6.24161,31.73814-.1015.93921-.17494,1.87174-.2148,2.79559-.01112.25761-2.05815,1.54144-.02907.77072s-1.08747,1.94967-.0292,3.58947,3.10929.635.08378,2.63741,3.63258,21.34431,2.97449,22.0024c-2,2-6,3-3,6s6,1,2,5-15.98425,11-15.98425,11Z"
transform=
"translate(-266.27734 -155.25706)"
fill=
"#3f3d56"
/><circle
cx=
"475.73406"
cy=
"189.15557"
r=
"21.52319"
fill=
"#a0616a"
/><path
d=
"M610.92115,411.192a7.72133,7.72133,0,0,1,10.62241,5.2291l27.317,2.584-8.93584,11.11135L615.354,425.9591a7.76317,7.76317,0,0,1-4.43284-14.76715Z"
transform=
"translate(-266.27734 -155.25706)"
fill=
"#a0616a"
/><path
d=
"M740.44091,395.17016a15.63965,15.63965,0,0,0-15.058-12.91423c-8.02961-.174-11.02364,2.50557-12.10552,6.29215-2,7-34.19685,31.60617-34.19685,31.60617l-27.65117-2.99243c-1.66278-.54016-.87427-2.05438-7.12586-.77115-3.07953-2.01669-5.07055-1.675-6.785-.73428l-10.24109-1.10831,1,16s10.96343-2.608,13,2,1.57046,5.26992,6,2,4,0,4,0l32,8,50.07135-31.40068a15.64187,15.64187,0,0,0,7.09222-15.97722Z"
transform=
"translate(-266.27734 -155.25706)"
fill=
"#1976d2"
/><path
d=
"M750.36737,363.628l1.41.45c-4.41.37-12.27,2.83-11.5,1.47s-2.14-6.49-.72-7.14a9.03069,9.03069,0,0,0,3.82-2.59c.9-1.26.88-3.34-.47-4.11-1.31-.76-2.93.06-4.23.83-1.31.76-3.73-10.42-3.11-13.91-3.65-2-8.07,1.83-12.17,1.08-2.51-.46-4.32-2.52-5.46-4.86a15.246,15.246,0,0,0,4.03-6.42,19.90965,19.90965,0,0,1-5.52,1.83,12.97091,12.97091,0,0,1,.14-5.48,8.94283,8.94283,0,0,1,5.57-6.34,6.48235,6.48235,0,0,1,7.6,2.82,6.44436,6.44436,0,0,0-4.08-6.4,6.77636,6.77636,0,0,1,9.75,4.61,20.93429,20.93429,0,0,1,14.59-1.56c4.84,1.27,11.26,6.64,11.26,6.64C772.19732,326.95805,771.67736,368.47807,750.36737,363.628Z"
transform=
"translate(-266.27734 -155.25706)"
fill=
"#2f2e41"
/><path
d=
"M864.39375,734.43979a1.2164,1.2164,0,0,0,.88157-2.10832l-.08335-.33136.03312-.07954a3.26656,3.26656,0,0,1,6.02555.02239c.98551,2.37356,2.24023,4.75117,2.54918,7.26082a9.66393,9.66393,0,0,1-.16964,3.32354,38.74392,38.74392,0,0,0,3.52438-16.09157,37.39746,37.39746,0,0,0-.232-4.17178q-.19217-1.70334-.53318-3.38243a39.19285,39.19285,0,0,0-7.77228-16.61089A10.43034,10.43034,0,0,1,864.2792,697.77a7.95618,7.95618,0,0,1-.72357-2.17417,9.819,9.819,0,0,0,.637-3.3859c.2943-.44659.82105-.66859,1.14248-1.10437,1.59857-2.16733,3.801-1.78891,4.95074,1.15632,2.45615,1.23962,2.47993,3.29545.97284,5.27269-.95881,1.25793-1.09055,2.96-1.93184,4.30676.08657.1108.17659.21813.26313.32893a39.4457,39.4457,0,0,1,4.11715,6.52255,16.39818,16.39818,0,0,1,.979-7.61655c.93706-2.26054,2.69343-4.16438,4.24012-6.11862a3.36576,3.36576,0,0,1,5.9948,1.65271l.00927.0864q-.3446.1944-.67464.41269a1.65,1.65,0,0,0,.66523,3.00262l.03364.00518a16.41807,16.41807,0,0,1-.43274,2.45462c1.98421,7.67347-2.29957,10.46831-8.41623,10.59386-.135.06923-.2666.13847-.40163.20427a40.262,40.262,0,0,1,2.16725,10.19917,38.18677,38.18677,0,0,1-.0277,6.1659l.0104-.07269a10.09082,10.09082,0,0,1,3.44475-5.82663c2.65092-2.17763,6.39617-2.97954,9.256-4.72993a1.89376,1.89376,0,0,1,2.90049,1.84233l-.01169.07644a11.08173,11.08173,0,0,0-1.24287.5989q-.3446.19445-.67465.41269a1.65,1.65,0,0,0,.66524,3.00265l.03367.00517.0692.01042a16.43116,16.43116,0,0,1-3.02234,4.73259c-1.24068,6.69864-6.56941,7.3342-12.2695,5.38348h-.00347a40.251,40.251,0,0,1-2.70387,7.89347h-9.65909c-.03464-.10732-.06579-.21812-.097-.32545a10.97506,10.97506,0,0,0,2.67273-.15921c-.71666-.87938-1.43329-1.76569-2.14994-2.645a.60206.60206,0,0,1-.045-.05194c-.36351-.45-.73049-.89666-1.094-1.34671l-.0002-.00055a16.07543,16.07543,0,0,1,.471-4.09507Z"
transform=
"translate(-266.27734 -155.25706)"
fill=
"#f2f2f2"
/><path
d=
"M542.80633,744.4356l389.72565.30734a1.19068,1.19068,0,0,0,0-2.38137l-389.72565-.30733a1.19068,1.19068,0,0,0,0,2.38136Z"
transform=
"translate(-266.27734 -155.25706)"
fill=
"#cacaca"
/><path
d=
"M522.8955,577.54808A14.14551,14.14551,0,1,1,537.041,563.40257,14.16159,14.16159,0,0,1,522.8955,577.54808Zm0-26.291A12.14551,12.14551,0,1,0,535.041,563.40257,12.159,12.159,0,0,0,522.8955,551.25706Z"
transform=
"translate(-266.27734 -155.25706)"
fill=
"#f2f2f2"
/><path
d=
"M528.43314,562.741l-4.38677-5.33454a1.29319,1.29319,0,0,0-1.96972-.03262l-4.69119,5.33454a1.29308,1.29308,0,0,0,1.942,1.70782l2.42714-2.76v6.92088a1.293,1.293,0,1,0,2.586,0v-6.74113l2.09505,2.54767a1.293,1.293,0,0,0,1.9974-1.64258Z"
transform=
"translate(-266.27734 -155.25706)"
fill=
"#f2f2f2"
/><path
d=
"M683.8955,368.54808A14.14551,14.14551,0,1,1,698.041,354.40257,14.16159,14.16159,0,0,1,683.8955,368.54808Zm0-26.291A12.14551,12.14551,0,1,0,696.041,354.40257,12.159,12.159,0,0,0,683.8955,342.25706Z"
transform=
"translate(-266.27734 -155.25706)"
fill=
"#f2f2f2"
/><path
d=
"M689.43314,353.741l-4.38677-5.33454a1.29319,1.29319,0,0,0-1.96972-.03262l-4.69119,5.33454a1.29308,1.29308,0,0,0,1.942,1.70782l2.42714-2.76v6.92088a1.293,1.293,0,1,0,2.586,0v-6.74113l2.09505,2.54767a1.293,1.293,0,0,0,1.9974-1.64258Z"
transform=
"translate(-266.27734 -155.25706)"
fill=
"#f2f2f2"
/><path
d=
"M364.8955,356.54808A14.14551,14.14551,0,1,1,379.041,342.40257,14.16159,14.16159,0,0,1,364.8955,356.54808Zm0-26.291A12.14551,12.14551,0,1,0,377.041,342.40257,12.159,12.159,0,0,0,364.8955,330.25706Z"
transform=
"translate(-266.27734 -155.25706)"
fill=
"#f2f2f2"
/><path
d=
"M370.43314,341.741l-4.38677-5.33454a1.29319,1.29319,0,0,0-1.96972-.03262l-4.69119,5.33454a1.29308,1.29308,0,0,0,1.942,1.70782l2.42714-2.76v6.92088a1.293,1.293,0,0,0,2.586,0v-6.74113l2.09505,2.54767a1.293,1.293,0,0,0,1.9974-1.64258Z"
transform=
"translate(-266.27734 -155.25706)"
fill=
"#f2f2f2"
/><path
d=
"M477.8955,183.54808A14.14551,14.14551,0,1,1,492.041,169.40257,14.16159,14.16159,0,0,1,477.8955,183.54808Zm0-26.291A12.14551,12.14551,0,1,0,490.041,169.40257,12.159,12.159,0,0,0,477.8955,157.25706Z"
transform=
"translate(-266.27734 -155.25706)"
fill=
"#f2f2f2"
/><path
d=
"M483.43314,168.741l-4.38677-5.33454a1.29319,1.29319,0,0,0-1.96972-.03262l-4.69119,5.33454a1.29308,1.29308,0,0,0,1.942,1.70782l2.42714-2.76v6.92088a1.293,1.293,0,0,0,2.586,0v-6.74113l2.09505,2.54767a1.293,1.293,0,0,0,1.9974-1.64258Z"
transform=
"translate(-266.27734 -155.25706)"
fill=
"#f2f2f2"
/><path
d=
"M326.8955,461.54808A14.14575,14.14575,0,1,1,341.041,447.40257,14.16159,14.16159,0,0,1,326.8955,461.54808Zm0-26.2915a12.14575,12.14575,0,1,0,12.14551,12.146A12.15941,12.15941,0,0,0,326.8955,435.25658Z"
transform=
"translate(-266.27734 -155.25706)"
fill=
"#fff"
/><path
d=
"M332.43314,446.741l-4.38677-5.33454a1.29319,1.29319,0,0,0-1.96972-.03262l-4.69119,5.33454a1.29308,1.29308,0,0,0,1.942,1.70782l2.42714-2.76v6.92088a1.293,1.293,0,0,0,2.586,0v-6.74113l2.09505,2.54767a1.293,1.293,0,0,0,1.9974-1.64258Z"
transform=
"translate(-266.27734 -155.25706)"
fill=
"#fff"
/><path
d=
"M632.8955,224.54808A14.14575,14.14575,0,1,1,647.041,210.40257,14.16159,14.16159,0,0,1,632.8955,224.54808Zm0-26.2915a12.14575,12.14575,0,1,0,12.14551,12.146A12.15941,12.15941,0,0,0,632.8955,198.25658Z"
transform=
"translate(-266.27734 -155.25706)"
fill=
"#fff"
/><path
d=
"M638.43314,209.741l-4.38677-5.33454a1.29319,1.29319,0,0,0-1.96972-.03262l-4.69119,5.33454a1.29308,1.29308,0,0,0,1.942,1.70782l2.42714-2.76v6.92088a1.293,1.293,0,1,0,2.586,0v-6.74113l2.09505,2.54767a1.293,1.293,0,0,0,1.9974-1.64258Z"
transform=
"translate(-266.27734 -155.25706)"
fill=
"#fff"
/></svg>
\ No newline at end of file
ux/public/_assets/illustrations/undraw_icon_design.svg
0 → 100644
View file @
7fe7fbb3
<svg
xmlns=
"http://www.w3.org/2000/svg"
width=
"445.34356"
height=
"581.89215"
viewBox=
"0 0 445.34356 581.89215"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
><g><g><polygon
points=
"128.92467 552.93374 138.51901 555.79104 154.10605 520.14411 139.9457 515.927 128.92467 552.93374"
fill=
"#a0616a"
/><path
d=
"M140.8288,550.50975l-.00948-.0032-10.43597-2.44529-.00948-.0032-2.41704-.56239-8.30729,21.23876-.44694,1.13674,6.81666,2.03656,.56063-1.09837,2.56737-4.98059,.97997,6.0405,.21014,1.31629,18.06517,5.38934c1.074,.32018,2.18446,.18836,3.11913-.29834,1.0011-.49591,1.80138-1.39733,2.14092-2.55981,1.8212-3.33262-10.90289-15.51054-12.20874-18.11479l1.94052-6.50076-2.56557-.59145Z"
fill=
"#2f2e41"
/></g><path
d=
"M190.38148,436.50921l-1.11692,2.88136-3.2501,8.36326-34.86355,89.0697-24.50891-6.02604c4.61286-33.65321,7.87162-54.49264,19.51731-72.39887,3.22505-4.96212,7.10411-9.70346,11.8281-14.43122,0,0-18.60782-.05679-40.46153-.50324-1.91794-.04031-3.86751-.07977-5.83331-.1347-18.09197-.42404-37.43081-1.12036-49.85358-2.27547-7.55893-.70184-12.77747-4.31265-16.19828-9.39219-9.79061-14.46282-5.12804-40.86067,.92335-45.88758l40.90617-16.26706,16.4964,29.65811,1.72604,3.09769,61.44197,4.30703c8.96469,.62842,16.58175,6.79079,19.06825,15.42664l4.17858,14.51258Z"
fill=
"#2f2e41"
/><path
d=
"M27.34356,0l-3,491,421-73V0H27.34356ZM96.67706,416H29.34356v-67.33301H96.67706v67.33301Zm0-69.33301H29.34356v-67.33398H96.67706v67.33398Zm0-69.33398H29.34356v-67.33301H96.67706v67.33301Zm0-69.33301H29.34356v-67.3335H96.67706v67.3335Zm0-69.3335H29.34356V71.3335H96.67706v67.33301Zm0-69.33301H29.34356v-.00007C29.34356,32.1462,59.48977,2,96.67699,2h.00007V69.3335Zm69.33301,346.6665H98.67706v-67.33301h67.33301v67.33301Zm0-69.33301H98.67706v-67.33398h67.33301v67.33398Zm0-69.33398H98.67706v-67.33301h67.33301v67.33301Zm0-69.33301H98.67706v-67.3335h67.33301v67.3335Zm0-69.3335H98.67706v-.00007c0-37.18696,30.14598-67.33294,67.33294-67.33294h.00007v67.33301Zm0-69.33301H98.67706V2h67.33301V69.3335Zm69.3335,346.6665h-67.3335v-67.33301h67.3335v67.33301Zm0-69.33301h-67.3335v-67.33398h67.3335v67.33398Zm0-69.33398h-67.3335v-67.33301h67.3335v67.33301Zm0-69.33301h-67.3335v-67.3335h67.3335v67.3335Zm0-69.3335h-67.3335V71.3335h67.3335v67.33301Zm0-69.33301h-67.3335V2h67.3335V69.3335Zm69.3335,346.6665h-67.3335v-67.33301h67.3335v67.33301Zm0-69.33301h-67.3335v-67.33398h67.3335v67.33398Zm0-69.33398h-67.3335v-67.33301h67.3335v67.33301Zm0-69.33301h-67.3335v-67.3335h67.3335v67.3335Zm0-69.3335h-67.3335V71.3335h67.3335v67.33301Zm0-69.33301h-67.3335V2h67.3335V69.3335Zm69.33301,346.6665h-.00007c-37.18696,0-67.33294-30.14598-67.33294-67.33294v-.00007h67.33301v67.33301Zm0-69.33301h-67.33301v-67.33398h67.33301v67.33398Zm0-69.33398h-67.33301v-67.33301h67.33301v67.33301Zm0-69.33301h-67.33301v-67.3335h67.33301v67.3335Zm0-69.3335h-67.33301V71.3335h67.33301v67.33301Zm0-69.33301h-67.33301V2h67.33301V69.3335Zm2.00056,346.6665h-.00056v-67.33301h67.3335v.00007c0,37.18696-30.14598,67.33294-67.33294,67.33294Zm67.33294-69.33301h-67.3335v-67.33398h67.3335v67.33398Zm0-69.33398h-67.3335v-67.33301h67.3335v67.33301Zm0-69.33301h-67.3335v-67.3335h67.3335v67.3335Zm0-69.3335h-67.3335v-.00007c0-37.18696,30.14598-67.33294,67.33294-67.33294h.00056v67.33301Zm0-69.33301h-67.3335V2h67.3335V69.3335Z"
fill=
"#f2f2f2"
/><g><path
d=
"M143.7444,210.76081l-8.21832,22.88252-13.72683-2.87098,9.54972-23.88366c-.26444-.73975-.42738-1.52969-.46665-2.35514-.21357-4.48952,3.25279-8.30215,7.74231-8.51572,4.48952-.21357,8.30215,3.25279,8.51572,7.74231,.1362,2.86317-1.22794,5.44608-3.39596,7.00067Z"
fill=
"#a0616a"
/><path
d=
"M145.10987,216.968l-18.60773,50.03919-2.68918,7.22055c-2.42809,6.53008-9.11185,10.43936-16.00056,9.36736l-43.2153-6.75236-3.19397-19.81033,46.61723,4.10299,7.79503-20.44702,10.34248-27.14067,2.35996,.42301,13.21703,2.38503,3.375,.61223Z"
fill=
"#1976d2"
/></g><g><polygon
points=
"64.23966 550.32766 72.28542 556.28428 99.08998 528.08542 87.21519 519.29401 64.23966 550.32766"
fill=
"#a0616a"
/><path
d=
"M74.42615,558.9911l4.03844-5.4543-2.21077-1.43683-8.98752-5.86479-2.08328-1.35297-15.04861,17.1392-.80671,.9189,5.71269,4.22975,.9037-.83655,4.10272-3.80625-1.13075,6.00673-.2508,1.31996,15.14552,11.21394c.90448,.66969,1.98926,.92533,3.02758,.78863,1.11791-.13048,2.17554-.70563,2.89561-1.67815,2.84985-2.51225-4.96672-18.29191-5.30781-21.18729Z"
fill=
"#2f2e41"
/></g><path
d=
"M237.34356,348c-76.09326,0-138-61.90625-138-138S161.2503,72,237.34356,72s138,61.90674,138,138-61.90674,138-138,138Zm0-274c-74.99072,0-100,58.00928-100,133s25.00928,139,100,139,136-61.00977,136-136-61.00928-136-136-136Z"
fill=
"#3f3d56"
/><path
d=
"M302.72351,204.42767l-61.15649-61.15649c-.17749-.23376-.36621-.46167-.57953-.67499-1.28137-1.28137-2.96454-1.91388-4.64392-1.90161-1.67938-.01227-3.36255,.62024-4.64392,1.90161-.21332,.21332-.40204,.44122-.57953,.67499l-61.15649,61.15649c-2.53839,2.53839-2.53839,6.65393,0,9.19238,2.53839,2.53839,6.65399,2.53839,9.19238,0l50.68756-50.68756v107.5675c0,3.58984,2.91016,6.5,6.5,6.5s6.5-2.91016,6.5-6.5v-107.5675l50.68756,50.68756c2.53839,2.53839,6.65399,2.53839,9.19238,0,2.53839-2.53845,2.53839-6.65399,0-9.19238Z"
fill=
"#1976d2"
/><polygon
points=
"78.34356 342 88.20183 374.1502 43.34356 379 59.34356 338 78.34356 342"
fill=
"#a0616a"
/><path
d=
"M162.34356,466l-2.03003,2.32996-5.89996,6.76001-63.07001,71.91003-21-14c15.78003-30.08002,25.92999-48.57001,42.96997-61.45001,4.72003-3.57001,9.98004-6.71002,16.03003-9.54999,0,0-17.47998-6.38-37.88-14.23004-1.78998-.69-3.60999-1.38995-5.44-2.10999-16.87-6.54999-34.82001-13.77997-46.10999-19.08997-6.87-3.23004-10.54999-8.40002-12.03998-14.34003-4.29004-16.92999,9.06995-40.16998,16.46997-42.83997l44-1.39001,5.42999,33.5,.57001,3.5s16.12,7.78998,33.03998,15.57996c2.54004,1.16003,5.09003,2.33002,7.61005,3.47003,4,1.79999,7.89996,3.53998,11.51996,5.10999,.0827,.0359,.16553,.07177,.24848,.1076,10.49055,4.53143,17.02074,15.14447,16.2606,26.54657l-.67906,10.18587Z"
fill=
"#2f2e41"
/><path
d=
"M89.32354,317.12c-1.07001,7.64001-1.32001,14.85999,.02002,18.88,.35629,1.06887,5.69178,8.88274,6,10,2.75418,9.98352-9,12-9,12l-45.09302,14.9706c-2.5966,.86206-4.78235-2.14578-3.12334-4.32137,3.69858-4.85026,7.07707-11.85798,6.83635-21.13922-.37512-14.46322-6.77592-37.46541-10.31388-49.1613-1.4559-4.81296-1.10486-9.98511,.98004-14.56086l5.03386-11.04787,7.32001-16.04999,2.35999-11.69,21,1,2.59003,9.51001,19.53998,29.82996c.78998,1.21002,1.31,2.56,1.53998,3.95001,.31,1.73999,.16003,3.56-.45001,5.27002-2.02997,5.69-4.09998,14.35999-5.23999,22.56Z"
fill=
"#1976d2"
/><g><path
d=
"M211.82763,280.34608l-23.93249,4.28793-4.35699-13.32985,25.46422-3.63317c.50933-.59812,1.11277-1.13329,1.80867-1.57897,3.78491-2.42402,8.81827-1.32079,11.24229,2.46412,2.42402,3.78491,1.32079,8.81827-2.46412,11.24229-2.4138,1.5459-5.33291,1.65158-7.76158,.54765Z"
fill=
"#a0616a"
/><path
d=
"M51.52867,280.18309l3.03433,3.25994c7.35817,7.90527,17.443,12.72244,28.21635,13.47794l40.24253,2.82209,74.74517-14.05192-4.55133-17.86856-70.65911,12.17742-71.02793,.18309Z"
fill=
"#1976d2"
/></g></g><g><path
d=
"M.00957,228.79794c-.2166,9.32008,3.26648,18.34462,8.27021,26.27122,1.4867-4.62743,4.15943-8.83902,6.94682-12.85381-1.45518,8.60015,.13811,17.65509,4.2583,25.34008,.15437,.10796,.29947,.20475,.45585,.29233,4.07857,2.4534,9.24943,3.44712,13.66155,1.67514-9.11615-9.82665-10.2763-26.10791-2.6334-37.13004,2.16385-3.12756,4.96233-5.89365,6.30257-9.45289,2.11609-5.67895,.08194-11.93163-1.20127-17.85254-1.19989-5.51058-1.40992-12.06821,2.28708-16.10676-.7592-1.08524-2.20101-1.8355-3.56069-1.63943-2.27941,.32199-3.93858,2.30324-4.99531,4.34381-1.05672,2.04051-1.75366,4.30209-3.22635,6.06458-2.72722,3.29889-7.37161,4.07886-11.28556,5.81745C5.81066,207.78906,.23679,218.42727,.00957,228.79794Z"
fill=
"#2f2e41"
/><path
d=
"M79.79675,223.46911c-.54166-1.89581,3.19176,9.69287,1.39023,9.90208-8.20531,.94132-19.46907,5.84176-25.184,8.12793-.25738-.02991-.51476-.05978-.76452-.09713-.61312-.06726-1.21114-.16439-1.80153-.27643-13.30712-2.51777-18.42436-22.95907-18.42436-23.14584,0-.91893,2.2055-26.15831,5.67986-26.53186,.90077-.09713,1.81669-.14943,2.74772-.14943h8.62162c1.8318-.38851,3.64848-.65746,5.41213-.78446h.01515c17.35676-1.3224,31.04235,9.2567,29.76311,22.12948-.00758,.01491-.02273,.02987-.03026,.04482-.37094,.55286-.69642,1.07584-.98407,1.5764-.28007,.47068-.51472,.91893-.71906,1.34479-1.58204,3.28732,2.48454,7.42377-.21196,8.19585-3.58634,1.02687,9.43221,34.7781-4.76294,34.7781,6.90484,1.96318,.74711-29.88452-.74711-35.11431Z"
fill=
"#2f2e41"
/><circle
cx=
"64.30255"
cy=
"222.86019"
r=
"20.41274"
fill=
"#a0616a"
/><path
d=
"M87.25214,213.75664c-.34063,.1793-.67369,.34364-1.01433,.50803-.35574,.17182-.71153,.34369-1.06727,.50055-6.83524,3.10054-12.39877,3.44418-15.77477-1.00858-.09083-2.33099-.61312-4.64707-1.55173-6.79876,.17413,2.38329-.47688,4.81141-1.80153,6.79876h-6.79736c-7.00175,4.64702-10.59724,5.13266-5.73766,20.3887,1.35496,4.25107,6.74242,28.98798,4.62298,32.65633-.61312-.06726-7.13605-27.16184-7.72644-27.27388-13.30712-2.51777-21.76218-24.44131-20.67975-25.68149,0-3.64592,.84778-7.0901,2.36924-10.1682,1.96804-3.99708,5.06397-7.35909,8.88653-9.66764,2.25568-1.09828,4.6325-1.98735,7.10015-2.6672,.06057-.01496,.11356-.02991,.17408-.04482,.74937-.20174,1.51389-.38851,2.27841-.54542,1.56688-.32873,3.15645-.57525,4.7839-.72468,.11356-.00748,.22707-.01496,.33306-.01496,.66612,0,1.28682,.18678,1.82422,.5006,.00758,0,.00758,.00743,.01515,.00743,.39363,.2316,.74179,.53795,1.01433,.90402,.4693,.59768,.74179,1.34479,.74179,2.15917h7.56946c.28007,0,.56013,.00748,.8402,.02239,10.54425,.41838,19.02205,8.71136,19.56707,19.0813,.02268,.3586,.03026,.70972,.03026,1.06837Z"
fill=
"#2f2e41"
/><path
d=
"M56.06882,193.78318c0,7.42714-6.02089,13.44803-13.44803,13.44803-7.42714,0-13.44803-6.02089-13.44803-13.44803s6.02089-13.44803,13.44803-13.44803c7.42714,0,13.44803,6.02089,13.44803,13.44803Z"
fill=
"#2f2e41"
/></g></svg>
\ No newline at end of file
ux/public/_assets/illustrations/undraw_settings.svg
0 → 100644
View file @
7fe7fbb3
<svg
xmlns=
"http://www.w3.org/2000/svg"
data-name=
"Layer 1"
width=
"753"
height=
"480.95111"
viewBox=
"0 0 753 480.95111"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
><path
d=
"M372.67989,690.09163l-2-.03906a463.83342,463.83342,0,0,1,7.09961-66.28711c8.64844-46.88086,23.02929-77.66992,42.74316-91.51172l1.14844,1.63672C375.61934,566.22444,372.70333,688.85628,372.67989,690.09163Z"
transform=
"translate(-223.5 -209.52444)"
fill=
"#2f2e41"
/><path
d=
"M397.67989,689.61311l-2-.03906c.043-2.21484,1.293-54.41406,21.84277-68.8418l1.14844,1.63672C398.9504,636.21468,397.68965,689.08089,397.67989,689.61311Z"
transform=
"translate(-223.5 -209.52444)"
fill=
"#2f2e41"
/><circle
cx=
"209.54903"
cy=
"314.54765"
r=
"10.00001"
fill=
"#1976d2"
/><circle
cx=
"204.59688"
cy=
"400.54767"
r=
"10"
fill=
"#1976d2"
/><path
d=
"M393.01866,540.06667c1.87935,12.004-3.0189,22.7406-3.0189,22.7406s-7.9453-8.72583-9.82465-20.72986,3.01891-22.7406,3.01891-22.7406S391.1393,528.06264,393.01866,540.06667Z"
transform=
"translate(-223.5 -209.52444)"
fill=
"#2f2e41"
/><path
d=
"M425.70583,569.22047c-11.493,3.9422-22.91878.98963-22.91878.98963s7.20793-9.34412,18.70088-13.28632,22.9188-.98962,22.9188-.98962S437.19878,565.27828,425.70583,569.22047Z"
transform=
"translate(-223.5 -209.52444)"
fill=
"#2f2e41"
/><path
d=
"M426.07508,645.38161a31.13456,31.13456,0,0,1-16.06421.69366,28.37369,28.37369,0,0,1,29.172-10.00628A31.13431,31.13431,0,0,1,426.07508,645.38161Z"
transform=
"translate(-223.5 -209.52444)"
fill=
"#2f2e41"
/><polygon
points=
"606.671 467.453 593.531 467.453 587.28 416.768 606.674 416.769 606.671 467.453"
fill=
"#9e616a"
/><path
d=
"M833.52257,689.71536l-42.3702-.00157v-.53592a16.49256,16.49256,0,0,1,16.49166-16.4914h.001l25.87827.001Z"
transform=
"translate(-223.5 -209.52444)"
fill=
"#2f2e41"
/><polygon
points=
"525.57 467.453 512.429 467.453 506.178 416.768 525.572 416.769 525.57 467.453"
fill=
"#9e616a"
/><path
d=
"M752.421,689.71536l-42.3702-.00157v-.53592a16.49256,16.49256,0,0,1,16.49166-16.4914h.00105l25.87827.001Z"
transform=
"translate(-223.5 -209.52444)"
fill=
"#2f2e41"
/><path
d=
"M716.28867,393.14081l-18.19929-2.81212-5.87957,9.464-63.27234,16.12848.1713.87221a11.90415,11.90415,0,1,0,2.58765,12.30932L708.321,413.12185Z"
transform=
"translate(-223.5 -209.52444)"
fill=
"#9e616a"
/><path
d=
"M898.0541,381.87169a11.85506,11.85506,0,0,0-4.37548.841l.36312-.63329-80.44329-41.58032L802.631,358.229l83.63476,37.12523a11.89949,11.89949,0,1,0,11.78838-13.48252Z"
transform=
"translate(-223.5 -209.52444)"
fill=
"#9e616a"
/><circle
cx=
"736.07056"
cy=
"267.73324"
r=
"35.53801"
transform=
"translate(130.38899 741.8887) rotate(-80.78252)"
fill=
"#2f2e41"
/><circle
cx=
"512.26421"
cy=
"70.76964"
r=
"22.6708"
fill=
"#a0616a"
/><ellipse
cx=
"512.57057"
cy=
"48.4052"
rx=
"24.50896"
ry=
"14.70538"
fill=
"#2f2e41"
/><circle
cx=
"515.02148"
cy=
"22.67078"
r=
"14.70537"
fill=
"#2f2e41"
/><path
d=
"M718.91431,224.22982A14.70692,14.70692,0,0,1,732.08789,209.604a14.86918,14.86918,0,0,0-1.53183-.07951,14.70539,14.70539,0,0,0,0,29.41076,14.86917,14.86917,0,0,0,1.53183-.0795A14.70693,14.70693,0,0,1,718.91431,224.22982Z"
transform=
"translate(-223.5 -209.52444)"
fill=
"#2f2e41"
/><path
d=
"M723.97781,336.57587l1.82839-17.57652s24.80562-16.34735,33.23625-6.68558l50.38786,86.21281s31.323,11.13572,30.21575,53.658l-1.498,205.5398L802.631,661.61826,781.063,501.3681l-19.48674,166.026-41.35039-1.29476,3.72025-109.37556,19.71737-106.02732-.1889-35.18233-8.68389-14.19874s-15.90728-6.39038-16.35213-24.44983l-.34823-25.38571Z"
transform=
"translate(-223.5 -209.52444)"
fill=
"#2f2e41"
/><path
d=
"M749.98787,317.13922l.48927-8.23917s75.032,19.772,69.07954,33.90894-17.11318,18.60128-17.11318,18.60128l-43.155-17.11318Z"
transform=
"translate(-223.5 -209.52444)"
fill=
"#2f2e41"
/><path
d=
"M730.38083,337.64127l-5.64584-6.02061s-45.03187,63.189-31.41423,70.24916,25.0524,3.35351,25.0524,3.35351l22.22821-40.75684Z"
transform=
"translate(-223.5 -209.52444)"
fill=
"#2f2e41"
/><path
d=
"M640.24484,543.397,922.80569,486.993l-23.614-118.29636L616.63089,425.1006Z"
transform=
"translate(-223.5 -209.52444)"
fill=
"#fff"
/><path
d=
"M925.11811,488.5359,638.702,545.70941,614.31843,423.5577l286.41613-57.1735ZM641.78762,541.08463l278.70571-55.63437L897.64892,371.009,618.94321,426.64335Z"
transform=
"translate(-223.5 -209.52444)"
fill=
"#e4e4e4"
/><rect
x=
"649.55431"
y=
"429.35966"
width=
"233.18398"
height=
"6.07982"
transform=
"translate(-293.32159 -51.18186) rotate(-11.28883)"
fill=
"#e4e4e4"
/><rect
x=
"654.1884"
y=
"452.57456"
width=
"233.18398"
height=
"6.07982"
transform=
"translate(-297.77636 -49.82557) rotate(-11.28883)"
fill=
"#e4e4e4"
/><rect
x=
"658.84925"
y=
"475.92356"
width=
"233.18398"
height=
"6.07982"
transform=
"translate(-302.25687 -48.46145) rotate(-11.28883)"
fill=
"#e4e4e4"
/><path
d=
"M770.62873,443.64449,762.631,445.241a2.24918,2.24918,0,0,1-2.643-1.76342L756.20675,424.535a2.24917,2.24917,0,0,1,1.76341-2.643l7.99772-1.59648a2.24918,2.24918,0,0,1,2.643,1.76342l3.78125,18.94256A2.24917,2.24917,0,0,1,770.62873,443.64449Z"
transform=
"translate(-223.5 -209.52444)"
fill=
"#1976d2"
/><path
d=
"M861.72707,449.59966l-7.99771,1.59648a2.24916,2.24916,0,0,1-2.643-1.76342l-3.78126-18.94255a2.24917,2.24917,0,0,1,1.76342-2.643l7.99772-1.59648a2.24917,2.24917,0,0,1,2.643,1.76342l3.78125,18.94255A2.24916,2.24916,0,0,1,861.72707,449.59966Z"
transform=
"translate(-223.5 -209.52444)"
fill=
"#1976d2"
/><path
d=
"M812.39337,483.72688l-7.99771,1.59648a2.24916,2.24916,0,0,1-2.643-1.76342l-3.78126-18.94255a2.24917,2.24917,0,0,1,1.76342-2.643l7.99772-1.59648a2.24917,2.24917,0,0,1,2.643,1.76342l3.78125,18.94256A2.24915,2.24915,0,0,1,812.39337,483.72688Z"
transform=
"translate(-223.5 -209.52444)"
fill=
"#1976d2"
/><path
d=
"M975.5,690.47556h-751a1,1,0,0,1,0-2h751a1,1,0,0,1,0,2Z"
transform=
"translate(-223.5 -209.52444)"
fill=
"#cacaca"
/></svg>
\ No newline at end of file
ux/public/_assets/illustrations/undraw_world.svg
0 → 100644
View file @
7fe7fbb3
<svg
xmlns=
"http://www.w3.org/2000/svg"
data-name=
"Layer 1"
width=
"825.20213"
height=
"591.41898"
viewBox=
"0 0 825.20213 591.41898"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
><path
d=
"M855.22391,530.60767a3.61324,3.61324,0,0,0,2.90706-6.13407c-.07417-.366-.12737-.62878-.20154-.99475q.05434-.11581.10925-.23144a9.7031,9.7031,0,0,1,17.876.89878c2.59635,7.179,5.991,14.40726,6.561,21.8966a28.70516,28.70516,0,0,1-.96247,9.83823,115.08607,115.08607,0,0,0,12.68043-47.26037,111.08146,111.08146,0,0,0-.112-12.41061q-.33489-5.08075-1.11483-10.11009a116.41936,116.41936,0,0,0-20.7675-50.36176,30.98251,30.98251,0,0,1-12.24992-13.95369,23.63369,23.63369,0,0,1-1.84668-6.55118c.62279.11137,1.25731.19237,1.882.2626.19474.01931.39969.03918.59443.05857l.07346.00673a3.5799,3.5799,0,0,0,3.20814-5.68922q-.38259-.51834-.7657-1.03621c-.387-.5328-.78478-1.05577-1.17173-1.58848a1.78375,1.78375,0,0,1-.12638-.16038c-.44535-.60755-.891-1.2048-1.33637-1.81235a10.3517,10.3517,0,0,1,3.54254-3.11908c4.86483-2.55314,11.30882-.328,14.53022,4.11493,3.23163,4.44334,3.599,10.48308,2.15829,15.77961a41.485,41.485,0,0,1-6.32713,12.51228c.24157.34072.49384.67161.73533,1.01232a117.17152,117.17152,0,0,1,11.3155,19.92258,48.70927,48.70927,0,0,1,3.957-22.46476c3.09271-6.57809,8.56723-11.98458,13.42656-17.56958,5.83684-6.70843,16.99941-3.14247,17.55956,5.73205q.00813.12888.0156.25766-1.04937.52926-2.05883,1.13134a4.9011,4.9011,0,0,0,1.55911,9.00132l.09912.02006a48.76709,48.76709,0,0,1-1.62312,7.22358,50.20985,50.20985,0,0,1-26.43617,30.27174c-.41021.18678-.8102.374-1.21994.5506a119.59729,119.59729,0,0,1,5.02184,30.56259,113.43466,113.43466,0,0,1-.93392,18.29177l.04087-.2143a29.97406,29.97406,0,0,1,11.02621-16.813c8.16666-6.09535,19.39042-7.95739,28.11808-12.75615a5.62528,5.62528,0,0,1,8.3519,5.86726q-.02235.11259-.04527.22517a32.92431,32.92431,0,0,0-3.77057,1.60542q-1.04937.52938-2.05883,1.13133a4.90116,4.90116,0,0,0,1.55911,9.00141l.0992.02c.0714.01365.13259.02683.20391.04048a48.808,48.808,0,0,1-9.6217,13.62515,50.25442,50.25442,0,0,1-37.14994,14.27914l-.01031-.00048a119.56225,119.56225,0,0,1-9.11335,23.04815l-28.66063-1.33426c-.088-.32324-.16508-.65631-.24275-.97907a32.59881,32.59881,0,0,0,7.95257-.10325c-2.005-2.70831-4.009-5.43714-6.014-8.14536a1.78114,1.78114,0,0,1-.12638-.16029c-1.01644-1.38562-2.04367-2.7615-3.06011-4.14712l-.0005-.00167a47.75014,47.75014,0,0,1,1.96332-12.08589Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#f2f2f2"
/><path
d=
"M277.74278,282.7727a3.61324,3.61324,0,0,1-3.28049-5.94275c.05141-.36985.08827-.63544.13969-1.00529q-.0614-.11225-.12334-.22425a9.70311,9.70311,0,0,0-17.78635,2.00152c-2.14784,7.32572-5.08937,14.74988-5.19559,22.26013a28.70519,28.70519,0,0,0,1.56847,9.76A115.08612,115.08612,0,0,1,237.489,263.2354a111.08,111.08,0,0,1-.655-12.39382q.02032-5.09173.488-10.15965a116.41941,116.41941,0,0,1,17.61625-51.54865,30.9826,30.9826,0,0,0,11.36441-14.68388,23.63353,23.63353,0,0,0,1.43838-6.65276c-.61471.14962-1.243.26968-1.86218.37837-.19317.0313-.3965.0638-.58967.09518l-.0729.01126a3.5799,3.5799,0,0,1-3.55352-5.48014q.34985-.541.70021-1.08154c.35338-.55569.71805-1.10224,1.07136-1.65784a1.783,1.783,0,0,0,.11622-.16788c.407-.63391.81488-1.25754,1.22185-1.89145a10.35181,10.35181,0,0,0-3.72849-2.89425c-5.01327-2.24769-11.30748.37131-14.24822,5.0048-2.95093,4.63452-2.94443,10.68542-1.17923,15.88282a41.485,41.485,0,0,0,7.0881,12.09746c-.22006.355-.4514.70083-.67138,1.05582a117.17159,117.17159,0,0,0-10.063,20.58363,48.70935,48.70935,0,0,0-5.33737-22.17736c-3.49323-6.37444-9.29133-11.43236-14.48644-16.70646-6.24017-6.335-17.16108-2.08617-17.17187,6.806q-.00015.12915.00035.25814,1.08007.46341,2.12481,1.002a4.9011,4.9011,0,0,1-1,9.08046l-.09769.02615a48.76726,48.76726,0,0,0,2.06632,7.10949,50.20987,50.20987,0,0,0,28.256,28.58057c.421.16108.83176.32327,1.25162.47418a119.5973,119.5973,0,0,0-3.124,30.81447,113.4334,113.4334,0,0,0,2.06228,18.19912l-.054-.21137a29.974,29.974,0,0,0-12.04392-16.09966c-8.52766-5.57913-19.845-6.74416-28.85249-10.99452a5.62528,5.62528,0,0,0-7.97344,6.37206q.02925.111.05909.22194a32.92391,32.92391,0,0,1,3.86256,1.3694q1.08007.46353,2.1248,1.002a4.90116,4.90116,0,0,1-1,9.08054l-.09777.02608c-.07043.018-.13068.035-.201.053a48.80794,48.80794,0,0,0,10.44514,13.00466,50.25449,50.25449,0,0,0,37.9612,11.95658l.01025-.00112a119.563,119.563,0,0,0,10.51995,22.44105l28.52344-3.10249c.06784-.32806.12422-.66525.1818-.99219a32.5995,32.5995,0,0,1-7.94375.38829c1.83384-2.827,3.66537-5.67444,5.49922-8.50137a1.7786,1.7786,0,0,0,.11623-.1678c.9289-1.44577,1.86915-2.88248,2.798-4.32825l.0004-.00171a47.75009,47.75009,0,0,0-2.70629-11.94149Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#f2f2f2"
/><path
d=
"M671.818,272.20237a10.016,10.016,0,0,1,6.38343,13.969l15.30646,17.01743-8.07279,11.82394L664.157,290.67726a10.07034,10.07034,0,0,1,7.661-18.47489Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#a0616a"
/><path
d=
"M815.11419,313.98886l0,0a20.02625,20.02625,0,0,0-27.60778-6.54222l-50.33925,31.17727-54.30081-46.15769L669.3562,305.04493l59.987,77.82961,77.96532-40.64446C805.489,343.17862,817.31273,317.56739,815.11419,313.98886Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#ccc"
/><path
d=
"M715.39088,417.65494a189.27007,189.27007,0,0,1-189.308,189.308c-104.55063,0-189.308-84.75749-189.308-189.308a189.24483,189.24483,0,0,1,9.65476-59.84238A189.50618,189.50618,0,0,1,526.08289,228.347,189.24453,189.24453,0,0,1,693.0211,328.33307a186.77361,186.77361,0,0,1,10.46447,23.10619c.41,1.10421.80984,2.20843,1.19884,3.32331v.01053q2.60321,7.35132,4.58557,14.97635A189.32006,189.32006,0,0,1,715.39088,417.65494Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#3f3d56"
/><path
d=
"M505.371,289.93115a63.51666,63.51666,0,0,0-55.7615-2.28136c-7.79648,3.393-16.00583,9.47972-18.6067,20.47116,10.519-6.20795,24.13568,3.60058,26.8425,19.33555l-.63186.17419c-1.42965,10.89863,1.76186,22.76429,7.94073,29.52228.81123-7.01955,5.42678-11.797,9.96657-14.78135,4.53979-2.9843,9.562-5.15219,13.02707-10.28189,4.10787-6.08133,5.151-14.96914,6.7829-23.077C496.56263,300.90483,499.65869,292.1904,505.371,289.93115Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#fff"
/><path
d=
"M446.48934,382.675c-2.91326,4.375-6.80454,7.12011-10.29617,10.53817-3.48109,3.42859-6.79414,8.056-7.48817,13.99821-.44177,3.80718.24187,7.67741.14712,11.52684-.09449,3.84917-1.37767,8.18221-3.99642,9.1393-4.13328,1.49335-7.28842-6.18406-11.53724-6.72045-3.37608-.42071-6.41541,4.89049-5.43739,9.497.97814,4.6065,5.57412,6.64675,8.21392,3.63888,2.38741,4.007.70457,11.27444-2.88168,12.50486-.37873,2.52413-.7572,5.03773-1.1254,7.56174-9.06574-6.34185-18.22611-12.78872-25.9351-22.07541a67.00679,67.00679,0,0,1-15.27087-36.09467c-.99907-10.67489.48375-22.88524-4.41713-31.099-3.923-6.57319-10.654-8.02468-16.71184-7.61437-1.10421.07356-2.219.19976-3.32331.33649a187.23535,187.23535,0,0,1,13.55644-31.02548,13.2821,13.2821,0,0,0,3.397-2.11395c5.63728-4.78521,8.14036-14.47155,12.71528-21.171q.44177-.64686.915-1.262c4.68019-6.1105,10.94835-9.25511,17.00622-12.1789,13.40931-6.51,27.20763-13.10427,41.36375-12.19982l-4.028.38913q-7.05168,19.75116-14.114,39.50233-1.07283,3.0288-2.16646,6.06839c-2.67138,7.48805-5.42686,15.4601-5.01668,23.84221.24187,4.964,1.96657,10.26471,5.248,11.96848,3.06039,1.57756,6.40488-.35755,9.36012-2.27173,1.25161-.79932,2.49268-1.59863,3.74416-2.40846,4.49082-2.89221,9.4654-5.858,14.20862-3.92287,4.34358,1.76694,7.55122,7.667,8.16129,14.02992A28.04928,28.04928,0,0,1,446.48934,382.675Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#fff"
/><path
d=
"M473.19842,472.57227q-19.67374-12.11336-39.34763-24.22672l.22263-.57342c-8.15482,3.106-11.54047,17.60169-10.19276,29.456,1.34764,11.85442,5.91745,22.45144,8.226,34.00207a90.25226,90.25226,0,0,1-3.40267,47.35761,387.843,387.843,0,0,0,45.56027-62.78054,33.58822,33.58822,0,0,0,4.12118-9.13813c.83321-3.44179.70508-7.57955-.96357-10.33953A11.5109,11.5109,0,0,0,473.19842,472.57227Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#fff"
/><path
d=
"M421.43456,325.65321c-1.3927,3.13139-1.92854,7.30684-.66468,10.5469,1.29075,3.309,4.01943,4.80443,6.53166,6.04952l7.24713,3.59224c2.411,1.19506,5.00969,2.40208,7.46752,1.41883,2.96442-1.18591,5.01982-5.83337,4.48812-10.14785-.56592-4.59118-3.45988-7.7493-6.13638-10.43868q-5.61837-5.64531-11.23667-11.29061l-2.11089,2.58543A28.19193,28.19193,0,0,0,421.43456,325.65321Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#fff"
/><path
d=
"M676.54061,374.73455q4.89062,1.15159,9.781,2.30319c-.568,11.01151-6.02628,21.20266-13.34615,24.894-3.05,1.53558-6.447,2.10342-8.97113,4.9747-2.28213,2.60822-3.43911,6.66768-4.50135,10.54856q-2.79233,10.15963-5.58465,20.319c-1.99815,7.29894-4.56426,15.40772-9.75978,18.037-4.45924,2.26108-9.56-.50493-12.9886-5.143-3.42859-4.638-5.52149-10.87466-7.55135-16.95345.1262,6.6257-2.95524,13.12534-7.31986,15.42852-4.37516,2.30319-9.69688.22082-12.62054-4.92193-2.10342-3.69152-2.97629-8.56108-5.03773-12.3051-2.06132-3.744-6.38383-5.88956-8.63451-2.37688-1.48295,2.3349-1.29371,5.91061-2.02986,8.87651-1.14633,4.60637-4.6169,7.49858-8.056,7.7511-3.42859.25241-6.77309-1.72482-9.64424-4.40673-5.92114-5.55307-10.28577-14.36628-11.979-24.15777-.74667-4.36463-.957-9.11826.33662-13.20956,1.29359-4.091,4.41714-7.24617,7.51964-6.46792,2.04038-4.31211-1.98763-10.03336-5.61611-9.52856-3.639.5048-6.4891,4.40661-9.47592,7.40409-2.9763,2.99735-7.141,5.17433-10.13851,2.198.02105,2.766-2.22963,4.596-4.17526,4.36462-1.93525-.22082-3.65994-1.77733-5.43727-2.88168-6.8677-4.28053-15.58643-1.44083-20.46638,6.65729,3.05-12.97808,7.51976-27.87034,16.89041-30.92033,3.82837-1.25148,8.00363-.22082,11.62146-2.38741,6.405-3.83864,7.69859-18.34178,2.16658-24.326.70457,5.65808.568,12.26286-2.419,16.13321-2.98683,3.87036-9.25511,1.34609-8.87638-4.37515-.86248,3.94391-5.15341,4.54346-7.13063,1.5144-1.98775-3.0288-1.81944-7.98232-.41019-11.60028s3.80719-6.21564,6.13143-8.70819c4.99563-5.35318,10.06495-10.76951,15.84936-14.13507,5.79494-3.36542,12.48381-4.50122,18.28914-1.15673,3.06065,1.76681,5.753,4.71165,8.87651,6.26816,3.12368,1.567,7.08852,1.36728,9.16049-2.29279,2.32424-4.08064,1.23042-10.13851,2.0929-15.23928,1.546-9.01311,10.55909-13.23048,15.55472-7.27789-3.7335-.957-7.59333,3.46018-8.05615,8.81348-.47322,5.35317,2.22975,10.759,5.84758,12.37866,6.07892,2.69231,12.03151-4.08078,16.62761-10.34893q7.19361-9.844,14.40839-19.67748a23.78177,23.78177,0,0,1,2.57664-3.13407,8.291,8.291,0,0,1,11.327-.23135c4.8589,3.96484,7.14116,12.09468,11.12719,17.68972,5.78441,8.12971,14.44,10.10693,22.496,11.6845q9.00784,1.75107,18.02648,3.52321a186.77361,186.77361,0,0,1,10.46447,23.10619C693.305,355.76164,683.91311,363.84937,676.54061,374.73455Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#fff"
/><path
d=
"M695.95528,501.2765a188.54566,188.54566,0,0,1-15.67052,26.21909c-3.78613-1.61968-7.85625,1.27253-11.40051,3.986-3.702,2.83957-8.15076,5.60558-11.94742,3.01841-3.88076-2.65033-5.13236-10.06482-3.90181-15.944,1.23042-5.8685,4.30133-10.53816,7.27776-14.97635,3.15513-4.71165,6.53108-9.60213,10.91676-11.4321,4.39621-1.83,10.04377.7572,11.327,7.00443l3.113-.10527c-1.74588-2.3978-.83077-7.362,1.51453-8.23485,2.70284-1.02013,5.04826,2.69231,6.64676,5.97377C694.546,498.26849,695.27164,499.762,695.95528,501.2765Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#fff"
/><path
d=
"M576.72735,456.85307c-6.69134.4208-11.99157-7.81664-15.51364-15.92031-3.52206-8.10375-6.73574-17.37094-12.77336-21.49573-3.44981-2.35695-7.3829-2.68032-11.12485-3.82245-3.742-1.142-7.65866-3.50524-9.44741-8.31792l-4.2446-1.71473c-5.60569,3.152-11.28535,6.36156-16.11556,11.4909a36.01807,36.01807,0,0,0-9.60269,20.99346c-.81084,8.4961,2.18328,17.96965,7.77788,21.16122,4.42058,2.52189,9.56739.93232,14.04519,3.24105,5.59453,2.88442,8.916,11.2636,10.17332,19.53684s.93866,16.87112,1.83819,25.23825,3.37871,17.07349,8.50933,21.36133c6.42036,5.36571,15.8412.907,18.72178-8.86044,1.413-4.79111,1.36427-10.19733,2.42106-15.1707,1.861-8.75838,6.88293-15.25634,10.866-22.44083C576.24114,474.94861,579.37645,465.19075,576.72735,456.85307Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#fff"
/><path
d=
"M510.60693,370.79a17.86027,17.86027,0,0,1,1.74249,1.84977,6.0774,6.0774,0,0,1-.107,6.27583,5.83861,5.83861,0,0,0,4.18126-2.12511,26.87915,26.87915,0,0,0,3.20585-4.51587c.68252-1.11285,1.40836-2.61751.94522-3.93927-.3161-.90214-1.06361-1.287-1.58767-1.96542-.83059-1.07533-1.03646-2.78336-1.46641-4.25929-.92846-3.18785-3.15264-5.53192-5.56707-5.86707l.33533.06416c-1.00855.34549-1.7128,1.94712-1.48986,3.38824.20313,1.31242,1.04646,2.402.96255,3.74051-.12061,1.92473-2.04418,2.828-2.163,4.753A3.67445,3.67445,0,0,0,510.60693,370.79Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#fff"
/><path
d=
"M499.14247,338.08151c.00994-.00271.01994-.00326.02988-.0058a5.35694,5.35694,0,0,0,.57089-.60813Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#e6e6e6"
/><path
d=
"M501.14925,347.11614c1.47948-.95135,2.30574-3.58245,1.81653-5.7846-.48608-2.18856-2.20646-3.66-3.79343-3.25583a3.86646,3.86646,0,0,1-3.59495,1.05839c-.98109-.25259-2.0582-.90305-2.90906-.16386a4.40412,4.40412,0,0,0-.9909,1.93479q-.47242,1.45027-.9449,2.90028a1.83,1.83,0,0,0-.11163,1.09908.93106.93106,0,0,0,.714.56762q2.83452.83566,5.669,1.67123C498.38094,347.54918,499.86781,347.94034,501.14925,347.11614Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#fff"
/><path
d=
"M643.80516,471.848q-1.31031-2.14511-2.62049-4.29038a14.334,14.334,0,0,0-3.45325-4.33578,3.05981,3.05981,0,0,0-4.356.43639l.1064.81686c1.991,2.498,4.09755,5.2729,4.60255,8.98025.19918,1.46151.12986,2.97414.3045,4.442s.671,2.9901,1.61837,3.623c1.37543.91891,2.99049-.43593,3.96942-2.08913a7.19317,7.19317,0,0,0,1.11451-4.57885A8.02966,8.02966,0,0,0,643.80516,471.848Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#fff"
/><path
d=
"M682.68046,417.23054q.37892-2.48492.758-4.96988a14.334,14.334,0,0,0,.15018-5.54088,3.05981,3.05981,0,0,0-3.61357-2.47124l-.44463.69346c-.0854,3.1932-.26073,6.67273-2.26178,9.83426-.78878,1.2464-1.8159,2.359-2.62754,3.59445s-1.41218,2.71968-1.09493,3.814c.46053,1.58874,2.56861,1.59226,4.38215.95787a7.19314,7.19314,0,0,0,3.80128-2.78536A8.02963,8.02963,0,0,0,682.68046,417.23054Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#e6e6e6"
/><path
d=
"M657.50794,473.70914c.42709-1.2275-.18949-2.63572-.31972-3.99283a8.76489,8.76489,0,0,1,1.33382-4.96911,16.1539,16.1539,0,0,0,2.07833-4.55638,3.81152,3.81152,0,0,0-.09971-2.23133c-.28914-.64955-.9895-.94582-1.39116-.43149l.85964.55366a7.82867,7.82867,0,0,0-3.48867.16894,4.3178,4.3178,0,0,0-2.64407,2.98058,18.44055,18.44055,0,0,1-.69335,3.09241c-.51278,1.054-1.50541,1.4046-2.12918,2.32976a5.57021,5.57021,0,0,0,.08774,5.29184,6.1768,6.1768,0,0,0,3.4939,2.74757C655.64528,475.06942,657.02766,475.08927,657.50794,473.70914Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#fff"
/><path
d=
"M681.91,481.07154a12.00485,12.00485,0,0,0,1.512,2.77512c1.16822,1.17675,2.75595.4536,4.17324.16757a7.21546,7.21546,0,0,1,6.86407,2.75319A17.47133,17.47133,0,0,0,684.41091,474.231c-3.341-1.362-6.85973-1.49359-10.33414-1.616l-.60013.1538C675.00587,477.22036,679.808,477.12076,681.91,481.07154Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#fff"
/><path
d=
"M578.55783,490.17659l.00879.01939q.08736-.168.17459-.33624Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#e6e6e6"
/><path
d=
"M574.8559,497.342a32.88905,32.88905,0,0,0-2.07687,4.56227,39.71126,39.71126,0,0,0-1.50522,7.80631c-.188,1.50447-.246,3.42594.69654,4.15905a1.337,1.337,0,0,0,1.74906-.23754,6.91827,6.91827,0,0,0,1.26793-1.88467,43.41661,43.41661,0,0,0,4.28028-10.15882c.90215-3.74378.89368-8.15134-.701-11.39266Q576.71136,493.76906,574.8559,497.342Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#fff"
/><path
d=
"M539.14331,306.43983a4.21456,4.21456,0,0,0,4.54215.88647,14.99873,14.99873,0,0,0,4.27371-2.823,10.0548,10.0548,0,0,0,2.59074-2.82624,5.73178,5.73178,0,0,0,.53-4.36641c-.58529-1.71175-2.07037-2.28553-3.38049-2.67406q-3.14617-.933-6.29241-1.86591l1.51726-1.36753c-1.561-.83779-3.288.71707-4.26378,2.64207a14.22382,14.22382,0,0,0-1.29432,3.98431C536.84394,301.051,537.35456,304.64906,539.14331,306.43983Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#e6e6e6"
/><path
d=
"M576.17373,294.00836a3.46486,3.46486,0,0,0,4.72246.38419,5.27918,5.27918,0,0,0,2.08866-3.76209c.14845-1.64984-.66729-3.48358-1.8324-3.626l.26665-1.54471c-2.24437-.4053-5.00619-.48651-6.20894,2.239A6.399,6.399,0,0,0,576.17373,294.00836Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#e6e6e6"
/><path
d=
"M571.22709,211.86454a49.9257,49.9257,0,0,0-55.20724,44.0149c-3.09067,27.39943,11.34417,86.89808,37.66188,111.52805,12.39171-47.189,55.81463-75.17882,61.56026-100.33572C621.38138,240.19076,598.62652,214.95522,571.22709,211.86454Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#1976d2"
/><circle
id=
"a2705e7e-530b-43fb-b0c6-4087ca2c8018"
data-name=
"b262ea8c-1946-46c9-a449-3a1996c39394"
cx=
"374.72809"
cy=
"102.20342"
r=
"16.28242"
fill=
"#fff"
/><circle
id=
"bb575e01-1284-49d3-8651-037e5b7ffa75"
data-name=
"bcc29a3a-8123-4529-80aa-6f70df2823cf"
cx=
"357.60783"
cy=
"225.9293"
r=
"10.66463"
fill=
"#1976d2"
/><path
d=
"M575.59911,244.82842A16.28211,16.28211,0,0,1,558.82662,272.741a16.28,16.28,0,0,0,11.9092-29.8527A16.28211,16.28211,0,0,1,575.59911,244.82842Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#231f20"
opacity=
"0.2"
style=
"isolation:isolate"
/><path
d=
"M615.30574,267.12439c-5.74562,25.15687-49.16855,53.14674-61.56025,100.33571a69.06074,69.06074,0,0,1-6.87746-7.53474c13.92474-44.35631,54.64494-71.30876,60.19629-95.61482,4.96849-21.75442-8.98817-42.429-29.01462-51.16258C602.29173,219.24193,620.93191,242.49051,615.30574,267.12439Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#231f20"
opacity=
"0.2"
style=
"isolation:isolate"
/><path
d=
"M418.64434,275.39608a37.4925,37.4925,0,0,0-41.45875,33.05369c-2.321,20.576,8.51909,65.25748,28.28279,83.75375,9.30575-35.43731,41.91488-56.45672,46.22965-75.34869C456.3085,296.6681,439.22038,277.71708,418.64434,275.39608Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#1976d2"
/><circle
id=
"b2d5ab8a-e71c-4a1a-aadf-98f8ab95825b"
data-name=
"b262ea8c-1946-46c9-a449-3a1996c39394"
cx=
"224.41157"
cy=
"154.62072"
r=
"12.22754"
fill=
"#fff"
/><circle
id=
"bac33ac8-32b5-423c-9bc5-6c03ceb8d8dc"
data-name=
"bcc29a3a-8123-4529-80aa-6f70df2823cf"
cx=
"211.55484"
cy=
"247.53462"
r=
"8.00877"
fill=
"#1976d2"
/><path
d=
"M421.92757,300.15083A12.2273,12.2273,0,1,1,409.332,321.11221a12.22574,12.22574,0,0,0,8.9434-22.41835A12.22721,12.22721,0,0,1,421.92757,300.15083Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#231f20"
opacity=
"0.2"
style=
"isolation:isolate"
/><path
d=
"M451.7459,316.89434c-4.31476,18.892-36.9239,39.91138-46.22964,75.34869a51.86155,51.86155,0,0,1-5.16474-5.65834c10.457-33.31006,41.03648-53.55043,45.20536-71.80345,3.73116-16.33682-6.74982-31.8627-21.789-38.42135C441.97282,280.93625,455.971,298.39514,451.7459,316.89434Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#231f20"
opacity=
"0.2"
style=
"isolation:isolate"
/><polygon
points=
"614.063 564.054 600.638 564.054 594.251 512.27 614.066 512.271 614.063 564.054"
fill=
"#a0616a"
/><path
d=
"M808.68441,743.83618H799.158l-1.70042-8.99408-4.355,8.99408H767.83616a5.67965,5.67965,0,0,1-3.22736-10.35347l20.177-13.93494v-9.0927l21.22264,1.2667Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#2f2e41"
/><polygon
points=
"562.063 564.054 548.638 564.054 542.251 512.27 562.066 512.271 562.063 564.054"
fill=
"#a0616a"
/><path
d=
"M756.68441,743.83618H747.158l-1.70042-8.99408-4.355,8.99408H715.83616a5.67965,5.67965,0,0,1-3.22736-10.35347l20.177-13.93494v-9.0927l21.22264,1.2667Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#2f2e41"
/><path
d=
"M698.45785,581.62352C701.027,585.47728,728.97669,691.417,728.97669,691.417l24.78267,2.8261-2.94167-26.65516-4.49613-47.1699-6.96244-31.48522s24.58692-55.95658,26.1413-60.41406l1.10473-3.19861L774.287,595.0346a19.577,19.577,0,0,1,1.16894,7.78459c-.23122,4.35477,4.1364,69.86859,4.1364,69.86859l2.09977,23.49506,21.23324,2.94958L811.54,658.48018c7.19365-13.20558,3.07-60.13148.12843-64.49911s-1.77275-34.78661-1.77275-34.78661c3.75647-1.32184,26.15662-77.70611,14.95252-77.25506.71936-4.07209,1.28453-7.70751,1.28453-7.70751L806.6841,458.54706l-48.67284-12.65291-12.27964-5.89628s-21.93185,40.55432-21.71349,42.57113a11.21429,11.21429,0,0,1-1.65709,7.3093l-22.14331,74.10779S695.863,577.73126,698.45785,581.62352Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#2f2e41"
/><path
d=
"M820.74021,316.438,812.997,299.99787l-26.35436,1.01288-8.59627,17.10337s-24.56687,29.34271-25.362,38.88375c-1,12,7.31164,70.81225-1,67,0,0-19.59459,23-8,23s64.04242,32.924,67.48383,36.62652,18.80446,6.10321,17.51617-1.62652-7.9442-49.53382-7.9442-49.53382l18.01876-65.733c5.18564-14.19171,6.79951-30.11048-4.923-39.64345Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#ccc"
/><path
d=
"M723.12108,268.05031A28.8805,28.8805,0,0,0,685.62273,284.238c-5.88478,14.825-6.86,50.22813,4.09122,67.97179,14.08087-24.45936,42.56848-33.49094,49.59479-46.6611C746.8166,291.47589,737.94606,273.9351,723.12108,268.05031Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#1976d2"
/><circle
id=
"f50692ea-d13f-4759-b5e2-05248e17533e"
data-name=
"b262ea8c-1946-46c9-a449-3a1996c39394"
cx=
"523.86724"
cy=
"137.29013"
r=
"9.41888"
fill=
"#fff"
/><circle
id=
"aec6a1c4-a00c-42b6-a49d-0158b63ca54a"
data-name=
"bcc29a3a-8123-4529-80aa-6f70df2823cf"
cx=
"495.52762"
cy=
"203.75403"
r=
"6.16917"
fill=
"#1976d2"
/><path
d=
"M720.55717,287.11426a9.41871,9.41871,0,0,1-13.59978,13.03434A9.4175,9.4175,0,0,0,718.13705,285.293,9.41862,9.41862,0,0,1,720.55717,287.11426Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#231f20"
opacity=
"0.2"
style=
"isolation:isolate"
/><path
d=
"M739.33634,305.58771c-7.0263,13.17015-35.51393,22.20174-49.59479,46.6611a39.949,39.949,0,0,1-2.69508-5.24993c14.50656-22.64545,41.328-31.50828,48.11674-44.233,6.076-11.3889,1.42413-25.0481-8.42863-32.96342C739.34118,276.88434,746.21658,292.69137,739.33634,305.58771Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#231f20"
opacity=
"0.2"
style=
"isolation:isolate"
/><path
d=
"M680.14627,355.92032a10.01609,10.01609,0,0,1,12.03458,9.542l21.36828,8.20224-1.81735,14.20115-30.01347-12.007a10.07034,10.07034,0,0,1-1.572-19.93845Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#a0616a"
/><path
d=
"M829.45215,326.65553l0,0a20.02625,20.02625,0,0,0-27.56523,6.71925l-30.67136,50.64907L701.8692,367.58613l-6.31772,17.34458,88.80518,42.06574,44.97713-71.63724C836.06781,345.896,839.36537,332.70754,829.45215,326.65553Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#ccc"
/><path
d=
"M830.59748,264.58346a29.82287,29.82287,0,1,1-51.29533-20.68525l.14314-.143c.2386-.25061.4772-.50108.72773-.73975a.01167.01167,0,0,0,.01187-.01194c.31017-.28629.62034-.57258.94245-.84692a29.815,29.815,0,0,1,49.47014,22.42685Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#2f2e41"
/><circle
cx=
"606.02821"
cy=
"117.1931"
r=
"25.00775"
fill=
"#9e616a"
/><path
d=
"M819.98324,278.61537l-4.14356-.73193a11.55433,11.55433,0,0,1-9.30469-9.31739l-4.043,6.77588-.17675.0586c-9.63282,3.19824-19.65528,2.2417-30.63379-2.92041a85.46475,85.46475,0,0,1-9.11817-5.02735l-.21679-.13525-.01758-.2544c-.55957-8.13525,1.26562-14.93164,5.1416-19.1372a15.41707,15.41707,0,0,1,11.63379-4.84961.95727.95727,0,0,0,.41309-.228c.05566-.041.11132-.08154.167-.12012v-.042l.28711-.13525c.61718-.29,1.24609-.56787,1.875-.82178a28.19911,28.19911,0,0,1,29.44824,5.708c7.70312,7.354,11.23633,19.69531,8.792,30.71093Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#2f2e41"
/><path
d=
"M872.72977,299.9221c-8.51007-4.39247,2.43483-20.33442.23554-29.65523-2.19937-9.32081-18.037-12.31871-19.04593-21.84222s-3.38245-19.346-9.6668-26.57249c-4.01568-4.61774-9.93278-8.02669-16.02492-7.44829a14.40868,14.40868,0,0,0-12.62826,17.79207c-1.73455-2.45776-6.22341-1.92509-7.33449.87052-.98788,2.48528,1.19437,5.49568,3.76252,5.71556,3.36046,4.15,7.2086,8.55427,12.47325,9.39144a5.68063,5.68063,0,0,0,4.84076-1.11734c1.23856-1.18942,1.33489-3.56739-.13434-4.45625,6.61615,2.62814,10.49509,9.78155,11.47678,16.83259.98162,7.051-.3765,14.18523-1.27148,21.24778s-1.28057,14.492,1.4886,21.05045c3.27178,7.74885,10.80453,13.30263,19.02518,15.0837s16.97552.04034,24.4166-3.88148c7.44108-3.92212,13.64622-9.90941,18.71523-16.62188C894.3263,302.51121,882.24593,304.834,872.72977,299.9221Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#2f2e41"
/><path
d=
"M818.91887,277.92016s-7.408-27.65168-39.16341-34.03389c-.03575-.01179-.15508-.05955-.31017-.131-.09538-.05971-.21472-.11941-.334-.179.35786-.20285.70378-.38167,1.06171-.56078a.01167.01167,0,0,0,.01187-.01194c.31017-.28629.62034-.57258.94245-.84692l.90663.03582S813.89667,237.14642,818.91887,277.92016Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#fd6584"
/><polygon
points=
"614.934 212.357 596.999 233.136 567.364 224.385 599.671 239.273 614.934 212.357"
opacity=
"0.2"
/><path
d=
"M909.9846,745.40215l-275.75.30734a1.19069,1.19069,0,0,1,0-2.38137l275.75-.30733a1.19068,1.19068,0,1,1,0,2.38136Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#cacaca"
/><path
d=
"M922.0884,560.36242q-19.36816,0-42.45654-1.46387c-79.61377-5.05566-182.73779-22.63281-290.376-49.49218C481.61813,482.547,382.32565,449.61242,309.67037,416.672c-35.39257-16.04687-62.55615-31.23633-80.73535-45.14746-19.24707-14.727-27.666-27.564-25.02392-38.15283,5.148-20.62891,50.731-25.14209,88.064-25.29541l.0127,3c-51.26807.21045-81.51367,8.38672-85.16553,23.022-4.65185,18.64014,33.28662,47.74072,104.08691,79.84131,72.49561,32.86813,171.60547,65.73923,279.07322,92.55661,107.46728,26.81641,210.40136,44.36328,289.83984,49.4082,77.57861,4.92774,124.74316-2.9375,129.39453-21.57812,3.86182-15.47657-21.59814-38.27539-71.68945-64.19825l1.3789-2.66406c36.397,18.83594,78.64551,45.85156,73.22168,67.58887-2.64251,10.58887-16.1054,17.96484-40.01507,21.92285C958.48342,559.23156,941.7427,560.36242,922.0884,560.36242Z"
transform=
"translate(-187.39893 -154.29051)"
fill=
"#1976d2"
/></svg>
\ No newline at end of file
ux/src/boot/apollo.js
View file @
7fe7fbb3
import
{
boot
}
from
'quasar/wrappers'
import
{
createApolloProvider
}
from
'@vue/apollo-option'
import
{
ApolloClient
,
InMemoryCache
}
from
'@apollo/client/core'
import
{
setContext
}
from
'@apollo/client/link/context'
import
{
createUploadLink
}
from
'apollo-upload-client'
...
...
@@ -41,16 +40,9 @@ export default boot(({ app }) => {
ssrForceFetchDelay
:
100
})
// Init Vue Apollo
const
apolloProvider
=
createApolloProvider
({
defaultClient
:
client
})
if
(
import
.
meta
.
env
.
SSR
)
{
global
.
APOLLO_CLIENT
=
client
}
else
{
window
.
APOLLO_CLIENT
=
client
}
app
.
use
(
apolloProvider
)
})
ux/src/components/ApiKeyCopyDialog.vue
0 → 100644
View file @
7fe7fbb3
<
template
lang=
"pug"
>
q-dialog(ref='dialogRef', @hide='onDialogHide', persistent)
q-card(style='min-width: 600px;')
q-card-section.card-header
q-icon(name='img:/_assets/icons/fluent-key-2.svg', left, size='sm')
span
{{
t
(
`admin.api.copyKeyTitle`
)
}}
q-card-section.card-negative
i18n-t(tag='span', keypath='admin.api.newKeyCopyWarn')
template(#bold)
strong
{{
t
(
'admin.api.newKeyCopyWarnBold'
)
}}
q-form.q-py-sm
q-item
blueprint-icon.self-start(icon='binary-file')
q-item-section
q-input(
type='textarea'
outlined
v-model='props.keyValue'
dense
hide-bottom-space
:label='t(`admin.api.key`)'
:aria-label='t(`admin.api.key`)'
autofocus
)
q-card-actions.card-actions
q-space
q-btn(
unelevated
:label='t(`common.actions.close`)'
color='primary'
padding='xs md'
@click='onDialogOK'
)
</
template
>
<
script
setup
>
import
{
useI18n
}
from
'vue-i18n'
import
{
useDialogPluginComponent
,
useQuasar
}
from
'quasar'
// PROPS
const
props
=
defineProps
({
keyValue
:
{
type
:
String
,
required
:
true
}
})
// EMITS
defineEmits
([
...
useDialogPluginComponent
.
emits
])
// QUASAR
const
{
dialogRef
,
onDialogHide
,
onDialogOK
}
=
useDialogPluginComponent
()
const
$q
=
useQuasar
()
// I18N
const
{
t
}
=
useI18n
()
</
script
>
ux/src/components/ApiKeyCreateDialog.vue
0 → 100644
View file @
7fe7fbb3
<
template
lang=
"pug"
>
q-dialog(ref='dialogRef', @hide='onDialogHide')
q-card(style='min-width: 650px;')
q-card-section.card-header
q-icon(name='img:/_assets/icons/fluent-plus-plus.svg', left, size='sm')
span
{{
t
(
`admin.api.newKeyTitle`
)
}}
q-form.q-py-sm(ref='createKeyForm', @submit='create')
q-item
blueprint-icon.self-start(icon='grand-master-key')
q-item-section
q-input(
outlined
v-model='state.keyName'
dense
:rules='keyNameValidation'
hide-bottom-space
:label='t(`admin.api.newKeyName`)'
:aria-label='t(`admin.api.newKeyName`)'
:hint='t(`admin.api.newKeyNameHint`)'
lazy-rules='ondemand'
autofocus
ref='iptName'
)
q-item
blueprint-icon.self-start(icon='schedule')
q-item-section
q-select(
outlined
:options='expirations'
v-model='state.keyExpiration'
multiple
map-options
option-value='value'
option-label='text'
emit-value
options-dense
dense
hide-bottom-space
:label='t(`admin.api.newKeyExpiration`)'
:aria-label='t(`admin.api.newKeyExpiration`)'
:hint='t(`admin.api.newKeyExpirationHint`)'
)
q-item
blueprint-icon.self-start(icon='access')
q-item-section
q-select(
outlined
:options='state.groups'
v-model='state.keyGroups'
multiple
map-options
emit-value
option-value='id'
option-label='name'
options-dense
dense
:rules='keyGroupsValidation'
hide-bottom-space
:label='t(`admin.api.permissionGroups`)'
:aria-label='t(`admin.api.permissionGroups`)'
:hint='t(`admin.api.newKeyGroupHint`)'
lazy-rules='ondemand'
:loading='state.loadingGroups'
)
template(v-slot:selected)
.text-caption(v-if='state.keyGroups.length > 1')
i18n-t(keypath='admin.api.groupsSelected')
template(#count)
strong
{{
state
.
keyGroups
.
length
}}
.text-caption(v-else-if='state.keyGroups.length === 1')
i18n-t(keypath='admin.api.groupSelected')
template(#group)
strong
{{
selectedGroupName
}}
span(v-else)
template(v-slot:option='{ itemProps, opt, selected, toggleOption }')
q-item(
v-bind='itemProps'
)
q-item-section(side)
q-checkbox(
size='sm'
:model-value='selected'
@update:model-value='toggleOption(opt)'
)
q-item-section
q-item-label
{{
opt
.
name
}}
q-card-actions.card-actions
q-space
q-btn.acrylic-btn(
flat
:label='t(`common.actions.cancel`)'
color='grey'
padding='xs md'
@click='onDialogCancel'
)
q-btn(
unelevated
:label='t(`common.actions.create`)'
color='primary'
padding='xs md'
@click='create'
:loading='state.loading > 0'
)
</
template
>
<
script
setup
>
import
gql
from
'graphql-tag'
import
{
cloneDeep
,
sampleSize
}
from
'lodash-es'
import
{
useI18n
}
from
'vue-i18n'
import
{
useDialogPluginComponent
,
useQuasar
}
from
'quasar'
import
{
computed
,
onMounted
,
reactive
,
ref
}
from
'vue'
import
ApiKeyCopyDialog
from
'./ApiKeyCopyDialog.vue'
// EMITS
defineEmits
([
...
useDialogPluginComponent
.
emits
])
// QUASAR
const
{
dialogRef
,
onDialogHide
,
onDialogOK
,
onDialogCancel
}
=
useDialogPluginComponent
()
const
$q
=
useQuasar
()
// I18N
const
{
t
}
=
useI18n
()
// DATA
const
state
=
reactive
({
keyName
:
''
,
keyExpiration
:
'90d'
,
keyGroups
:
[],
groups
:
[],
loadingGroups
:
false
,
loading
:
false
})
const
expirations
=
[
{
value
:
'30d'
,
text
:
t
(
'admin.api.expiration30d'
)
},
{
value
:
'90d'
,
text
:
t
(
'admin.api.expiration90d'
)
},
{
value
:
'180d'
,
text
:
t
(
'admin.api.expiration180d'
)
},
{
value
:
'1y'
,
text
:
t
(
'admin.api.expiration1y'
)
},
{
value
:
'3y'
,
text
:
t
(
'admin.api.expiration3y'
)
}
]
// REFS
const
createKeyForm
=
ref
(
null
)
const
iptName
=
ref
(
null
)
// COMPUTED
const
selectedGroupName
=
computed
(()
=>
{
return
state
.
groups
.
filter
(
g
=>
g
.
id
===
state
.
keyGroups
[
0
])[
0
]?.
name
})
// VALIDATION RULES
const
keyNameValidation
=
[
val
=>
val
.
length
>
0
||
t
(
'admin.api.nameMissing'
),
val
=>
/^
[^
<>"
]
+$/
.
test
(
val
)
||
t
(
'admin.api.nameInvalidChars'
)
]
const
keyGroupsValidation
=
[
val
=>
val
.
length
>
0
||
t
(
'admin.api.groupsMissing'
)
]
// METHODS
async
function
loadGroups
()
{
state
.
loading
++
state
.
loadingGroups
=
true
const
resp
=
await
APOLLO_CLIENT
.
query
({
query
:
gql
`
query getGroupsForCreateApiKey {
groups {
id
name
}
}
`
,
fetchPolicy
:
'network-only'
})
state
.
groups
=
cloneDeep
(
resp
?.
data
?.
groups
?.
filter
(
g
=>
g
.
id
!==
'10000000-0000-4000-8000-000000000001'
)
??
[])
state
.
loadingGroups
=
false
state
.
loading
--
}
async
function
create
()
{
state
.
loading
++
try
{
const
isFormValid
=
await
createKeyForm
.
value
.
validate
(
true
)
if
(
!
isFormValid
)
{
throw
new
Error
(
t
(
'admin.api.createInvalidData'
))
}
const
resp
=
await
APOLLO_CLIENT
.
mutate
({
mutation
:
gql
`
mutation createApiKey (
$name: String!
$expiration: String!
$groups: [UUID]!
) {
createApiKey (
name: $name
expiration: $expiration
groups: $groups
) {
operation {
succeeded
message
}
key
}
}
`
,
variables
:
{
name
:
state
.
keyName
,
expiration
:
state
.
keyExpiration
,
groups
:
state
.
keyGroups
}
})
if
(
resp
?.
data
?.
createApiKey
?.
operation
?.
succeeded
)
{
$q
.
notify
({
type
:
'positive'
,
message
:
t
(
'admin.api.createSuccess'
)
})
$q
.
dialog
({
component
:
ApiKeyCopyDialog
,
componentProps
:
{
keyValue
:
resp
?.
data
?.
createApiKey
?.
key
||
'ERROR'
}
}).
onDismiss
(()
=>
{
onDialogOK
()
})
}
else
{
throw
new
Error
(
resp
?.
data
?.
createApiKey
?.
operation
?.
message
||
'An unexpected error occured.'
)
}
}
catch
(
err
)
{
$q
.
notify
({
type
:
'negative'
,
message
:
err
.
message
})
}
state
.
loading
--
}
// MOUNTED
onMounted
(
loadGroups
)
</
script
>
ux/src/components/ApiKeyRevokeDialog.vue
0 → 100644
View file @
7fe7fbb3
<
template
lang=
"pug"
>
q-dialog(ref='dialogRef', @hide='onDialogHide')
q-card(style='min-width: 350px; max-width: 450px;')
q-card-section.card-header
q-icon(name='img:/_assets/icons/fluent-unavailable.svg', left, size='sm')
span
{{
t
(
`admin.api.revokeConfirm`
)
}}
q-card-section
.text-body2
i18n-t(keypath='admin.api.revokeConfirmText')
template(#name)
strong
{{
apiKey
.
name
}}
q-card-actions.card-actions
q-space
q-btn.acrylic-btn(
flat
:label='t(`common.actions.cancel`)'
color='grey'
padding='xs md'
@click='onDialogCancel'
)
q-btn(
unelevated
:label='t(`admin.api.revoke`)'
color='negative'
padding='xs md'
@click='confirm'
:loading='state.isLoading'
)
</
template
>
<
script
setup
>
import
gql
from
'graphql-tag'
import
{
useI18n
}
from
'vue-i18n'
import
{
useDialogPluginComponent
,
useQuasar
}
from
'quasar'
import
{
reactive
}
from
'vue'
// PROPS
const
props
=
defineProps
({
apiKey
:
{
type
:
Object
,
required
:
true
}
})
// EMITS
defineEmits
([
...
useDialogPluginComponent
.
emits
])
// QUASAR
const
{
dialogRef
,
onDialogHide
,
onDialogOK
,
onDialogCancel
}
=
useDialogPluginComponent
()
const
$q
=
useQuasar
()
// I18N
const
{
t
}
=
useI18n
()
// DATA
const
state
=
reactive
({
isLoading
:
false
})
// METHODS
async
function
confirm
()
{
state
.
isLoading
=
true
try
{
const
resp
=
await
APOLLO_CLIENT
.
mutate
({
mutation
:
gql
`
mutation revokeApiKey ($id: UUID!) {
revokeApiKey (id: $id) {
operation {
succeeded
message
}
}
}
`
,
variables
:
{
id
:
props
.
apiKey
.
id
}
})
if
(
resp
?.
data
?.
revokeApiKey
?.
operation
?.
succeeded
)
{
$q
.
notify
({
type
:
'positive'
,
message
:
t
(
'admin.api.revokeSuccess'
)
})
onDialogOK
()
}
else
{
throw
new
Error
(
resp
?.
data
?.
revokeApiKey
?.
operation
?.
message
||
'An unexpected error occured.'
)
}
}
catch
(
err
)
{
$q
.
notify
({
type
:
'negative'
,
message
:
err
.
message
})
}
state
.
isLoading
=
false
}
</
script
>
ux/src/components/CheckUpdateDialog.vue
0 → 100644
View file @
7fe7fbb3
<
template
lang=
"pug"
>
q-dialog(ref='dialogRef', @hide='onDialogHide')
q-card(style='min-width: 350px; max-width: 450px;')
q-card-section.card-header
q-icon(name='img:/_assets/icons/fluent-downloading-updates.svg', left, size='sm')
span
{{
t
(
`admin.system.checkingForUpdates`
)
}}
q-card-section
.q-pa-md.text-center
img(src='/_assets/illustrations/undraw_going_up.svg', style='width: 150px;')
q-linear-progress(
indeterminate
size='lg'
rounded
)
.q-mt-sm.text-center.text-caption Fetching latest version info...
q-card-actions.card-actions
q-space
q-btn.acrylic-btn(
flat
:label='t(`common.actions.cancel`)'
color='grey'
padding='xs md'
@click='onDialogCancel'
)
q-btn(
v-if='state.canUpgrade'
unelevated
:label='t(`admin.system.upgrade`)'
color='primary'
padding='xs md'
@click='upgrade'
:loading='state.isLoading'
)
</
template
>
<
script
setup
>
import
gql
from
'graphql-tag'
import
{
useI18n
}
from
'vue-i18n'
import
{
useDialogPluginComponent
,
useQuasar
}
from
'quasar'
import
{
reactive
}
from
'vue'
// EMITS
defineEmits
([
...
useDialogPluginComponent
.
emits
])
// QUASAR
const
{
dialogRef
,
onDialogHide
,
onDialogOK
,
onDialogCancel
}
=
useDialogPluginComponent
()
const
$q
=
useQuasar
()
// I18N
const
{
t
}
=
useI18n
()
// DATA
const
state
=
reactive
({
isLoading
:
false
,
canUpgrade
:
false
})
// METHODS
async
function
upgrade
()
{
state
.
isLoading
=
true
try
{
const
resp
=
await
APOLLO_CLIENT
.
mutate
({
mutation
:
gql
`
mutation deleteHook ($id: UUID!) {
deleteHook(id: $id) {
operation {
succeeded
message
}
}
}
`
,
variables
:
{
id
:
0
}
})
if
(
resp
?.
data
?.
deleteHook
?.
operation
?.
succeeded
)
{
$q
.
notify
({
type
:
'positive'
,
message
:
t
(
'admin.webhooks.deleteSuccess'
)
})
onDialogOK
()
}
else
{
throw
new
Error
(
resp
?.
data
?.
deleteHook
?.
operation
?.
message
||
'An unexpected error occured.'
)
}
}
catch
(
err
)
{
$q
.
notify
({
type
:
'negative'
,
message
:
err
.
message
})
}
state
.
isLoading
=
false
}
</
script
>
ux/src/css/app.scss
View file @
7fe7fbb3
...
...
@@ -152,6 +152,27 @@ body::-webkit-scrollbar-thumb {
}
}
.card-negative
{
display
:
flex
;
align-items
:
center
;
font-size
:
.9rem
;
@at-root
.body--light
&
{
background-color
:
$red-1
;
background-image
:
radial-gradient
(
at
bottom
center
,
lighten
(
$red-1
,
2%
)
,
lighten
(
$red-2
,
2%
));
border-bottom
:
1px
solid
$red-3
;
text-shadow
:
0
0
4px
#FFF
;
color
:
$red-9
;
}
@at-root
.body--dark
&
{
background-color
:
$red-9
;
background-image
:
radial-gradient
(
at
bottom
center
,
$red-7
,
$red-9
);
border-bottom
:
1px
solid
$red-7
;
text-shadow
:
0
0
4px
darken
(
$red-9
,
10%
);
color
:
#FFF
;
}
}
.card-actions
{
@at-root
.body--light
&
{
background-color
:
#FAFAFA
;
...
...
ux/src/i18n/locales/en.json
View file @
7fe7fbb3
...
...
@@ -24,7 +24,7 @@
"admin.api.headerRevoke"
:
"Revoke"
,
"admin.api.newKeyButton"
:
"New API Key"
,
"admin.api.newKeyCopyWarn"
:
"Copy the key shown below as {bold}"
,
"admin.api.newKeyCopyWarnBold"
:
"it will NOT be shown again"
,
"admin.api.newKeyCopyWarnBold"
:
"it will NOT be shown again
.
"
,
"admin.api.newKeyExpiration"
:
"Expiration"
,
"admin.api.newKeyExpirationHint"
:
"You can still revoke a key anytime regardless of the expiration."
,
"admin.api.newKeyFullAccess"
:
"Full Access"
,
...
...
@@ -1449,5 +1449,22 @@
"admin.auth.enabledHint"
:
"Should this strategy be available to sites for login."
,
"admin.auth.vendor"
:
"Vendor"
,
"admin.auth.vendorWebsite"
:
"Website"
,
"admin.auth.status"
:
"Status"
"admin.auth.status"
:
"Status"
,
"admin.system.checkingForUpdates"
:
"Checking for Updates..."
,
"admin.system.upgrade"
:
"Upgrade"
,
"admin.system.checkForUpdates"
:
"Check"
,
"admin.system.checkUpdate"
:
"Check / Upgrade"
,
"admin.api.none"
:
"There are no API keys yet."
,
"admin.api.groupsMissing"
:
"You must select at least 1 group for this key."
,
"admin.api.nameInvalidChars"
:
"Key name has invalid characters."
,
"admin.api.nameMissing"
:
"Key name is missing."
,
"admin.api.permissionGroups"
:
"Group Permissions"
,
"admin.api.groupSelected"
:
"Use {group} group permissions"
,
"admin.api.groupsSelected"
:
"Use permissions from {count} groups"
,
"admin.api.createInvalidData"
:
"Some fields are missing or have invalid data."
,
"admin.api.copyKeyTitle"
:
"Copy API Key"
,
"admin.api.key"
:
"API Key"
,
"admin.api.createSuccess"
:
"API Key created successfully."
,
"admin.api.revoked"
:
"Revoked"
,
"admin.api.revokedHint"
:
"This key has been revoked and can no longer be used."
}
ux/src/pages/AdminApi.vue
View file @
7fe7fbb3
...
...
@@ -9,7 +9,7 @@ q-page.admin-api
.col
.flex.items-center
template(v-if='state.enabled')
q-spinner-rings.q-mr-sm(color='green')
q-spinner-rings.q-mr-sm(color='green'
, size='md'
)
.text-caption.text-green
{{
t
(
'admin.api.enabled'
)
}}
template(v-else)
q-spinner-rings.q-mr-sm(color='red', size='md')
...
...
@@ -28,7 +28,7 @@ q-page.admin-api
flat
color='secondary'
:loading='state.loading > 0'
@click='
load
'
@click='
refresh
'
)
q-btn.q-mr-sm(
unelevated
...
...
@@ -36,6 +36,7 @@ q-page.admin-api
:label='!state.enabled ? t(`admin.api.enableButton`) : t(`admin.api.disableButton`)'
:color='!state.enabled ? `positive` : `negative`'
@click='globalSwitch'
:loading='state.isToggleLoading'
:disabled='state.loading > 0'
)
q-btn(
...
...
@@ -48,70 +49,47 @@ q-page.admin-api
)
q-separator(inset)
.row.q-pa-md.q-col-gutter-md
.col-12.col-lg-7
q-card.shadow-1
//- v-container(fluid, grid-list-lg)
//- v-layout(row, wrap)
//- v-flex(xs12)
//- .admin-header
//- img.animated.fadeInUp(src='/_assets/svg/icon-rest-api.svg', alt='API', style='width: 80px;')
//- .admin-header-title
//- .headline.primary--text.animated.fadeInLeft
{{
$t
(
'admin.api.title'
)
}}
//- .subtitle-1.grey--text.animated.fadeInLeft
{{
$t
(
'admin.api.subtitle'
)
}}
//- v-spacer
//- template(v-if='enabled')
//- status-indicator.mr-3(positive, pulse)
//- .caption.green--text.animated.fadeInLeft
{{
$t
(
'admin.api.enabled'
)
}}
//- template(v-else)
//- status-indicator.mr-3(negative, pulse)
//- .caption.red--text.animated.fadeInLeft
{{
$t
(
'admin.api.disabled'
)
}}
//- v-spacer
//- v-btn.mr-3.animated.fadeInDown.wait-p2s(outlined, color='grey', icon, @click='refresh')
//- v-icon mdi-refresh
//- v-btn.mr-3.animated.fadeInDown.wait-p1s(:color='enabled ? `red` : `green`', depressed, @click='globalSwitch', dark, :loading='isToggleLoading')
//- v-icon(left) mdi-power
//- span(v-if='!enabled')
{{
$t
(
'admin.api.enableButton'
)
}}
//- span(v-else)
{{
$t
(
'admin.api.disableButton'
)
}}
//- v-btn.animated.fadeInDown(color='primary', depressed, large, @click='newKey', dark)
//- v-icon(left) mdi-plus
//- span
{{
$t
(
'admin.api.newKeyButton'
)
}}
//- v-card.mt-3.animated.fadeInUp
//- v-simple-table(v-if='keys && keys.length > 0')
//- template(v-slot:default)
//- thead
//- tr.grey(:class='$vuetify.theme.dark ? `darken-4-d5` : `lighten-5`')
//- th
{{
$t
(
'admin.api.headerName'
)
}}
//- th
{{
$t
(
'admin.api.headerKeyEnding'
)
}}
//- th
{{
$t
(
'admin.api.headerExpiration'
)
}}
//- th
{{
$t
(
'admin.api.headerCreated'
)
}}
//- th
{{
$t
(
'admin.api.headerLastUpdated'
)
}}
//- th(width='100')
{{
$t
(
'admin.api.headerRevoke'
)
}}
//- tbody
//- tr(v-for='key of keys', :key='`key-` + key.id')
//- td
//- strong(:class='key.isRevoked ? `red--text` : ``')
{{
key
.
name
}}
//- em.caption.ml-1.red--text(v-if='key.isRevoked') (revoked)
//- td.caption
{{
key
.
keyShort
}}
//- td(:style='key.isRevoked ? `text-decoration: line-through;` : ``')
{{
key
.
expiration
|
moment
(
'LL'
)
}}
//- td
{{
key
.
createdAt
|
moment
(
'calendar'
)
}}
//- td
{{
key
.
updatedAt
|
moment
(
'calendar'
)
}}
//- td: v-btn(icon, @click='revoke(key)', :disabled='key.isRevoked'): v-icon(color='error') mdi-cancel
//- v-card-text(v-else)
//- v-alert.mb-0(icon='mdi-information', :value='true', outlined, color='info')
{{
$t
(
'admin.api.noKeyInfo'
)
}}
//- create-api-key(v-model='isCreateDialogShown', @refresh='refresh(false)')
//- v-dialog(v-model='isRevokeConfirmDialogShown', max-width='500', persistent)
//- v-card
//- .dialog-header.is-red
{{
$t
(
'admin.api.revokeConfirm'
)
}}
//- v-card-text.pa-4
//- i18next(tag='span', path='admin.api.revokeConfirmText')
//- strong(place='name')
{{
current
.
name
}}
//- v-card-actions
//- v-spacer
//- v-btn(text, @click='isRevokeConfirmDialogShown = false', :disabled='revokeLoading')
{{
$t
(
'common.actions.cancel'
)
}}
//- v-btn(color='red', dark, @click='revokeConfirm', :loading='revokeLoading')
{{
$t
(
'admin.api.revoke'
)
}}
.col-12(v-if='state.keys.length < 1')
q-card.rounded-borders(
flat
:class='$q.dark.isActive ? `bg-dark-5 text-white` : `bg-grey-3 text-dark`'
)
q-card-section.items-center(horizontal)
q-card-section.col-auto.q-pr-none
q-icon(name='las la-info-circle', size='sm')
q-card-section.text-caption
{{
t
(
'admin.api.none'
)
}}
.col-12(v-else)
q-card
q-list(separator)
q-item(v-for='key of state.keys', :key='key.id')
q-item-section(side)
q-icon(name='las la-key', :color='key.isRevoked ? `negative` : `positive`')
q-item-section
q-item-label
{{
key
.
name
}}
q-item-label(caption) Ending in
{{
key
.
keyShort
}}
q-item-label(caption) Created On: #[strong
{{
DateTime
.
fromISO
(
key
.
createdAt
).
toFormat
(
'fff'
)
}}
]
q-item-label(caption) Expiration: #[strong(:style='key.isRevoked ? `text-decoration: line-through;` : ``')
{{
DateTime
.
fromISO
(
key
.
expiration
).
toFormat
(
'fff'
)
}}
]
q-item-section(
v-if='key.isRevoked'
side
style='flex-direction: row; align-items: center;'
)
q-icon.q-mr-sm(
color='negative'
size='xs'
name='las la-exclamation-triangle'
)
.text-caption.text-negative
{{
t
(
'admin.api.revoked'
)
}}
q-tooltip(anchor='center left', self='center right')
{{
t
(
'admin.api.revokedHint'
)
}}
q-separator.q-ml-md(vertical)
q-item-section(side, style='flex-direction: row; align-items: center;')
q-btn.acrylic-btn(
:color='key.isRevoked ? `gray` : `red`'
icon='las la-ban'
flat
@click='revoke(key)'
:disable='key.isRevoked'
)
</
template
>
<
script
setup
>
...
...
@@ -120,6 +98,10 @@ import { cloneDeep } from 'lodash-es'
import
{
useI18n
}
from
'vue-i18n'
import
{
useMeta
,
useQuasar
}
from
'quasar'
import
{
computed
,
onMounted
,
reactive
,
watch
}
from
'vue'
import
{
DateTime
}
from
'luxon'
import
ApiKeyCreateDialog
from
'../components/ApiKeyCreateDialog.vue'
import
ApiKeyRevokeDialog
from
'../components/ApiKeyRevokeDialog.vue'
// QUASAR
...
...
@@ -140,6 +122,7 @@ useMeta({
const
state
=
reactive
({
enabled
:
false
,
loading
:
0
,
isToggleLoading
:
false
,
keys
:
[],
isCreateDialogShown
:
false
,
isRevokeConfirmDialogShown
:
false
,
...
...
@@ -154,7 +137,7 @@ async function load () {
$q
.
loading
.
show
()
const
resp
=
await
APOLLO_CLIENT
.
query
({
query
:
gql
`
query get
Hook
s {
query get
ApiKey
s {
apiKeys {
id
name
...
...
@@ -175,23 +158,27 @@ async function load () {
state
.
loading
--
}
async
function
refresh
()
{
await
load
()
$q
.
notify
({
type
:
'positive'
,
message
:
t
(
'admin.api.refreshSuccess'
)
})
}
async
function
globalSwitch
()
{
state
.
isToggleLoading
=
true
try
{
const
resp
=
await
APOLLO_CLIENT
.
mutate
({
mutation
:
gql
`
mutation ($enabled: Boolean!) {
authentication {
setApiState (enabled: $enabled) {
responseResult
{
operation
{
succeeded
errorCode
slug
message
}
}
}
}
`
,
variables
:
{
enabled
:
!
state
.
enabled
...
...
@@ -204,7 +191,7 @@ async function globalSwitch () {
})
await
load
()
}
else
{
throw
new
Error
(
resp
?.
data
?.
setApiState
?.
operation
.
message
||
'An unexpected error occurred.'
)
throw
new
Error
(
resp
?.
data
?.
setApiState
?.
operation
?
.
message
||
'An unexpected error occurred.'
)
}
}
catch
(
err
)
{
$q
.
notify
({
...
...
@@ -217,62 +204,27 @@ async function globalSwitch () {
}
async
function
newKey
()
{
state
.
isCreateDialogShown
=
true
$q
.
dialog
({
component
:
ApiKeyCreateDialog
}).
onOk
(()
=>
{
load
()
})
}
function
revoke
(
key
)
{
state
.
current
=
key
state
.
isRevokeConfirmDialogShown
=
true
}
async
function
revokeConfirm
()
{
state
.
revokeLoading
=
true
try
{
const
resp
=
await
APOLLO_CLIENT
.
mutate
({
mutation
:
gql
`
mutation ($id: Int!) {
authentication {
revokeApiKey (id: $id) {
responseResult {
succeeded
errorCode
slug
message
}
}
}
}
`
,
variables
:
{
id
:
state
.
current
.
id
$q
.
dialog
({
component
:
ApiKeyRevokeDialog
,
componentProps
:
{
apiKey
:
key
}
}).
onOk
(()
=>
{
load
()
})
// if (_get(resp, 'data.authentication.revokeApiKey.responseResult.succeeded', false)) {
// this.$store.commit('showNotification', {
// style: 'success',
// message: this.$t('admin.api.revokeSuccess'),
// icon: 'check'
// })
// this.load()
// } else {
// this.$store.commit('showNotification', {
// style: 'red',
// message: _get(resp, 'data.authentication.revokeApiKey.responseResult.message', 'An unexpected error occurred.'),
// icon: 'alert'
// })
// }
}
catch
(
err
)
{
// this.$store.commit('pushGraphError', err)
}
state
.
isRevokeConfirmDialogShown
=
false
state
.
revokeLoading
=
false
}
// MOUNTED
onMounted
(()
=>
{
load
()
})
onMounted
(
load
)
</
script
>
...
...
ux/src/pages/AdminApiCreate.vue
deleted
100644 → 0
View file @
6625267b
<
template
lang=
"pug"
>
div
v-dialog(v-model='isShown', max-width='650', persistent)
v-card
.dialog-header.is-short
v-icon.mr-3(color='white') mdi-plus
span
{{
$t
(
'admin.api.newKeyTitle'
)
}}
v-card-text.pt-5
v-text-field(
outlined
prepend-icon='mdi-format-title'
v-model='name'
:label='$t(`admin.api.newKeyName`)'
persistent-hint
ref='keyNameInput'
:hint='$t(`admin.api.newKeyNameHint`)'
counter='255'
)
v-select.mt-3(
:items='expirations'
outlined
prepend-icon='mdi-clock'
v-model='expiration'
:label='$t(`admin.api.newKeyExpiration`)'
:hint='$t(`admin.api.newKeyExpirationHint`)'
persistent-hint
)
v-divider.mt-4
v-subheader.pl-2: strong.indigo--text
{{
$t
(
'admin.api.newKeyPermissionScopes'
)
}}
v-list.pl-8(nav)
v-list-item-group(v-model='fullAccess')
v-list-item(
:value='true'
active-class='indigo--text'
)
template(v-slot:default='{ active, toggle }')
v-list-item-action
v-checkbox(
:input-value='active'
:true-value='true'
color='indigo'
@click='toggle'
)
v-list-item-content
v-list-item-title
{{
$t
(
'admin.api.newKeyFullAccess'
)
}}
v-divider.mt-3
v-subheader.caption.indigo--text
{{
$t
(
'admin.api.newKeyGroupPermissions'
)
}}
v-list-item
v-select(
:disabled='fullAccess'
:items='groups'
item-text='name'
item-value='id'
outlined
color='indigo'
v-model='group'
:label='$t(`admin.api.newKeyGroup`)'
:hint='$t(`admin.api.newKeyGroupHint`)'
persistent-hint
)
v-card-chin
v-spacer
v-btn(text, @click='isShown = false', :disabled='loading')
{{
$t
(
'common.actions.cancel'
)
}}
v-btn.px-3(depressed, color='primary', @click='generate', :loading='loading')
v-icon(left) mdi-chevron-right
span
{{
$t
(
'common.actions.generate'
)
}}
v-dialog(
v-model='isCopyKeyDialogShown'
max-width='750'
persistent
overlay-color='blue darken-5'
overlay-opacity='.9'
)
v-card
v-toolbar(dense, flat, color='primary', dark)
{{
$t
(
'admin.api.newKeyTitle'
)
}}
v-card-text.pt-5
.body-2.text-center
i18next(tag='span', path='admin.api.newKeyCopyWarn')
strong(place='bold')
{{
$t
(
'admin.api.newKeyCopyWarnBold'
)
}}
v-textarea.mt-3(
ref='keyContentsIpt'
filled
no-resize
readonly
v-model='key'
:rows='10'
hide-details
)
v-card-chin
v-spacer
v-btn.px-3(depressed, dark, color='primary', @click='isCopyKeyDialogShown = false')
{{
$t
(
'common.actions.close'
)
}}
</
template
>
<
script
>
import
_
from
'lodash'
import
gql
from
'graphql-tag'
import
groupsQuery
from
'gql/admin/users/users-query-groups.gql'
export
default
{
props
:
{
value
:
{
type
:
Boolean
,
default
:
false
}
},
data
()
{
return
{
loading
:
false
,
name
:
''
,
expiration
:
'1y'
,
fullAccess
:
true
,
groups
:
[],
group
:
null
,
isCopyKeyDialogShown
:
false
,
key
:
''
}
},
computed
:
{
isShown
:
{
get
()
{
return
this
.
value
},
set
(
val
)
{
this
.
$emit
(
'input'
,
val
)
}
},
expirations
()
{
return
[
{
value
:
'30d'
,
text
:
this
.
$t
(
'admin.api.expiration30d'
)
},
{
value
:
'90d'
,
text
:
this
.
$t
(
'admin.api.expiration90d'
)
},
{
value
:
'180d'
,
text
:
this
.
$t
(
'admin.api.expiration180d'
)
},
{
value
:
'1y'
,
text
:
this
.
$t
(
'admin.api.expiration1y'
)
},
{
value
:
'3y'
,
text
:
this
.
$t
(
'admin.api.expiration3y'
)
}
]
}
},
watch
:
{
value
(
newValue
,
oldValue
)
{
if
(
newValue
)
{
setTimeout
(()
=>
{
this
.
$refs
.
keyNameInput
.
focus
()
},
400
)
}
}
},
methods
:
{
async
generate
()
{
try
{
if
(
_
.
trim
(
this
.
name
).
length
<
2
||
this
.
name
.
length
>
255
)
{
throw
new
Error
(
this
.
$t
(
'admin.api.newKeyNameError'
))
}
else
if
(
!
this
.
fullAccess
&&
!
this
.
group
)
{
throw
new
Error
(
this
.
$t
(
'admin.api.newKeyGroupError'
))
}
else
if
(
!
this
.
fullAccess
&&
this
.
group
===
2
)
{
throw
new
Error
(
this
.
$t
(
'admin.api.newKeyGuestGroupError'
))
}
}
catch
(
err
)
{
return
this
.
$store
.
commit
(
'showNotification'
,
{
style
:
'red'
,
message
:
err
,
icon
:
'alert'
})
}
this
.
loading
=
true
try
{
const
resp
=
await
this
.
$apollo
.
mutate
({
mutation
:
gql
`
mutation ($name: String!, $expiration: String!, $fullAccess: Boolean!, $group: Int) {
authentication {
createApiKey (name: $name, expiration: $expiration, fullAccess: $fullAccess, group: $group) {
key
responseResult {
succeeded
errorCode
slug
message
}
}
}
}
`
,
variables
:
{
name
:
this
.
name
,
expiration
:
this
.
expiration
,
fullAccess
:
(
this
.
fullAccess
===
true
),
group
:
this
.
group
},
watchLoading
(
isLoading
)
{
this
.
$store
.
commit
(
`loading
${
isLoading
?
'Start'
:
'Stop'
}
`
,
'admin-api-create'
)
}
})
if
(
_
.
get
(
resp
,
'data.authentication.createApiKey.responseResult.succeeded'
,
false
))
{
this
.
$store
.
commit
(
'showNotification'
,
{
style
:
'success'
,
message
:
this
.
$t
(
'admin.api.newKeySuccess'
),
icon
:
'check'
})
this
.
name
=
''
this
.
expiration
=
'1y'
this
.
fullAccess
=
true
this
.
group
=
null
this
.
isShown
=
false
this
.
$emit
(
'refresh'
)
this
.
key
=
_
.
get
(
resp
,
'data.authentication.createApiKey.key'
,
'???'
)
this
.
isCopyKeyDialogShown
=
true
setTimeout
(()
=>
{
this
.
$refs
.
keyContentsIpt
.
$refs
.
input
.
select
()
},
400
)
}
else
{
this
.
$store
.
commit
(
'showNotification'
,
{
style
:
'red'
,
message
:
_
.
get
(
resp
,
'data.authentication.createApiKey.responseResult.message'
,
'An unexpected error occurred.'
),
icon
:
'alert'
})
}
}
catch
(
err
)
{
this
.
$store
.
commit
(
'pushGraphError'
,
err
)
}
this
.
loading
=
false
}
},
apollo
:
{
groups
:
{
query
:
groupsQuery
,
fetchPolicy
:
'network-only'
,
update
:
(
data
)
=>
data
.
groups
.
list
,
watchLoading
(
isLoading
)
{
this
.
$store
.
commit
(
`loading
${
isLoading
?
'Start'
:
'Stop'
}
`
,
'admin-api-groups-refresh'
)
}
}
}
}
</
script
>
ux/src/pages/AdminAuth.vue
View file @
7fe7fbb3
...
...
@@ -162,8 +162,9 @@ q-page.admin-mail
.text-subtitle1
{{
state
.
strategy
.
strategy
.
title
}}
q-img.q-mt-sm.rounded-borders(
:src='state.strategy.strategy.logo'
fit='co
ver
'
fit='co
ntain
'
no-spinner
style='height: 100px;'
)
.text-body2.q-mt-md
{{
state
.
strategy
.
strategy
.
description
}}
q-separator.q-mb-sm(inset)
...
...
ux/src/pages/AdminDashboard.vue
View file @
7fe7fbb3
...
...
@@ -97,12 +97,13 @@ q-page.admin-dashboard
template(#action)
q-btn(
flat
label='Check'
:label='t(`admin.system.checkForUpdates`)'
@click='checkForUpdates'
)
q-separator.q-mx-sm(vertical, dark)
q-btn(
flat
label='System Info
'
:label='t(`admin.system.title`)
'
to='/_admin/system'
)
.col-12
...
...
@@ -224,6 +225,7 @@ import { useAdminStore } from '../stores/admin'
// COMPONENTS
import
CheckUpdateDialog
from
'../components/CheckUpdateDialog.vue'
import
SiteCreateDialog
from
'../components/SiteCreateDialog.vue'
import
UserCreateDialog
from
'../components/UserCreateDialog.vue'
...
...
@@ -265,6 +267,11 @@ function newUser () {
router
.
push
(
'/_admin/users'
)
}
)
}
function
checkForUpdates
()
{
$q
.
dialog
({
component
:
CheckUpdateDialog
}
)
}
<
/script
>
...
...
ux/src/pages/AdminFlags.vue
View file @
7fe7fbb3
...
...
@@ -77,6 +77,10 @@ q-page.admin-flags
unchecked-icon='las la-times'
:aria-label='t(`admin.flags.hidedonatebtn.label`)'
)
.col-12.col-lg-5.gt-md
.q-pa-md.text-center
img(src='/_assets/illustrations/undraw_settings.svg', style='width: 80%;')
</
template
>
<
script
setup
>
...
...
ux/src/pages/AdminLocale.vue
View file @
7fe7fbb3
...
...
@@ -117,6 +117,9 @@ q-page.admin-locale
:
aria
-
label
=
'lc.name'
)
.
q
-
pa
-
md
.
text
-
center
.
gt
-
md
(
v
-
else
)
img
(
src
=
'/_assets/illustrations/undraw_world.svg'
,
style
=
'width: 80%;'
)
//- q-separator.q-my-sm(inset)
//- q-item
//- blueprint-icon(icon='test-passed')
...
...
ux/src/pages/AdminSystem.vue
View file @
7fe7fbb3
...
...
@@ -54,7 +54,16 @@ q-page.admin-system
q-item-label
{{
t
(
'admin.system.latestVersion'
)
}}
q-item-label(caption)
{{
t
(
'admin.system.latestVersionHint'
)
}}
q-item-section
q-item-label.dark-value(caption)
{{
state
.
info
.
latestVersion
}}
.row.q-col-gutter-sm
.col
.dark-value(caption)
{{
state
.
info
.
latestVersion
}}
.col-auto
q-btn.acrylic-btn(
flat
color='purple'
@click='checkForUpdates'
:label='t(`admin.system.checkUpdate`)'
)
//- -----------------------
//- CLIENT
...
...
@@ -234,6 +243,8 @@ import { useMeta, useQuasar } from 'quasar'
import
{
computed
,
onMounted
,
reactive
,
ref
,
watch
}
from
'vue'
import
ClipboardJS
from
'clipboard'
import
CheckUpdateDialog
from
'../components/CheckUpdateDialog.vue'
// QUASAR
const
$q
=
useQuasar
()
...
...
@@ -340,6 +351,12 @@ async function load () {
state
.
loading
--
}
function
checkForUpdates
()
{
$q
.
dialog
({
component
:
CheckUpdateDialog
})
}
// async function performUpgrade () {
// state.isUpgrading = true
// state.isUpgradingStarted = false
...
...
ux/yarn.lock
View file @
7fe7fbb3
This diff was suppressed by a .gitattributes entry.
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