This commit is contained in:
Zhigang Wang 2024-06-25 08:51:50 -07:00
parent b5065151d4
commit cf46520ada
20 changed files with 360 additions and 300 deletions

View File

@ -1,7 +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-left.png" alt="freeleaps" class="app-bg-left" />
<img src="@/assets/images/home-bg-right.png" alt="freeleaps" class="app-bg-right"> <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>

View File

@ -204,7 +204,7 @@ p {
// border-bottom: 1px solid #dee2e6; // border-bottom: 1px solid #dee2e6;
&::before { &::before {
left: 0; left: 0;
width: 100%;; width: 100%;
} }
.dashed-container { .dashed-container {
background-color: #f3f6ff; background-color: #f3f6ff;
@ -248,7 +248,7 @@ p {
} }
input:-webkit-autofill { input:-webkit-autofill {
box-shadow:0 0 0 1000px white inset !important; box-shadow: 0 0 0 1000px white inset !important;
} }
input:-internal-autofill-previewed, input:-internal-autofill-previewed,
input:-internal-autofill-selected { input:-internal-autofill-selected {

View File

@ -309,7 +309,7 @@ export default {
let html = $event.target.innerHTML || '' let html = $event.target.innerHTML || ''
setTimeout(() => { setTimeout(() => {
this.$emit('update:content', html) this.$emit('update:content', html)
}); })
} }
} }
} }

View File

@ -1,66 +1,73 @@
<template> <template>
<div class="laguage-switch-container"> <div class="laguage-switch-container">
<button class="btn btn-link btn-link-switch" data-bs-toggle="dropdown" aria-expanded="false" id="language-switch-button"> <button
<img :src="languageMapper[currentLanguage]" alt="freeleap language"> class="btn btn-link btn-link-switch"
</button> data-bs-toggle="dropdown"
<ul class="dropdown-menu" aria-labelledby="language-switch-button"> aria-expanded="false"
<template v-for="item in languageList" :key="item"> id="language-switch-button"
<li v-if="item != currentLanguage"> >
<button class="btn btn-link btn-link-switch" @click="changeLanguage(item)"> <img :src="languageMapper[currentLanguage]" alt="freeleap language" />
<img :src="languageMapper[item]" alt="freeleap zh"> </button>
</button> <ul class="dropdown-menu" aria-labelledby="language-switch-button">
</li> <template v-for="item in languageList" :key="item">
</template> <li v-if="item != currentLanguage">
</ul> <button class="btn btn-link btn-link-switch" @click="changeLanguage(item)">
</div> <img :src="languageMapper[item]" alt="freeleap zh" />
</button>
</li>
</template>
</ul>
</div>
</template> </template>
<script> <script>
import zh_icon from '@/assets/lang/zh.png' import zh_icon from '@/assets/lang/zh.png'
import en_icon from '@/assets/lang/us.png' import en_icon from '@/assets/lang/us.png'
export default { export default {
name: 'LaguageSwitch', name: 'LaguageSwitch',
data() { data() {
return { return {
languageList: ["zh", "en"], languageList: ['zh', 'en'],
languageMapper: { languageMapper: {
"zh": zh_icon, zh: zh_icon,
"en": en_icon en: en_icon
} }
}
},
computed: {
currentLanguage() {
return this.$store.getters['basic/language']
}
},
methods: {
changeLanguage(l) {
this.$store.dispatch('basic/setLanguage', l)
}
} }
},
computed: {
currentLanguage() {
return this.$store.getters['basic/language']
}
},
methods: {
changeLanguage(l) {
this.$store.dispatch('basic/setLanguage', l)
}
}
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.laguage-switch-container { .laguage-switch-container {
display: inline; display: inline;
position: relative; 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 { .btn-link-switch {
padding: 0; padding: 0 5px;
width: 35px; width: 45px;
line-height: 1;
img {width: 100%;}
}
.dropdown-menu {
min-width: auto;
margin-left: -5px !important;
.btn-link-switch {
padding: 0 5px;
width: 45px;
}
} }
}
} }
</style> </style>

View File

@ -4,7 +4,7 @@
<div <div
class="information-bar" class="information-bar"
@click="gotoMessages" @click="gotoMessages"
:class="{'active' : activePath == 'message', 'unread' : unreadCount > 0}" :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>

View File

@ -1,70 +1,70 @@
export default { export default {
"About": "About", About: 'About',
"Blogs": "Blogs", Blogs: 'Blogs',
"Career": "Career", Career: 'Career',
"Contact": "Contact", Contact: 'Contact',
"Summary": "Summary", Summary: 'Summary',
"Status": "Status", Status: 'Status',
"Date": "Date", Date: 'Date',
"withdraw": "withdraw", withdraw: 'withdraw',
"edit": "edit", edit: 'edit',
"Quote": "Quote", Quote: 'Quote',
"Payment": "Payment", Payment: 'Payment',
"Duration": "Duration", Duration: 'Duration',
"days": "days", days: 'days',
"Update": "Update", Update: 'Update',
"From": "From", From: 'From',
"reject": "reject", reject: 'reject',
"accept": "accept", accept: 'accept',
"Note": "Note", Note: 'Note',
"Invite": "Invite", Invite: 'Invite',
"Input E-mail to invite other": "Input E-mail to invite other", 'Input E-mail to invite other': 'Input E-mail to invite other',
"Submit": "Submit", Submit: 'Submit',
"Progress": "Progress", Progress: 'Progress',
"milestones": "milestones", milestones: 'milestones',
"Paid": "Paid", Paid: 'Paid',
"Milestone": "Milestone", Milestone: 'Milestone',
"Description": "Description", Description: 'Description',
"Mark As Paid": "Mark As Paid", 'Mark As Paid': 'Mark As Paid',
"Code Depot": "Code Depot", 'Code Depot': 'Code Depot',
"Commits": "Commits", Commits: 'Commits',
"Last committer": "Last committer", 'Last committer': 'Last committer',
"copy git url": "copy git url", 'copy git url': 'copy git url',
"Manage": "Manage", Manage: 'Manage',
"TO BE IMPLEMENTED.": "TO BE IMPLEMENTED.", 'TO BE IMPLEMENTED.': 'TO BE IMPLEMENTED.',
"Open issues": "Open issues", 'Open issues': 'Open issues',
"Resolved issues": "Resolved issues", 'Resolved issues': 'Resolved issues',
"Closed issues": "Closed issues", 'Closed issues': 'Closed issues',
"Add Issue": "Add Issue", 'Add Issue': 'Add Issue',
"New issue description": "New issue description", 'New issue description': 'New issue description',
"Issue title": "Issue title", 'Issue title': 'Issue title',
"Last updated": "Last updated", 'Last updated': 'Last updated',
"Issue description": "Issue description", 'Issue description': 'Issue description',
"Resolve": "Resolve", Resolve: 'Resolve',
"Confirm": "Confirm", Confirm: 'Confirm',
"Reopen": "Reopen", Reopen: 'Reopen',
"fd_1": "A platform where our users can find a trustworthy partner,", fd_1: 'A platform where our users can find a trustworthy partner,',
"fd_2": "simplify software development, and secure return.", fd_2: 'simplify software development, and secure return.',
"fd_3": "One stop platform", fd_3: 'One stop platform',
"fd_4": "for hiring the best", fd_4: 'for hiring the best',
"fd_5": "freelance software development talent", fd_5: 'freelance software development talent',
"Email address": "Email address", 'Email address': 'Email address',
"GET STARTED": "GET STARTED", 'GET STARTED': 'GET STARTED',
"Please type in your email": "Please type in your email", 'Please type in your email': 'Please type in your email',
"Your Freeleaps User ID": "Your Freeleaps User ID", 'Your Freeleaps User ID': 'Your Freeleaps User ID',
"SUBMIT": "SUBMIT", SUBMIT: 'SUBMIT',
"Please type in your Freeleaps user ID": "Please type in your Freeleaps user ID", 'Please type in your Freeleaps user ID': 'Please type in your Freeleaps user ID',
"Your password": "Your password", 'Your password': 'Your password',
"Repeat password": "Repeat password", 'Repeat password': 'Repeat password',
"SIGN UP": "SIGN UP", 'SIGN UP': 'SIGN UP',
"Please type in your password": "Please type in your password", 'Please type in your password': 'Please type in your password',
"The two passwords are not matched": "The two passwords are not matched", 'The two passwords are not matched': 'The two passwords are not matched',
"Authenticaion Code Sent To Your Email": "Authenticaion Code Sent To Your Email", 'Authenticaion Code Sent To Your Email': 'Authenticaion Code Sent To Your Email',
"SIGN IN": "SIGN IN", 'SIGN IN': 'SIGN IN',
"Please type in the code sent to your email": "Please type in the code sent to your email", 'Please type in the code sent to your email': 'Please type in the code sent to your email',
"Invalid auth code": "Invalid auth code", 'Invalid auth code': 'Invalid auth code',
"invalid code": "invalid code", 'invalid code': 'invalid code',
"Password": "Password", Password: 'Password',
"Forget password": "Forget password", 'Forget password': 'Forget password',
"Invalid password": "Invalid password", 'Invalid password': 'Invalid password'
} }

View File

@ -1,3 +1,3 @@
export default { export default {
"Contact": "联系我们" Contact: '联系我们'
} }

View File

@ -1,8 +1,8 @@
<template> <template>
<div class="flex-colum-container front-container"> <div class="flex-colum-container front-container">
<div class="slogen">{{$t('fd_1')}}<br />{{$t('fd_2')}}</div> <div class="slogen">{{ $t('fd_1') }}<br />{{ $t('fd_2') }}</div>
<div class="poster"> <div class="poster">
<span class="blue">{{$t('fd_3')}}</span> {{$t('fd_4')}} <br />{{$t('fd_5')}} <span class="blue">{{ $t('fd_3') }}</span> {{ $t('fd_4') }} <br />{{ $t('fd_5') }}
</div> </div>
<div class="input-container"> <div class="input-container">
<div class="form-group"> <div class="form-group">
@ -15,10 +15,10 @@
placeholder="name@example.com" placeholder="name@example.com"
v-model="email" v-model="email"
/> />
<label for="inputEmail">{{$t('Email address')}}</label> <label for="inputEmail">{{ $t('Email address') }}</label>
</div> </div>
<button class="btn-start" ref="submitButton" @click="trySigninWithEmail()"> <button class="btn-start" ref="submitButton" @click="trySigninWithEmail()">
{{$t('GET STARTED')}} {{ $t('GET STARTED') }}
</button> </button>
</div> </div>
</div> </div>

View File

@ -12,9 +12,9 @@
:placeholder="'set your Freeleaps user id'" :placeholder="'set your Freeleaps user id'"
v-model="flid" v-model="flid"
/> />
<label for="inputCode">{{$t('Your Freeleaps User ID')}}</label> <label for="inputCode">{{ $t('Your Freeleaps User ID') }}</label>
</div> </div>
<button type="submit" class="btn-start">{{$t('SUBMIT')}}</button> <button type="submit" class="btn-start">{{ $t('SUBMIT') }}</button>
</div> </div>
</div> </div>
<p class="errorInput" v-if="message != null">{{ message }}</p> <p class="errorInput" v-if="message != null">{{ message }}</p>

View File

@ -12,7 +12,7 @@
:placeholder="'Type your password'" :placeholder="'Type your password'"
v-model="password" v-model="password"
/> />
<label for="inputCode">{{$t('Your password')}}</label> <label for="inputCode">{{ $t('Your password') }}</label>
</div> </div>
</div> </div>
</div> </div>
@ -27,9 +27,9 @@
:placeholder="'Repeat your password'" :placeholder="'Repeat your password'"
v-model="password2" v-model="password2"
/> />
<label for="inputCode">{{$t('Repeat password')}}</label> <label for="inputCode">{{ $t('Repeat password') }}</label>
</div> </div>
<button type="submit" class="btn-start">{{$t('SIGN UP')}}</button> <button type="submit" class="btn-start">{{ $t('SIGN UP') }}</button>
</div> </div>
<p class="error-msg" v-if="message != null">{{ message }}</p> <p class="error-msg" v-if="message != null">{{ message }}</p>
</div> </div>

View File

@ -12,9 +12,9 @@
:placeholder="'Code sent to your email'" :placeholder="'Code sent to your email'"
v-model="code" v-model="code"
/> />
<label for="inputCode">{{$t('Authenticaion Code Sent To Your Email')}}</label> <label for="inputCode">{{ $t('Authenticaion Code Sent To Your Email') }}</label>
</div> </div>
<button type="submit" class="btn-start">{{$t('SIGN IN')}}</button> <button type="submit" class="btn-start">{{ $t('SIGN IN') }}</button>
</div> </div>
</div> </div>
<p class="error-msg" v-if="message != null">{{ message }}</p> <p class="error-msg" v-if="message != null">{{ message }}</p>

View File

@ -12,16 +12,16 @@
:placeholder="'Type in your password'" :placeholder="'Type in your password'"
v-model="password" v-model="password"
/> />
<label for="inputCode">{{$t('Password')}}</label> <label for="inputCode">{{ $t('Password') }}</label>
</div> </div>
<button type="submit" class="btn-start">{{$t('SIGN IN')}}</button> <button type="submit" class="btn-start">{{ $t('SIGN IN') }}</button>
</div> </div>
</div> </div>
<div class="error-msg flex-row-container"> <div class="error-msg flex-row-container">
<p class="error-p" v-if="message != null">{{ message }}</p> <p class="error-p" v-if="message != null">{{ message }}</p>
<div class="flex-1" /> <div class="flex-1" />
<button type="button" class="btn-forget-password" @click="forgetPassword()"> <button type="button" class="btn-forget-password" @click="forgetPassword()">
{{$t('Forget password')}} {{ $t('Forget password') }}
</button> </button>
</div> </div>
</div> </div>

View File

@ -70,7 +70,7 @@ export default {
.directory-title { .directory-title {
font-size: 48px; font-size: 48px;
// font-weight: bold; // font-weight: bold;
color: #18181A; color: #18181a;
margin-bottom: 5px; margin-bottom: 5px;
} }
.directory-subtitle { .directory-subtitle {

View File

@ -56,7 +56,8 @@ export default {
cursor: pointer; cursor: pointer;
padding: 0; padding: 0;
h2, p { h2,
p {
text-align: left; text-align: left;
} }
} }

View File

@ -50,15 +50,17 @@ export default {
.career-item { .career-item {
cursor: pointer; cursor: pointer;
box-shadow: 0px 0px 24px 0px #D4D3E380; box-shadow: 0px 0px 24px 0px #d4d3e380;
padding: 32px; padding: 32px;
color: #18181A; color: #18181a;
font-size: 14px; font-size: 14px;
background-color: white; background-color: white;
margin-bottom: 32px; margin-bottom: 32px;
text-align: left; text-align: left;
p {margin: 0;} p {
margin: 0;
}
.career-title { .career-title {
font-size: 32px; font-size: 32px;
margin-bottom: 10px; margin-bottom: 10px;

View File

@ -84,10 +84,10 @@ export default {
} }
.contact-right { .contact-right {
margin-left: 24px; margin-left: 24px;
box-shadow: 0px 0px 24px 0px #D4D3E380; box-shadow: 0px 0px 24px 0px #d4d3e380;
background: white; background: white;
padding: 32px; padding: 32px;
color: #18181A; color: #18181a;
border-radius: 12px; border-radius: 12px;
width: 368px; width: 368px;
text-align: left; text-align: left;

View File

@ -4,7 +4,14 @@
<div class="accordion accordion-list" id="accordion-history-total"> <div class="accordion accordion-list" id="accordion-history-total">
<div class="accordion-item"> <div class="accordion-item">
<h2 class="accordion-header"> <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"> <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 dashed-container">
<div class="history-bar-container"> <div class="history-bar-container">
<div class="history-bar-item"> <div class="history-bar-item">
@ -31,10 +38,12 @@
</div> </div>
</button> </button>
</h2> </h2>
<div id="collapse-history-total" class="accordion-collapse collapse" data-bs-parent="#accordion-history-total"> <div
<div class="accordion-body"> id="collapse-history-total"
class="accordion-collapse collapse"
</div> data-bs-parent="#accordion-history-total"
>
<div class="accordion-body"></div>
</div> </div>
</div> </div>
</div> </div>
@ -42,7 +51,14 @@
<div class="accordion accordion-list" id="accordion-history-total"> <div class="accordion accordion-list" id="accordion-history-total">
<div class="accordion-item"> <div class="accordion-item">
<h2 class="accordion-header"> <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"> <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 dashed-container">
<div class="history-bar-container"> <div class="history-bar-container">
<div class="history-bar-item"> <div class="history-bar-item">
@ -61,16 +77,25 @@
</div> </div>
</button> </button>
</h2> </h2>
<div id="collapse-history-total" class="accordion-collapse collapse" data-bs-parent="#accordion-history-total"> <div
<div class="accordion-body"> id="collapse-history-total"
class="accordion-collapse collapse"
</div> data-bs-parent="#accordion-history-total"
>
<div class="accordion-body"></div>
</div> </div>
</div> </div>
<div class="accordion-item"> <div class="accordion-item">
<h2 class="accordion-header"> <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"> <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 dashed-container">
<div class="history-bar-container"> <div class="history-bar-container">
<div class="history-bar-item"> <div class="history-bar-item">
@ -89,19 +114,27 @@
</div> </div>
</button> </button>
</h2> </h2>
<div id="collapse-history-total" class="accordion-collapse collapse" data-bs-parent="#accordion-history-total"> <div
<div class="accordion-body"> id="collapse-history-total"
class="accordion-collapse collapse"
</div> data-bs-parent="#accordion-history-total"
>
<div class="accordion-body"></div>
</div> </div>
</div> </div>
</div> </div>
<div class="accordion accordion-list" id="accordion-history-earning"> <div class="accordion accordion-list" id="accordion-history-earning">
<div class="accordion-item"> <div class="accordion-item">
<h2 class="accordion-header"> <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"> <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 dashed-container">
<div class="history-bar-container"> <div class="history-bar-container">
<div class="history-bar-item"> <div class="history-bar-item">
@ -120,7 +153,11 @@
</div> </div>
</button> </button>
</h2> </h2>
<div id="collapse-history-earning" class="accordion-collapse collapse" data-bs-parent="#accordion-history-earning"> <div
id="collapse-history-earning"
class="accordion-collapse collapse"
data-bs-parent="#accordion-history-earning"
>
<div class="accordion-body"> <div class="accordion-body">
<div class="history-bar dashed-container"> <div class="history-bar dashed-container">
<div class="history-bar-container"> <div class="history-bar-container">

View File

@ -21,15 +21,15 @@
<div class="workspace-item-bar dashed-container"> <div class="workspace-item-bar dashed-container">
<div class="workspace-item-bar-left"> <div class="workspace-item-bar-left">
<div class="project-item-title-container"> <div class="project-item-title-container">
<label class="project-item-label">{{$t('Summary')}}</label> <label class="project-item-label">{{ $t('Summary') }}</label>
<p class="project-item-text">{{ project.title }}</p> <p class="project-item-text">{{ project.title }}</p>
</div> </div>
<div class="project-item-status-container"> <div class="project-item-status-container">
<label class="project-item-label">{{$t('Status')}}</label> <label class="project-item-label">{{ $t('Status') }}</label>
<p class="project-item-text">{{ fromIntToProjectStatus(project.status) }}</p> <p class="project-item-text">{{ fromIntToProjectStatus(project.status) }}</p>
</div> </div>
<div class="project-item-date-container"> <div class="project-item-date-container">
<label class="project-item-label">{{$t('Date')}}</label> <label class="project-item-label">{{ $t('Date') }}</label>
<p class="project-item-text"> <p class="project-item-text">
{{ getDateFromFulltimeString(project.update_time) }} {{ getDateFromFulltimeString(project.update_time) }}
</p> </p>
@ -52,7 +52,7 @@
<div class="accordion-body" v-if="isOpenRequest(project)"> <div class="accordion-body" v-if="isOpenRequest(project)">
<div class="float-action-container"> <div class="float-action-container">
<button class="request-action-withdraw" @click="withdrawAndEditRequest(project)"> <button class="request-action-withdraw" @click="withdrawAndEditRequest(project)">
{{$t('withdraw')}}&{{$t('edit')}} {{ $t('withdraw') }}&{{ $t('edit') }}
</button> </button>
</div> </div>
<div class="project-request-container"> <div class="project-request-container">
@ -82,27 +82,29 @@
> >
<div class="project-request-proposal-bar-container"> <div class="project-request-proposal-bar-container">
<div class="project-request-proposal-quote-container"> <div class="project-request-proposal-quote-container">
<label class="project-item-label">{{$t('Quote')}}</label> <label class="project-item-label">{{ $t('Quote') }}</label>
<p class="project-item-text">{{ proposal.price_in_usd }} USD</p> <p class="project-item-text">{{ proposal.price_in_usd }} USD</p>
</div> </div>
<div class="project-request-proposal-payment-type-container"> <div class="project-request-proposal-payment-type-container">
<label class="project-item-label">{{$t('Payment')}}</label> <label class="project-item-label">{{ $t('Payment') }}</label>
<p class="project-item-text"> <p class="project-item-text">
{{ fromIntToPaymentType(proposal.payment_plan.type) }} {{ fromIntToPaymentType(proposal.payment_plan.type) }}
</p> </p>
</div> </div>
<div class="project-request-proposal-duration-container"> <div class="project-request-proposal-duration-container">
<label class="project-item-label">{{$t('Duration')}}</label> <label class="project-item-label">{{ $t('Duration') }}</label>
<p class="project-item-text">{{ proposal.duration_in_day }}&nbsp;{{$t('days')}}</p> <p class="project-item-text">
{{ proposal.duration_in_day }}&nbsp;{{ $t('days') }}
</p>
</div> </div>
<div class="project-request-proposal-date-container"> <div class="project-request-proposal-date-container">
<label class="project-item-label">{{$t('Update')}}</label> <label class="project-item-label">{{ $t('Update') }}</label>
<p class="project-item-text"> <p class="project-item-text">
{{ getDateFromFulltimeString(proposal.update_time) }} {{ getDateFromFulltimeString(proposal.update_time) }}
</p> </p>
</div> </div>
<div class="project-request-proposal-from-container"> <div class="project-request-proposal-from-container">
<label class="project-item-label">{{$t('From')}}</label> <label class="project-item-label">{{ $t('From') }}</label>
<p class="project-item-text"> <p class="project-item-text">
{{ proposal.proposer.first_name }} {{ proposal.proposer.last_name }} {{ proposal.proposer.first_name }} {{ proposal.proposer.last_name }}
</p> </p>
@ -121,13 +123,13 @@
class="request-proposal-action-reject" class="request-proposal-action-reject"
@click="rejectProposal(project, proposal_index)" @click="rejectProposal(project, proposal_index)"
> >
{{$t('reject')}} {{ $t('reject') }}
</button> </button>
<button <button
class="request-proposal-action-accept" class="request-proposal-action-accept"
@click="acceptProposal(project, proposal_index)" @click="acceptProposal(project, proposal_index)"
> >
{{$t('accept')}} {{ $t('accept') }}
</button> </button>
</div> </div>
<div class="request-proposal-content-container"> <div class="request-proposal-content-container">
@ -141,17 +143,19 @@
:id="'payment-stage-' + stage_index" :id="'payment-stage-' + stage_index"
> >
<div class="project-request-proposal-stage-payment-container"> <div class="project-request-proposal-stage-payment-container">
<label class="project-item-label">{{$t('Payment')}}</label> <label class="project-item-label">{{ $t('Payment') }}</label>
<p class="project-item-text"> <p class="project-item-text">
{{ stage.amount }} {{ stage.currency }} {{ stage.amount }} {{ stage.currency }}
</p> </p>
</div> </div>
<div class="project-request-proposal-stage-duration-container"> <div class="project-request-proposal-stage-duration-container">
<label class="project-item-label">{{$t('Duration')}}</label> <label class="project-item-label">{{ $t('Duration') }}</label>
<p class="project-item-text">{{ stage.duration_in_day }}&nbsp;{{$t('days')}}</p> <p class="project-item-text">
{{ stage.duration_in_day }}&nbsp;{{ $t('days') }}
</p>
</div> </div>
<div class="project-request-proposal-stage-note-container"> <div class="project-request-proposal-stage-note-container">
<label class="project-item-label">{{$t('Note')}}</label> <label class="project-item-label">{{ $t('Note') }}</label>
<p class="project-item-text">{{ stage.note }}</p> <p class="project-item-text">{{ stage.note }}</p>
</div> </div>
</div> </div>
@ -165,7 +169,7 @@
<div class="accordion-body" v-if="isPendingProposal(project)"> <div class="accordion-body" v-if="isPendingProposal(project)">
<div class="float-action-container"> <div class="float-action-container">
<button class="proposal-action-withdraw" @click="withdrawAndEditProposal(project)"> <button class="proposal-action-withdraw" @click="withdrawAndEditProposal(project)">
{{$t('withdraw')}}&{{$t('edit')}} {{ $t('withdraw') }}&{{ $t('edit') }}
</button> </button>
</div> </div>
<div class="request-proposal-content-container"> <div class="request-proposal-content-container">
@ -179,15 +183,17 @@
:id="'payment-stage-' + stage_index" :id="'payment-stage-' + stage_index"
> >
<div class="project-request-proposal-stage-payment-container"> <div class="project-request-proposal-stage-payment-container">
<label class="project-item-label">{{$t('Payment')}}</label> <label class="project-item-label">{{ $t('Payment') }}</label>
<p class="project-item-text">{{ stage.amount }} {{ stage.currency }}</p> <p class="project-item-text">{{ stage.amount }} {{ stage.currency }}</p>
</div> </div>
<div class="project-request-proposal-stage-duration-container"> <div class="project-request-proposal-stage-duration-container">
<label class="project-item-label">{{$t('Duration')}}</label> <label class="project-item-label">{{ $t('Duration') }}</label>
<p class="project-item-text">{{ stage.duration_in_day }}&nbsp;{{$t('days')}}</p> <p class="project-item-text">
{{ stage.duration_in_day }}&nbsp;{{ $t('days') }}
</p>
</div> </div>
<div class="project-request-proposal-stage-note-container"> <div class="project-request-proposal-stage-note-container">
<label class="project-item-label">{{$t('Note')}}</label> <label class="project-item-label">{{ $t('Note') }}</label>
<p class="project-item-text">{{ stage.note }}</p> <p class="project-item-text">{{ stage.note }}</p>
</div> </div>
</div> </div>
@ -211,7 +217,7 @@
aria-expanded="false" aria-expanded="false"
aria-controls="collapse-project-invite-collaborator" aria-controls="collapse-project-invite-collaborator"
> >
<div class="project-invite-collaborator">+ {{$t('Invite')}}</div> <div class="project-invite-collaborator">+ {{ $t('Invite') }}</div>
</button> </button>
<div <div
id="collapse-project-invite-collaborator" id="collapse-project-invite-collaborator"
@ -220,7 +226,9 @@
> >
<div class="project-invite-collaborator-form-container"> <div class="project-invite-collaborator-form-container">
<div class="project-invite-collaborator-form"> <div class="project-invite-collaborator-form">
<label class="project-item-label">{{$t('Input E-mail to invite other')}}</label> <label class="project-item-label">{{
$t('Input E-mail to invite other')
}}</label>
<input <input
class="project-invite-collaborator-input" class="project-invite-collaborator-input"
v-model="newInviteCollaborator[project_index]" v-model="newInviteCollaborator[project_index]"
@ -232,7 +240,7 @@
inviteCollaborator(project.project_id, newInviteCollaborator[project_index]) inviteCollaborator(project.project_id, newInviteCollaborator[project_index])
" "
> >
{{$t('Submit')}} {{ $t('Submit') }}
</button> </button>
</div> </div>
</div> </div>
@ -250,14 +258,16 @@
> >
<div class="project-milestone-bar-container"> <div class="project-milestone-bar-container">
<div class="project-milestone-bar-progress"> <div class="project-milestone-bar-progress">
<label class="project-item-label">{{$t('Progress')}}</label> <label class="project-item-label">{{ $t('Progress') }}</label>
<p class="project-item-text"> <p class="project-item-text">
{{ project.project.progress.current_milestone }} / {{ project.project.progress.current_milestone }} /
{{ project.project.progress.milestones.length }}&nbsp;{{$t('milestones')}} {{ project.project.progress.milestones.length }}&nbsp;{{
$t('milestones')
}}
</p> </p>
</div> </div>
<div class="project-milestone-bar-status"> <div class="project-milestone-bar-status">
<label class="project-item-label">{{$t('Status')}}</label> <label class="project-item-label">{{ $t('Status') }}</label>
<p class="project-item-text"> <p class="project-item-text">
{{ {{
fromIntToMilestoneStatus(project.project.progress.milestone_status) fromIntToMilestoneStatus(project.project.progress.milestone_status)
@ -265,7 +275,7 @@
</p> </p>
</div> </div>
<div class="project-milestone-bar-paid"> <div class="project-milestone-bar-paid">
<label class="project-item-label">{{$t('Paid')}}</label> <label class="project-item-label">{{ $t('Paid') }}</label>
<p class="project-item-text"> <p class="project-item-text">
{{ project.project.progress.actual_paid }} / {{ project.project.progress.actual_paid }} /
{{ project.project.progress.expected_payment }} {{ project.project.progress.expected_payment }}
@ -273,7 +283,7 @@
</p> </p>
</div> </div>
<div class="project-milestone-bar-update"> <div class="project-milestone-bar-update">
<label class="project-item-label">{{$t('Update')}}</label> <label class="project-item-label">{{ $t('Update') }}</label>
<p class="project-item-text"> <p class="project-item-text">
{{ getDateFromFulltimeString(project.project.progress.last_update) }} {{ getDateFromFulltimeString(project.project.progress.last_update) }}
</p> </p>
@ -294,32 +304,32 @@
:id="'project-milestone-' + milestone.index" :id="'project-milestone-' + milestone.index"
> >
<div class="project-milestone-index"> <div class="project-milestone-index">
<label class="project-item-label">{{$t('Milestone')}}</label> <label class="project-item-label">{{ $t('Milestone') }}</label>
<p class="project-item-text"> <p class="project-item-text">
{{ milestone.index }} {{ milestone.index }}
</p> </p>
</div> </div>
<div class="project-milestone-description"> <div class="project-milestone-description">
<label class="project-item-label">{{$t('Description')}}</label> <label class="project-item-label">{{ $t('Description') }}</label>
<p class="project-item-text"> <p class="project-item-text">
{{ milestone.description }} {{ milestone.description }}
</p> </p>
</div> </div>
<div class="project-milestone-status"> <div class="project-milestone-status">
<label class="project-item-label">{{$t('Status')}}</label> <label class="project-item-label">{{ $t('Status') }}</label>
<p class="project-item-text"> <p class="project-item-text">
{{ fromIntToMilestoneStatus(milestone.status) }} {{ fromIntToMilestoneStatus(milestone.status) }}
</p> </p>
</div> </div>
<div class="project-milestone-payment"> <div class="project-milestone-payment">
<label class="project-item-label">{{$t('Payment')}}</label> <label class="project-item-label">{{ $t('Payment') }}</label>
<p class="project-item-text"> <p class="project-item-text">
{{ milestone.actual_paid }} / {{ milestone.expected_payment }} {{ milestone.actual_paid }} / {{ milestone.expected_payment }}
{{ project.project.progress.payment_currency }} {{ project.project.progress.payment_currency }}
</p> </p>
</div> </div>
<div class="project-milestone-update"> <div class="project-milestone-update">
<label class="project-item-label">{{$t('Update')}}</label> <label class="project-item-label">{{ $t('Update') }}</label>
<p class="project-item-text"> <p class="project-item-text">
{{ getDateFromFulltimeString(milestone.update_time) }} {{ getDateFromFulltimeString(milestone.update_time) }}
</p> </p>
@ -340,7 +350,7 @@
class="project-milestone-payment-confirm-button" class="project-milestone-payment-confirm-button"
@click="handlePaymentAction(project.project, milestone)" @click="handlePaymentAction(project.project, milestone)"
> >
{{$t('Mark As Paid')}} {{ $t('Mark As Paid') }}
</button> </button>
</div> </div>
</div> </div>
@ -359,19 +369,19 @@
> >
<div class="project-code-bar-container"> <div class="project-code-bar-container">
<div class="project-code-git-status"> <div class="project-code-git-status">
<label class="project-item-label">{{$t('Code Depot')}}</label> <label class="project-item-label">{{ $t('Code Depot') }}</label>
<p class="project-item-text">{{ getGitStatus(project) }}</p> <p class="project-item-text">{{ getGitStatus(project) }}</p>
</div> </div>
<div class="project-code-commits"> <div class="project-code-commits">
<label class="project-item-label">{{$t('Commits')}}</label> <label class="project-item-label">{{ $t('Commits') }}</label>
<p class="project-item-text">{{ project.project.code.total_commits }}</p> <p class="project-item-text">{{ project.project.code.total_commits }}</p>
</div> </div>
<div class="project-code-last-committer"> <div class="project-code-last-committer">
<label class="project-item-label">{{$t('Last committer')}}</label> <label class="project-item-label">{{ $t('Last committer') }}</label>
<p class="project-item-text">{{ project.project.code.last_commiter }}</p> <p class="project-item-text">{{ project.project.code.last_commiter }}</p>
</div> </div>
<div class="project-code-last-update"> <div class="project-code-last-update">
<label class="project-item-label">{{$t('Update')}}</label> <label class="project-item-label">{{ $t('Update') }}</label>
<p class="project-item-text"> <p class="project-item-text">
{{ getDateFromFulltimeString(project.project.code.last_update) }} {{ getDateFromFulltimeString(project.project.code.last_update) }}
</p> </p>
@ -395,12 +405,12 @@
trigger="click" trigger="click"
delay='{"show":"500", "hide":"100"}' delay='{"show":"500", "hide":"100"}'
> >
{{$t('copy git url')}} {{ $t('copy git url') }}
</button> </button>
</div> </div>
<div class="project-code-statistics-container"> <div class="project-code-statistics-container">
<button class="project-code-manage-button">{{$t('Manage')}}</button> <button class="project-code-manage-button">{{ $t('Manage') }}</button>
{{$t('TO BE IMPLEMENTED.')}} {{ $t('TO BE IMPLEMENTED.') }}
</div> </div>
</div> </div>
</div> </div>
@ -417,19 +427,19 @@
> >
<div class="project-issue-bar-container"> <div class="project-issue-bar-container">
<div class="project-issue-open-issues"> <div class="project-issue-open-issues">
<label class="project-item-label">{{$t('Open issues')}}</label> <label class="project-item-label">{{ $t('Open issues') }}</label>
<p class="project-item-text"> <p class="project-item-text">
{{ project.project.issue.number_of_open_issues }} {{ project.project.issue.number_of_open_issues }}
</p> </p>
</div> </div>
<div class="project-issue-resolved-issues"> <div class="project-issue-resolved-issues">
<label class="project-item-label">{{$t('Resolved issues')}}</label> <label class="project-item-label">{{ $t('Resolved issues') }}</label>
<p class="project-item-text"> <p class="project-item-text">
{{ project.project.issue.number_of_resolved_issues }} {{ project.project.issue.number_of_resolved_issues }}
</p> </p>
</div> </div>
<div class="project-issue-closed-issues"> <div class="project-issue-closed-issues">
<label class="project-item-label">{{$t('Closed issues')}}</label> <label class="project-item-label">{{ $t('Closed issues') }}</label>
<p class="project-item-text"> <p class="project-item-text">
{{ project.project.issue.number_of_closed_issues }} {{ project.project.issue.number_of_closed_issues }}
</p> </p>
@ -455,7 +465,7 @@
aria-expanded="false" aria-expanded="false"
aria-controls="collapse-project-issue" aria-controls="collapse-project-issue"
> >
<div class="project-add-new-issue">+ {{$t('Add Issue')}}</div> <div class="project-add-new-issue">+ {{ $t('Add Issue') }}</div>
</button> </button>
<div <div
id="collapse-project-new-issue" id="collapse-project-new-issue"
@ -464,7 +474,9 @@
> >
<div class="project-issue-description-container"> <div class="project-issue-description-container">
<div class="project-issue-description"> <div class="project-issue-description">
<label class="project-item-label">{{$t('New issue description')}}</label> <label class="project-item-label">{{
$t('New issue description')
}}</label>
<textarea <textarea
class="project-new-issue-textarea" class="project-new-issue-textarea"
type="text" type="text"
@ -482,7 +494,7 @@
) )
" "
> >
{{$t('Submit')}} {{ $t('Submit') }}
</button> </button>
</div> </div>
</div> </div>
@ -506,17 +518,17 @@
aria-controls="collapse-project-issue-details" aria-controls="collapse-project-issue-details"
> >
<div class="project-issue-title"> <div class="project-issue-title">
<label class="project-item-label">{{$t('Issue title')}}</label> <label class="project-item-label">{{ $t('Issue title') }}</label>
<p class="project-item-text">{{ issue.title }}</p> <p class="project-item-text">{{ issue.title }}</p>
</div> </div>
<div class="project-issue-status"> <div class="project-issue-status">
<label class="project-item-label">{{$t('Status')}}</label> <label class="project-item-label">{{ $t('Status') }}</label>
<p class="project-item-text"> <p class="project-item-text">
{{ fromIntToProjectIssueStatus(issue.status) }} {{ fromIntToProjectIssueStatus(issue.status) }}
</p> </p>
</div> </div>
<div class="project-issue-update"> <div class="project-issue-update">
<label class="project-item-label">{{$t('Last updated')}}</label> <label class="project-item-label">{{ $t('Last updated') }}</label>
<p class="project-item-text"> <p class="project-item-text">
{{ getDateFromFulltimeString(issue.update_time) }} {{ getDateFromFulltimeString(issue.update_time) }}
</p> </p>
@ -529,7 +541,9 @@
:data-bs-parent="'#collapse-project-issue-details' + issue_index" :data-bs-parent="'#collapse-project-issue-details' + issue_index"
> >
<div class="project-issue-description-container"> <div class="project-issue-description-container">
<label class="project-item-label">{{$t('Issue description')}}</label> <label class="project-item-label">{{
$t('Issue description')
}}</label>
<p class="project-item-text">{{ issue.description }}</p> <p class="project-item-text">{{ issue.description }}</p>
</div> </div>
<div class="project-issue-action-container"> <div class="project-issue-action-container">
@ -538,21 +552,21 @@
class="project-issue-action-button" class="project-issue-action-button"
@click="setProjectIssueStatus(issue.id, 1)" @click="setProjectIssueStatus(issue.id, 1)"
> >
{{$t('Resolve')}} {{ $t('Resolve') }}
</button> </button>
<button <button
:hidden="!showIssueActionButton(project.project, issue, 'Confirm')" :hidden="!showIssueActionButton(project.project, issue, 'Confirm')"
class="project-issue-action-button" class="project-issue-action-button"
@click="setProjectIssueStatus(issue.id, 2)" @click="setProjectIssueStatus(issue.id, 2)"
> >
{{$t('Confirm')}} {{ $t('Confirm') }}
</button> </button>
<button <button
:hidden="!showIssueActionButton(project.project, issue, 'Reopen')" :hidden="!showIssueActionButton(project.project, issue, 'Reopen')"
class="project-issue-action-button" class="project-issue-action-button"
@click="setProjectIssueStatus(issue.id, 0)" @click="setProjectIssueStatus(issue.id, 0)"
> >
{{$t('Reopen')}} {{ $t('Reopen') }}
</button> </button>
</div> </div>
</div> </div>
@ -1075,7 +1089,7 @@ export default {
.request-proposal-payment-plan { .request-proposal-payment-plan {
@extend .container; @extend .container;
border: 1px dashed #9CB0F6; border: 1px dashed #9cb0f6;
border-radius: 3px; border-radius: 3px;
padding: 24px; padding: 24px;
margin: 32px 0; margin: 32px 0;

View File

@ -336,7 +336,7 @@ export default {
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-radius: 12px; border-radius: 12px;
overflow: hidden; overflow: hidden;
background: white background: white;
} }
.action-bar { .action-bar {

View File

@ -3,82 +3,81 @@ import { i18n } from '@/lang'
import { WsConnectionFactory } from '@/utils/backend/websocket' import { WsConnectionFactory } from '@/utils/backend/websocket'
const basicStore = { const basicStore = {
namespaced: true, namespaced: true,
state() { state() {
return { return {
language: 'zh', language: 'zh',
unreadCountMapper: [], unreadCountMapper: [],
downstream_web_socket: null, downstream_web_socket: null
} }
},
mutations: {
setLanguage(state, language) {
state.language = language
i18n.global.locale.value = language
localStorage.setItem('language', language)
}, },
mutations: { initWebsocket(state, token) {
setLanguage(state, language) { state.downstream_web_socket = WsConnectionFactory.CreateWebSocket(
state.language = language token,
i18n.global.locale.value = language () => {
localStorage.setItem('language', language) // keep
setInterval(() => {
state.downstream_web_socket.send(1)
}, 1000 * 60)
console.log('downstream_web_socket open')
}, },
initWebsocket(state, token) { (e) => {
state.downstream_web_socket = WsConnectionFactory.CreateWebSocket( const data = JSON.parse(e.data)
token, let unread = state.unreadCountMapper[data.sender_id]
() => { if (unread) {
// keep unread++
setInterval(() => { } else {
state.downstream_web_socket.send(1) unread = 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')
}
)
},
readMessageBy(state, sender) {
delete state.unreadCountMapper?.[sender]
}
},
actions: {
setLanguage(context, language) {
context.commit('setLanguage', language)
},
initWebsocket(context, token) {
context.commit('initWebsocket', token)
},
readMessageBy(context, sender) {
context.commit('readMessageBy', sender)
}
},
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 state.unreadCountMapper[data.sender_id] = unread
console.log('downstream_web_socket onmessage: ', data, state.unreadCountMapper)
}, },
unreadCountMapper(state) { () => {
return state.unreadCountMapper console.log('downstream_web_socket error')
},
() => {
console.log('downstream_web_socket closed')
} }
)
},
readMessageBy(state, sender) {
delete state.unreadCountMapper?.[sender]
}
},
actions: {
setLanguage(context, language) {
context.commit('setLanguage', language)
},
initWebsocket(context, token) {
context.commit('initWebsocket', token)
},
readMessageBy(context, sender) {
context.commit('readMessageBy', sender)
}
},
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
},
unreadCountMapper(state) {
return state.unreadCountMapper
} }
} }
}
export { basicStore } export { basicStore }