update
@ -4,7 +4,7 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<link rel="icon" href="/favicon.ico">
|
<link rel="icon" href="/favicon.ico">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Vite App</title>
|
<title>Freeleaps</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
|||||||
@ -17,6 +17,7 @@
|
|||||||
"pdfjs-dist": "^4.3.136",
|
"pdfjs-dist": "^4.3.136",
|
||||||
"pinia": "^2.1.6",
|
"pinia": "^2.1.6",
|
||||||
"vue": "^3.3.4",
|
"vue": "^3.3.4",
|
||||||
|
"vue-i18n": "^9.13.1",
|
||||||
"vue-router": "^4.2.4",
|
"vue-router": "^4.2.4",
|
||||||
"vuex": "^4.1.0"
|
"vuex": "^4.1.0"
|
||||||
},
|
},
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 16 KiB |
@ -1,5 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="app-body">
|
<div class="app-body">
|
||||||
|
<img src="@/assets/images/home-bg-left.png" alt="freeleaps" class="app-bg-left">
|
||||||
|
<img src="@/assets/images/home-bg-right.png" alt="freeleaps" class="app-bg-right">
|
||||||
<header class="body-header">
|
<header class="body-header">
|
||||||
<router-view name="header"></router-view>
|
<router-view name="header"></router-view>
|
||||||
</header>
|
</header>
|
||||||
@ -34,6 +36,22 @@ export default {
|
|||||||
margin-top: 0px;
|
margin-top: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.app-bg-left {
|
||||||
|
width: 300px;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-bg-right {
|
||||||
|
width: 300px;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
.body-header {
|
.body-header {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: $header-height;
|
height: $header-height;
|
||||||
|
|||||||
BIN
frontend/src/assets/images/home-bg-left.png
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
frontend/src/assets/images/home-bg-right.png
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
frontend/src/assets/lang/us.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
frontend/src/assets/lang/zh.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
@ -1 +1,8 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 261.76 226.69"><path d="M161.096.001l-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z" fill="#41b883"/><path d="M161.096.001l-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z" fill="#34495e"/></svg>
|
<svg width="12" height="19" viewBox="0 0 12 19" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M2.56464 6.68937L0 9.35254L2.56464 12.0157L5.12928 9.35254L2.56464 6.68937Z" fill="#A4CBFA"/>
|
||||||
|
<path d="M5.78339 3.34465L3.21875 6.00781L5.78339 8.67098L8.34803 6.00781L5.78339 3.34465Z" fill="#5E8AF9"/>
|
||||||
|
<path d="M5.78729 10.0321L3.22266 12.6953L5.78729 15.3585L8.35193 12.6953L5.78729 10.0321Z" fill="#5E8AF9"/>
|
||||||
|
<path d="M9.00995 13.3798L6.44531 16.043L9.00995 18.7061L11.5746 16.043L9.00995 13.3798Z" fill="#1748F8"/>
|
||||||
|
<path d="M9.00214 6.68742L6.4375 9.35059L9.00214 12.0138L11.5668 9.35059L9.00214 6.68742Z" fill="#1748F8"/>
|
||||||
|
<path d="M9.00604 -7.86142e-05L6.44141 2.66309L9.00604 5.32625L11.5707 2.66309L9.00604 -7.86142e-05Z" fill="#1748F8"/>
|
||||||
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 276 B After Width: | Height: | Size: 757 B |
@ -44,6 +44,10 @@ $header-height: 88px;
|
|||||||
$footer-height: 110px;
|
$footer-height: 110px;
|
||||||
$body-height: calc(100vh - $header-height - $footer-height);
|
$body-height: calc(100vh - $header-height - $footer-height);
|
||||||
$body-width: 1288px;
|
$body-width: 1288px;
|
||||||
|
|
||||||
|
$accordion-icon-width: 1rem;
|
||||||
|
$accordion-button-icon: url("data:image/svg+xml,<svg viewBox='0 0 1331 1024' xmlns='http://www.w3.org/2000/svg' width='64' height='64'><path d='M552.5504 896.512L45.1584 244.1216A102.4 102.4 0 0 1 125.952 78.848h1014.784a102.4 102.4 0 0 1 80.896 165.2736l-507.4944 652.288a102.4 102.4 0 0 1-161.6896 0z'></path></svg>");
|
||||||
|
$accordion-button-active-icon: url("data:image/svg+xml,<svg viewBox='0 0 1331 1024' xmlns='http://www.w3.org/2000/svg' width='64' height='64'><path d='M552.5504 896.512L45.1584 244.1216A102.4 102.4 0 0 1 125.952 78.848h1014.784a102.4 102.4 0 0 1 80.896 165.2736l-507.4944 652.288a102.4 102.4 0 0 1-161.6896 0z'></path></svg>");
|
||||||
// $default-font: "Lato", Verdana, Arial, sans-serif;
|
// $default-font: "Lato", Verdana, Arial, sans-serif;
|
||||||
|
|
||||||
// $link-color: #ef899e;
|
// $link-color: #ef899e;
|
||||||
|
|||||||
@ -179,6 +179,16 @@ p {
|
|||||||
padding: 12px 28px 12px 12px;
|
padding: 12px 28px 12px 12px;
|
||||||
outline: none;
|
outline: none;
|
||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
bottom: 0;
|
||||||
|
left: 50%;
|
||||||
|
width: 0;
|
||||||
|
height: 1px;
|
||||||
|
position: absolute;
|
||||||
|
background-color: #dee2e6;
|
||||||
|
transition: all 300ms ease-in-out;
|
||||||
|
}
|
||||||
.dashed-container {
|
.dashed-container {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
margin-right: 28px;
|
margin-right: 28px;
|
||||||
@ -191,7 +201,11 @@ p {
|
|||||||
color: black;
|
color: black;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
border-bottom: 1px solid #dee2e6;
|
// border-bottom: 1px solid #dee2e6;
|
||||||
|
&::before {
|
||||||
|
left: 0;
|
||||||
|
width: 100%;;
|
||||||
|
}
|
||||||
.dashed-container {
|
.dashed-container {
|
||||||
background-color: #f3f6ff;
|
background-color: #f3f6ff;
|
||||||
}
|
}
|
||||||
@ -232,3 +246,11 @@ p {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input:-webkit-autofill {
|
||||||
|
box-shadow:0 0 0 1000px white inset !important;
|
||||||
|
}
|
||||||
|
input:-internal-autofill-previewed,
|
||||||
|
input:-internal-autofill-selected {
|
||||||
|
transition: background-color 5000s ease-in-out 0s !important;
|
||||||
|
}
|
||||||
@ -237,7 +237,6 @@ export default {
|
|||||||
getSelect() {
|
getSelect() {
|
||||||
if (window.getSelection) {
|
if (window.getSelection) {
|
||||||
let sel = window.getSelection()
|
let sel = window.getSelection()
|
||||||
console.log('this.selectedRange', sel)
|
|
||||||
if (sel.rangeCount > 0) {
|
if (sel.rangeCount > 0) {
|
||||||
return sel.getRangeAt(0)
|
return sel.getRangeAt(0)
|
||||||
}
|
}
|
||||||
@ -290,6 +289,7 @@ export default {
|
|||||||
default:
|
default:
|
||||||
console.log('none')
|
console.log('none')
|
||||||
}
|
}
|
||||||
|
this.$refs.editor.blur()
|
||||||
// window.getSelection().removeAllRanges()
|
// window.getSelection().removeAllRanges()
|
||||||
},
|
},
|
||||||
restoreSelection() {
|
restoreSelection() {
|
||||||
@ -307,7 +307,9 @@ export default {
|
|||||||
|
|
||||||
updateAction($event) {
|
updateAction($event) {
|
||||||
let html = $event.target.innerHTML || ''
|
let html = $event.target.innerHTML || ''
|
||||||
|
setTimeout(() => {
|
||||||
this.$emit('update:content', html)
|
this.$emit('update:content', html)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
66
frontend/src/components/LaguageSwitch.vue
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<template>
|
||||||
|
<div class="laguage-switch-container">
|
||||||
|
<button class="btn btn-link btn-link-switch" data-bs-toggle="dropdown" aria-expanded="false" id="language-switch-button">
|
||||||
|
<img :src="languageMapper[currentLanguage]" alt="freeleap language">
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu" aria-labelledby="language-switch-button">
|
||||||
|
<template v-for="item in languageList" :key="item">
|
||||||
|
<li v-if="item != currentLanguage">
|
||||||
|
<button class="btn btn-link btn-link-switch" @click="changeLanguage(item)">
|
||||||
|
<img :src="languageMapper[item]" alt="freeleap zh">
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</template>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import zh_icon from '@/assets/lang/zh.png'
|
||||||
|
import en_icon from '@/assets/lang/us.png'
|
||||||
|
export default {
|
||||||
|
name: 'LaguageSwitch',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
languageList: ["zh", "en"],
|
||||||
|
languageMapper: {
|
||||||
|
"zh": zh_icon,
|
||||||
|
"en": en_icon
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
currentLanguage() {
|
||||||
|
return this.$store.getters['basic/language']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
changeLanguage(l) {
|
||||||
|
this.$store.dispatch('basic/setLanguage', l)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.laguage-switch-container {
|
||||||
|
display: inline;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.btn-link-switch {
|
||||||
|
padding: 0;
|
||||||
|
width: 35px;
|
||||||
|
line-height: 1;
|
||||||
|
|
||||||
|
img {width: 100%;}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu {
|
||||||
|
min-width: auto;
|
||||||
|
margin-left: -5px !important;
|
||||||
|
|
||||||
|
.btn-link-switch {
|
||||||
|
padding: 0 5px;
|
||||||
|
width: 45px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -87,5 +87,8 @@ export default {
|
|||||||
right: 0;
|
right: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
}
|
}
|
||||||
|
canvas {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -13,20 +13,22 @@
|
|||||||
>
|
>
|
||||||
</div> -->
|
</div> -->
|
||||||
<div class="public-sites">
|
<div class="public-sites">
|
||||||
<button class="public-site-button" @click="gotoAbout()">About</button>
|
<button class="public-site-button" @click="gotoAbout()">{{ $t('About') }}</button>
|
||||||
<button class="public-site-button" @click="gotoBlogs()">Blogs</button>
|
<button class="public-site-button" @click="gotoBlogs()">{{ $t('Blogs') }}</button>
|
||||||
<button class="public-site-button" @click="gotoCareer()">Career</button>
|
<button class="public-site-button" @click="gotoCareer()">{{ $t('Career') }}</button>
|
||||||
<button class="public-site-button" @click="gotoContact()">
|
<button class="public-site-button" @click="gotoContact()">{{ $t('Contact') }}</button>
|
||||||
{{ getContactText }}
|
<laguage-switch />
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
import LaguageSwitch from '@/components/LaguageSwitch.vue'
|
||||||
|
// import { i18n } from '@/lang'
|
||||||
|
// const { t } = i18n.global
|
||||||
export default {
|
export default {
|
||||||
name: 'HeaderGuest',
|
name: 'HeaderGuest',
|
||||||
components: {},
|
components: { LaguageSwitch },
|
||||||
computed: {
|
computed: {
|
||||||
getContactText() {
|
getContactText() {
|
||||||
if (this.getRegion === 'CN') {
|
if (this.getRegion === 'CN') {
|
||||||
@ -44,6 +46,9 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
// translate(content) {
|
||||||
|
// return i18n.global.t(content)
|
||||||
|
// },
|
||||||
gotoFrontdoor() {
|
gotoFrontdoor() {
|
||||||
this.mnx_navToFrontDoor()
|
this.mnx_navToFrontDoor()
|
||||||
},
|
},
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
<div
|
<div
|
||||||
class="information-bar"
|
class="information-bar"
|
||||||
@click="gotoMessages"
|
@click="gotoMessages"
|
||||||
:class="activePath == 'message' ? 'active' : ''"
|
:class="{'active' : activePath == 'message', 'unread' : unreadCount > 0}"
|
||||||
>
|
>
|
||||||
<img alt="freeleaps logo" src="@/assets/message.png" />
|
<img alt="freeleaps logo" src="@/assets/message.png" />
|
||||||
</div>
|
</div>
|
||||||
@ -56,6 +56,7 @@
|
|||||||
Please go to profile page to add money receiving method
|
Please go to profile page to add money receiving method
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<laguage-switch class="laguage-switch" />
|
||||||
</div>
|
</div>
|
||||||
<div class="profile-container">
|
<div class="profile-container">
|
||||||
<img
|
<img
|
||||||
@ -87,15 +88,21 @@
|
|||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { UserAuthApi } from '@/utils/backend/index'
|
import { UserAuthApi } from '@/utils/backend/index'
|
||||||
|
import LaguageSwitch from '@/components/LaguageSwitch.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'HeaderGuest',
|
name: 'HeaderGuest',
|
||||||
components: {},
|
components: { LaguageSwitch },
|
||||||
computed: {},
|
computed: {
|
||||||
|
unreadCount() {
|
||||||
|
return this.$store.getters['basic/unreadCount']
|
||||||
|
}
|
||||||
|
},
|
||||||
created() {
|
created() {
|
||||||
if (this.userIdentityNote.length > 8) {
|
if (this.userIdentityNote.length > 8) {
|
||||||
this.userIdentityNote = this.userIdentityNote.slice(0, 5) + '...'
|
this.userIdentityNote = this.userIdentityNote.slice(0, 5) + '...'
|
||||||
}
|
}
|
||||||
|
this.$store.dispatch('basic/initWebsocket', this.mnx_getUserAuthToken())
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -157,6 +164,9 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
.laguage-switch {
|
||||||
|
margin-left: 30px;
|
||||||
|
}
|
||||||
.header-container {
|
.header-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@ -191,7 +201,7 @@ export default {
|
|||||||
|
|
||||||
&::after {
|
&::after {
|
||||||
content: '';
|
content: '';
|
||||||
display: block;
|
display: none;
|
||||||
width: 8px;
|
width: 8px;
|
||||||
height: 8px;
|
height: 8px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
@ -201,6 +211,10 @@ export default {
|
|||||||
background-color: #f44837;
|
background-color: #f44837;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.unread::after {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
border: 1px solid $primary;
|
border: 1px solid $primary;
|
||||||
}
|
}
|
||||||
@ -244,7 +258,7 @@ export default {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
left: 0;
|
left: 0;
|
||||||
bottom: -20px;
|
bottom: -24px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #3d455f;
|
color: #3d455f;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|||||||
6
frontend/src/lang/en.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export default {
|
||||||
|
"About": "About",
|
||||||
|
"Blogs": "Blogs",
|
||||||
|
"Career": "Career",
|
||||||
|
"Contact": "Contact",
|
||||||
|
}
|
||||||
32
frontend/src/lang/index.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { createI18n } from 'vue-i18n'
|
||||||
|
import en from './en'
|
||||||
|
import zh from './zh'
|
||||||
|
const messages = { en, zh }
|
||||||
|
|
||||||
|
const getDefaultLocale = () => {
|
||||||
|
let defaultLanguage = localStorage.getItem('language')
|
||||||
|
if (defaultLanguage) {
|
||||||
|
return defaultLanguage
|
||||||
|
}
|
||||||
|
const lan = (navigator.browserLanguage || navigator.language).toLowerCase()
|
||||||
|
if (lan.indexOf('zh') > -1) {
|
||||||
|
defaultLanguage = 'zh'
|
||||||
|
} else if (lan.indexOf('en') > -1) {
|
||||||
|
defaultLanguage = 'en'
|
||||||
|
}
|
||||||
|
return defaultLanguage || 'zh'
|
||||||
|
}
|
||||||
|
|
||||||
|
const localeData = {
|
||||||
|
globalInjection: true,
|
||||||
|
legacy: false,
|
||||||
|
locale: getDefaultLocale(),
|
||||||
|
messages
|
||||||
|
}
|
||||||
|
|
||||||
|
export const i18n = createI18n(localeData)
|
||||||
|
export const setupI18n = {
|
||||||
|
install(app) {
|
||||||
|
app.use(i18n)
|
||||||
|
}
|
||||||
|
}
|
||||||
3
frontend/src/lang/zh.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export default {
|
||||||
|
"Contact": "联系我们"
|
||||||
|
}
|
||||||
@ -5,6 +5,7 @@ import { store, router } from './plugins/index'
|
|||||||
import { navigatorMixin, userIdentityMixin, errorHanlderMixin, userAuthMixin } from './mixins/index'
|
import { navigatorMixin, userIdentityMixin, errorHanlderMixin, userAuthMixin } from './mixins/index'
|
||||||
import { tooltip } from './utils/index'
|
import { tooltip } from './utils/index'
|
||||||
|
|
||||||
|
import { setupI18n } from '@/lang'
|
||||||
/* import the fontawesome core */
|
/* import the fontawesome core */
|
||||||
// import { library } from '@fortawesome/fontawesome-svg-core'
|
// import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
/* import font awesome icon component */
|
/* import font awesome icon component */
|
||||||
@ -31,6 +32,7 @@ import { tooltip } from './utils/index'
|
|||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
app.use(store)
|
app.use(store)
|
||||||
app.use(router)
|
app.use(router)
|
||||||
|
app.use(setupI18n)
|
||||||
app.mixin(userIdentityMixin)
|
app.mixin(userIdentityMixin)
|
||||||
app.mixin(navigatorMixin)
|
app.mixin(navigatorMixin)
|
||||||
app.mixin(errorHanlderMixin)
|
app.mixin(errorHanlderMixin)
|
||||||
|
|||||||
@ -40,6 +40,7 @@ import {
|
|||||||
import { signinActionEnum } from '@/types/index'
|
import { signinActionEnum } from '@/types/index'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: {},
|
||||||
name: 'FrontDoor',
|
name: 'FrontDoor',
|
||||||
props: {},
|
props: {},
|
||||||
data() {
|
data() {
|
||||||
|
|||||||
@ -6,9 +6,10 @@
|
|||||||
:key="index"
|
:key="index"
|
||||||
@click="view_link(directory)"
|
@click="view_link(directory)"
|
||||||
>
|
>
|
||||||
<p>{{ directory.title_text }}</p>
|
|
||||||
<img class="directory_cover_image" :src="directory.cover_picture" />
|
<img class="directory_cover_image" :src="directory.cover_picture" />
|
||||||
<p>{{ directory.summary_text }}</p>
|
<p class="directory-title">{{ directory.title_text }}</p>
|
||||||
|
<p class="directory-subtitle">{{ directory.summary_text }}</p>
|
||||||
|
<button class="btn btn-link">Read More</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -46,13 +47,34 @@ export default {
|
|||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.directories_containter {
|
.directories_containter {
|
||||||
@extend .container;
|
@extend .container;
|
||||||
|
padding: 56px 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.directory_container {
|
.directory_container {
|
||||||
@extend .container;
|
@extend .container;
|
||||||
|
padding: 0;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
|
.btn-link {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
text-decoration: underline;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.directory_cover_image {
|
.directory_cover_image {
|
||||||
height: 20vh;
|
width: 100%;
|
||||||
|
border-radius: 16px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
.directory-title {
|
||||||
|
font-size: 48px;
|
||||||
|
// font-weight: bold;
|
||||||
|
color: #18181A;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
.directory-subtitle {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666666;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -48,14 +48,20 @@ export default {
|
|||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.blogs_containter {
|
.blogs_containter {
|
||||||
@extend .container;
|
@extend .container;
|
||||||
|
padding: 56px 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.blog_containter {
|
.blog_containter {
|
||||||
@extend .container;
|
@extend .container;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
h2, p {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.blog_cover_image {
|
.blog_cover_image {
|
||||||
height: 20vh;
|
height: 311px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,19 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="directories_containter">
|
<div class="career_containter">
|
||||||
<div
|
<div
|
||||||
class="directory_container"
|
class="career-item"
|
||||||
v-for="(directory, index) in directories"
|
v-for="(directory, index) in directories"
|
||||||
:key="index"
|
:key="index"
|
||||||
@click="view_link(directory)"
|
@click="view_link(directory)"
|
||||||
>
|
>
|
||||||
<p
|
<p class="career-title">
|
||||||
class="directory_title_txt"
|
{{ directory.title_text }}
|
||||||
v-tooltip
|
|
||||||
:title="directory.summary_text"
|
|
||||||
delay='{"show":"500", "hide":"100"}'
|
|
||||||
>
|
|
||||||
<u>{{ directory.title_text }}</u>
|
|
||||||
</p>
|
</p>
|
||||||
|
<p>{{ directory.summary_text }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -48,15 +44,25 @@ export default {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.directories_containter {
|
.career_containter {
|
||||||
@extend .container;
|
@extend .container;
|
||||||
}
|
max-width: 1000px;
|
||||||
|
|
||||||
.directory_container {
|
.career-item {
|
||||||
@extend .container;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
box-shadow: 0px 0px 24px 0px #D4D3E380;
|
||||||
|
padding: 32px;
|
||||||
|
color: #18181A;
|
||||||
|
font-size: 14px;
|
||||||
|
background-color: white;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
.directory_title_txt {
|
p {margin: 0;}
|
||||||
|
.career-title {
|
||||||
|
font-size: 32px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,8 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="directories_containter">
|
<div class="contact-container">
|
||||||
<div class="directory_container" v-for="(directory, index) in directories" :key="index">
|
<div class="contact-item" v-for="(directory, index) in directories" :key="index">
|
||||||
<img class="directory_cover_image" :src="directory.cover_picture" />
|
<div class="contact-left">
|
||||||
<div v-html="directory.content_html"></div>
|
<img :src="directory.cover_picture" />
|
||||||
|
<div class="contact-left-content">
|
||||||
|
<p class="contact-title-text">{{ directory.title_text }}</p>
|
||||||
|
<p>{{ directory.summary_text }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="contact-right" v-html="directory.content_html"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -34,6 +40,61 @@ export default {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
.contact-container {
|
||||||
|
display: flex;
|
||||||
|
padding: 42px;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.contact-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
margin-bottom: 62px;
|
||||||
|
|
||||||
|
.contact-left {
|
||||||
|
border-radius: 12px;
|
||||||
|
background-color: $primary;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
width: 368px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.contact-left-content {
|
||||||
|
padding: 32px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
text-align: left;
|
||||||
|
color: white;
|
||||||
|
flex: 1;
|
||||||
|
font-size: 14px;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contact-title-text {
|
||||||
|
font-size: 32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.contact-right {
|
||||||
|
margin-left: 24px;
|
||||||
|
box-shadow: 0px 0px 24px 0px #D4D3E380;
|
||||||
|
background: white;
|
||||||
|
padding: 32px;
|
||||||
|
color: #18181A;
|
||||||
|
border-radius: 12px;
|
||||||
|
width: 368px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.directories_containter {
|
.directories_containter {
|
||||||
@extend .container;
|
@extend .container;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,148 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="history-container">
|
||||||
<p>History</p>
|
<div class="history-content">
|
||||||
|
<div class="accordion accordion-list" id="accordion-history-total">
|
||||||
|
<div class="accordion-item">
|
||||||
|
<h2 class="accordion-header">
|
||||||
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="collapse-history-total" aria-expanded="false" aria-controls="collapse-history-total">
|
||||||
|
<div class="history-bar dashed-container">
|
||||||
|
<div class="history-bar-container">
|
||||||
|
<div class="history-bar-item">
|
||||||
|
<label class="history-item-label">Total earning</label>
|
||||||
|
<p class="history-item-text">2000USD</p>
|
||||||
|
</div>
|
||||||
|
<div class="history-bar-item">
|
||||||
|
<label class="history-item-label">Paid</label>
|
||||||
|
<p class="history-item-text">2000USD</p>
|
||||||
|
</div>
|
||||||
|
<div class="history-bar-item">
|
||||||
|
<label class="history-item-label">Payable</label>
|
||||||
|
<p class="history-item-text">2000USD</p>
|
||||||
|
</div>
|
||||||
|
<div class="history-bar-item">
|
||||||
|
<label class="history-item-label">Total spending</label>
|
||||||
|
<p class="history-item-text">2000USD</p>
|
||||||
|
</div>
|
||||||
|
<div class="history-bar-item">
|
||||||
|
<label class="history-item-label">Deposit</label>
|
||||||
|
<p class="history-item-text">2000USD</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</h2>
|
||||||
|
<div id="collapse-history-total" class="accordion-collapse collapse" data-bs-parent="#accordion-history-total">
|
||||||
|
<div class="accordion-body">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="accordion accordion-list" id="accordion-history-total">
|
||||||
|
<div class="accordion-item">
|
||||||
|
<h2 class="accordion-header">
|
||||||
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="collapse-history-total" aria-expanded="false" aria-controls="collapse-history-total">
|
||||||
|
<div class="history-bar dashed-container">
|
||||||
|
<div class="history-bar-container">
|
||||||
|
<div class="history-bar-item">
|
||||||
|
<label class="history-item-label">Summary</label>
|
||||||
|
<p class="history-item-text">Need a python programmer</p>
|
||||||
|
</div>
|
||||||
|
<div class="history-bar-item">
|
||||||
|
<label class="history-item-label">Spending</label>
|
||||||
|
<p class="history-item-text">2000USD</p>
|
||||||
|
</div>
|
||||||
|
<div class="history-bar-item">
|
||||||
|
<label class="history-item-label">Updated</label>
|
||||||
|
<p class="history-item-text">2023-10-19</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</h2>
|
||||||
|
<div id="collapse-history-total" class="accordion-collapse collapse" data-bs-parent="#accordion-history-total">
|
||||||
|
<div class="accordion-body">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="accordion-item">
|
||||||
|
<h2 class="accordion-header">
|
||||||
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="collapse-history-total" aria-expanded="false" aria-controls="collapse-history-total">
|
||||||
|
<div class="history-bar dashed-container">
|
||||||
|
<div class="history-bar-container">
|
||||||
|
<div class="history-bar-item">
|
||||||
|
<label class="history-item-label">Summary</label>
|
||||||
|
<p class="history-item-text">Need a python programmer</p>
|
||||||
|
</div>
|
||||||
|
<div class="history-bar-item">
|
||||||
|
<label class="history-item-label">Spending</label>
|
||||||
|
<p class="history-item-text">2000USD</p>
|
||||||
|
</div>
|
||||||
|
<div class="history-bar-item">
|
||||||
|
<label class="history-item-label">Updated</label>
|
||||||
|
<p class="history-item-text">2023-10-19</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</h2>
|
||||||
|
<div id="collapse-history-total" class="accordion-collapse collapse" data-bs-parent="#accordion-history-total">
|
||||||
|
<div class="accordion-body">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="accordion accordion-list" id="accordion-history-earning">
|
||||||
|
<div class="accordion-item">
|
||||||
|
<h2 class="accordion-header">
|
||||||
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapse-history-earning" aria-expanded="false" aria-controls="collapse-history-earning">
|
||||||
|
<div class="history-bar dashed-container">
|
||||||
|
<div class="history-bar-container">
|
||||||
|
<div class="history-bar-item">
|
||||||
|
<label class="history-item-label">Summary</label>
|
||||||
|
<p class="history-item-text">Need a python programmer</p>
|
||||||
|
</div>
|
||||||
|
<div class="history-bar-item">
|
||||||
|
<label class="history-item-label">Earining</label>
|
||||||
|
<p class="history-item-text">2000USD</p>
|
||||||
|
</div>
|
||||||
|
<div class="history-bar-item">
|
||||||
|
<label class="history-item-label">Updated</label>
|
||||||
|
<p class="history-item-text">2023-10-19</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</h2>
|
||||||
|
<div id="collapse-history-earning" class="accordion-collapse collapse" data-bs-parent="#accordion-history-earning">
|
||||||
|
<div class="accordion-body">
|
||||||
|
<div class="history-bar dashed-container">
|
||||||
|
<div class="history-bar-container">
|
||||||
|
<div class="history-bar-item">
|
||||||
|
<label class="history-item-label">Summary</label>
|
||||||
|
<p class="history-item-text">Need a python programmer</p>
|
||||||
|
</div>
|
||||||
|
<div class="history-bar-item">
|
||||||
|
<label class="history-item-label">Earining</label>
|
||||||
|
<p class="history-item-text">2000USD</p>
|
||||||
|
</div>
|
||||||
|
<div class="history-bar-item">
|
||||||
|
<label class="history-item-label">Updated</label>
|
||||||
|
<p class="history-item-text">2023-10-19</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -30,3 +172,43 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.history-container {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.history-content {
|
||||||
|
width: 100%;
|
||||||
|
max-width: $body-width;
|
||||||
|
padding: 24px 0;
|
||||||
|
|
||||||
|
.history-bar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.history-bar-container {
|
||||||
|
@extend .flex-row-container;
|
||||||
|
@extend .flex-grow-1;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-bar-item {
|
||||||
|
@extend .text-start;
|
||||||
|
@extend .flex-grow-1;
|
||||||
|
|
||||||
|
.history-item-label {
|
||||||
|
@extend .label-text-light;
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-item-text {
|
||||||
|
@extend .text-start;
|
||||||
|
margin-bottom: 0;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -1008,8 +1008,8 @@ export default {
|
|||||||
|
|
||||||
.project-item-text {
|
.project-item-text {
|
||||||
@extend .text-start;
|
@extend .text-start;
|
||||||
@extend .mx-1;
|
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.project-request-container {
|
.project-request-container {
|
||||||
@ -1067,7 +1067,6 @@ export default {
|
|||||||
|
|
||||||
.request-proposal-content-container {
|
.request-proposal-content-container {
|
||||||
@extend .container;
|
@extend .container;
|
||||||
@extend .border;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.request-proposal-content {
|
.request-proposal-content {
|
||||||
@ -1076,7 +1075,10 @@ export default {
|
|||||||
|
|
||||||
.request-proposal-payment-plan {
|
.request-proposal-payment-plan {
|
||||||
@extend .container;
|
@extend .container;
|
||||||
@extend .border;
|
border: 1px dashed #9CB0F6;
|
||||||
|
border-radius: 3px;
|
||||||
|
padding: 24px;
|
||||||
|
margin: 32px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.request-proposal-payment-plan-stage-container {
|
.request-proposal-payment-plan-stage-container {
|
||||||
|
|||||||
@ -147,21 +147,8 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="description-container">
|
<div class="description-container">
|
||||||
<!-- <div
|
|
||||||
class="input-description"
|
|
||||||
id="inputDescription"
|
|
||||||
placeholder="Fill the request's description here"
|
|
||||||
v-html="content"
|
|
||||||
@keyup="textAreaAdjust($event)"
|
|
||||||
@blur="descriptionDone($event)"
|
|
||||||
contenteditable="true"
|
|
||||||
/> -->
|
|
||||||
<freeleaps-editor v-model:content="content" />
|
<freeleaps-editor v-model:content="content" />
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="file-upload-container">
|
|
||||||
<label for="file-upload" class="file-upload-label">Upload File:</label>
|
|
||||||
<input type="file" id="file-upload" class="file-upload-input" @change="handleFileUpload" />
|
|
||||||
</div> -->
|
|
||||||
<div class="action-footer">
|
<div class="action-footer">
|
||||||
<button class="cancel-button" @click="back">Cancel</button>
|
<button class="cancel-button" @click="back">Cancel</button>
|
||||||
<button class="submit-button" @click="submit">(Re)Submit</button>
|
<button class="submit-button" @click="submit">(Re)Submit</button>
|
||||||
@ -347,9 +334,9 @@ export default {
|
|||||||
.request-issue-container {
|
.request-issue-container {
|
||||||
@extend .flex-colum-container;
|
@extend .flex-colum-container;
|
||||||
box-shadow: 0px 0px 24px 0px rgba(212, 211, 227, 0.5);
|
box-shadow: 0px 0px 24px 0px rgba(212, 211, 227, 0.5);
|
||||||
border-top-left-radius: 12px;
|
border-radius: 12px;
|
||||||
border-top-right-radius: 12px;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
background: white
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-bar {
|
.action-bar {
|
||||||
|
|||||||
75
frontend/src/plugins/store/basic.js
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
/* eslint-disable no-prototype-builtins */
|
||||||
|
import { i18n } from '@/lang'
|
||||||
|
import { WsConnectionFactory } from '@/utils/backend/websocket'
|
||||||
|
|
||||||
|
const basicStore = {
|
||||||
|
namespaced: true,
|
||||||
|
state() {
|
||||||
|
return {
|
||||||
|
language: 'zh',
|
||||||
|
unreadCountMapper: [],
|
||||||
|
downstream_web_socket: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mutations: {
|
||||||
|
setLanguage(state, language) {
|
||||||
|
state.language = language
|
||||||
|
i18n.global.locale.value = language
|
||||||
|
localStorage.setItem('language', language)
|
||||||
|
},
|
||||||
|
initWebsocket(state, token) {
|
||||||
|
state.downstream_web_socket = WsConnectionFactory.CreateWebSocket(
|
||||||
|
token,
|
||||||
|
() => {
|
||||||
|
// keep
|
||||||
|
setInterval(() => {
|
||||||
|
state.downstream_web_socket.send(1)
|
||||||
|
}, 1000 * 60)
|
||||||
|
console.log('downstream_web_socket open')
|
||||||
|
},
|
||||||
|
(e) => {
|
||||||
|
const data = JSON.parse(e.data)
|
||||||
|
let unread = state.unreadCountMapper[data.sender_id]
|
||||||
|
if (unread) {
|
||||||
|
unread ++
|
||||||
|
} else {
|
||||||
|
unread = 1
|
||||||
|
}
|
||||||
|
state.unreadCountMapper[data.sender_id] = unread
|
||||||
|
console.log('downstream_web_socket onmessage: ', data, state.unreadCountMapper)
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
console.log('downstream_web_socket error')
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
console.log('downstream_web_socket closed')
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
setLanguage(context, language) {
|
||||||
|
context.commit('setLanguage', language)
|
||||||
|
},
|
||||||
|
initWebsocket(context, token) {
|
||||||
|
context.commit('initWebsocket', token)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getters: {
|
||||||
|
language(state) {
|
||||||
|
return state.language
|
||||||
|
},
|
||||||
|
unreadCount(state) {
|
||||||
|
let count = 0
|
||||||
|
for (let key in state.unreadCountMapper) {
|
||||||
|
if (state.unreadCountMapper.hasOwnProperty(key)) {
|
||||||
|
count += state.unreadCountMapper[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { basicStore }
|
||||||
|
|
||||||
@ -2,11 +2,13 @@
|
|||||||
import { createStore } from 'vuex'
|
import { createStore } from 'vuex'
|
||||||
import { userAuthStore } from './userAuth'
|
import { userAuthStore } from './userAuth'
|
||||||
import { userRoleEnum, userProfileStore } from './userProfile'
|
import { userRoleEnum, userProfileStore } from './userProfile'
|
||||||
|
import { basicStore } from './basic'
|
||||||
|
|
||||||
const store = createStore({
|
const store = createStore({
|
||||||
modules: {
|
modules: {
|
||||||
userAuth: userAuthStore,
|
userAuth: userAuthStore,
|
||||||
userProfile: userProfileStore
|
userProfile: userProfileStore,
|
||||||
|
basic: basicStore
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import { userUtils } from '../store/index'
|
// import { userUtils } from '../store/index'
|
||||||
|
|
||||||
class WsConnectionFactory {
|
class WsConnectionFactory {
|
||||||
static CreateWebSocket(onOpen, onMessage, onError, onClose) {
|
static CreateWebSocket(jwt, onOpen, onMessage, onError, onClose) {
|
||||||
let jwt = userUtils.getJwtToken()
|
// let jwt = userUtils.getJwtToken()
|
||||||
this.socket = new WebSocket(`/ws/downstream/online_platform_notification?token=${jwt}`)
|
this.socket = new WebSocket(`/ws/downstream/online_platform_notification?token=${jwt}`)
|
||||||
this.socket.onopen = onOpen
|
this.socket.onopen = onOpen
|
||||||
this.socket.onmessage = onMessage
|
this.socket.onmessage = onMessage
|
||||||
|
|||||||