chore: update latest, add achievements field in work_experience

This commit is contained in:
Jesús Pérez 2024-08-24 23:11:15 +01:00
parent 8d91ba5649
commit da2f714a10
No known key found for this signature in database
19 changed files with 4621 additions and 3235 deletions

View File

@ -6,7 +6,7 @@
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<title>CV Gen</title>
<meta name="description" content="CV Gen to generate and publish CVs">
<script src="https://unpkg.com/@themesberg/flowbite@1.1.0/dist/flowbite.bundle.js"></script>
<script src="https://unpkg.com/@themesberg/flowbite@1.1.0/dist/flowbite.bundle.js"></script>
</head>
<body>
<div id="app"></div>

View File

@ -17,6 +17,7 @@ code: Code
license: License
for: For
role: Role
achievements: Achievements
tasks: Tasks
description: Description
tools: Tools

View File

@ -16,6 +16,7 @@ name: Nombre
code: Código
license: Licencia
for: Para
achievements: Logros
tasks: Tareas
role: Rol
description: Descripción

View File

@ -1,43 +1,43 @@
{
"private": true,
"scripts": {
"dev": "vite --port 3333 --open",
"dev": "vite --port 3333 --host --open",
"build": "cross-env NODE_ENV=production vite build",
"preview": "vite preview"
},
"dependencies": {
"@intlify/vite-plugin-vue-i18n": "^2.5.0",
"@tiptap/extension-link": "^2.0.0-beta.36",
"@tiptap/extension-text-style": "^2.0.0-beta.23",
"@tiptap/starter-kit": "^2.0.0-beta.183",
"@tiptap/vue-3": "^2.0.0-beta.90",
"@tiptap/extension-link": "^2.6.5",
"@tiptap/extension-text-style": "^2.6.5",
"@tiptap/starter-kit": "^2.6.5",
"@tiptap/vue-3": "^2.6.5",
"@vueuse/core": "^6.9.2",
"@vueuse/head": "^0.6.0",
"install": "^0.13.0",
"toastify-js": "^1.11.2",
"vue": "^3.2.31",
"vue-demi": "^0.12.4",
"vue-i18n": "^9.2.0-beta.33",
"vue-router": "^4.0.14",
"toastify-js": "^1.12.0",
"vue": "^3.4.38",
"vue-demi": "^0.12.5",
"vue-i18n": "^9.14.0",
"vue-router": "^4.4.3",
"vue3-highlightjs": "^1.0.5"
},
"devDependencies": {
"@antfu/eslint-config": "^0.11.1",
"@iconify-json/carbon": "^1.1.2",
"@types/node": "^16.11.26",
"@types/toastify-js": "^1.11.0",
"@iconify-json/carbon": "^1.1.37",
"@types/node": "^16.18.105",
"@types/toastify-js": "^1.12.3",
"@unocss/preset-icons": "^0.7.7",
"@unocss/reset": "^0.7.7",
"@vitejs/plugin-vue": "^1.10.2",
"cross-env": "^7.0.3",
"eslint": "^8.11.0",
"pnpm": "^6.32.3",
"typescript": "^4.6.2",
"eslint": "^8.57.0",
"pnpm": "^6.35.1",
"typescript": "^4.9.5",
"unocss": "^0.7.7",
"unplugin-auto-import": "^0.5.11",
"unplugin-icons": "^0.12.23",
"unplugin-vue-components": "^0.17.21",
"vite": "^2.8.6",
"vite": "^2.9.18",
"vite-plugin-inspect": "^0.3.15",
"vite-plugin-md": "^0.11.9",
"vite-plugin-pages": "^0.18.2",

7362
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -84,12 +84,12 @@
<template v-slot:button>
<div class="flex items-center gap-5">
<button
v-if="messageType === MessageBoxType.Select || (messageType === MessageBoxType.Save && data_url_encoded === '')"
v-if="messageType === MessageBoxType.Select || (messageType === MessageBoxType.Save && data_url_encoded === '')"
class="btn-msg flex-grow"
@click="onMessageOkBtn"
>
<span v-if="messageType === MessageBoxType.Select">{{ t('select', 'Select') }}</span>
<span v-if="messageType === MessageBoxType.Save && data_url_encoded === ''" >{{ t('save', 'Save') }}</span>
<span v-if="messageType === MessageBoxType.Select">{{ t('select', 'Select') }}</span>
<span v-if="messageType === MessageBoxType.Save && data_url_encoded === ''" >{{ t('save', 'Save') }}</span>
</button>
<button v-if="messageType === MessageBoxType.OneInput" :disabled="oneinputValue === ''" class="btn-msg flex-grow" @click="onMessageOkBtn">{{ t('save', 'Save') }}</button>
<button v-else class="btn-msg flex-grow" @click="onMessageCloseBtn">{{ t('close', 'Close') }}</button>
@ -115,17 +115,17 @@ const props = defineProps({
default: false,
required: true,
},
show_input: {
show_input: {
type: Boolean,
default: false,
required: false,
},
input_btns: {
input_btns: {
type: Array as PropType<InputBtnsType[]>,
default: [],
required: false,
},
input_placeholder: {
input_placeholder: {
type: String,
default: '',
required: false,
@ -140,7 +140,7 @@ const props = defineProps({
default: '',
required: false,
},
inpType: {
inpType: {
type: String,
default: 'text',
required: false,
@ -163,21 +163,21 @@ const onMessageOkBtn = () => {
switch(props.messageType) {
case MessageBoxType.Save:
if (inputSaveMode.value === 'send') {
emit('onMessageBox', { src: 'sendata', val: inputValue.value })
emit('onMessageBox', { src: 'sendata', val: inputValue.value })
} else {
emit('onMessageBox', { src: 'savedata', val: inputValue.value })
}
emit('onMessageBox', { src: 'savedata', val: inputValue.value })
}
break
case MessageBoxType.Select:
if (useState().current_model.value.id !== selectValue.value) {
emit('onLoadModel', { id: selectValue.value })
if (useState().current_model.value.id !== selectValue.value) {
emit('onLoadModel', { id: selectValue.value })
}
emit('onMessageBox', { src: 'done' })
emit('onMessageBox', { src: 'done' })
break
case MessageBoxType.OneInput:
if (oneinputValue.value !== '') {
emit('onMessageBox', { src: 'oneinput', val: oneinputValue.value })
}
emit('onMessageBox', { src: 'oneinput', val: oneinputValue.value })
}
// emit('onMessageBox', { src: 'done' })
break
}

View File

@ -1,7 +1,7 @@
<template>
<nav
class="noprint flex flex-row gap-2 mx-1 mt-1 border-b-1 border-gray-800 dark:border-gray-500 bg-indigo-100 dark:bg-gray-800 dark:text-white"
:class="{ 'fixed z-50 w-full lg:w-screen-xl -top-2 pt-2 border-1': position === NavPosition.header && fixMenu, 'z-1 opacity-20': openMessageBox }"
:class="{ 'fixed z-50 w-full lg:w-screen-2xl -top-2 pt-2 border-1': position === NavPosition.header && fixMenu, 'z-1 opacity-20': openMessageBox }"
>
<button
type="button"
@ -306,4 +306,4 @@ const onNeedSaveBtn = () => {
goTopPage()
emit('onNavMenu', { src: 'save' })
}
</script>
</script>

View File

@ -39,61 +39,62 @@ export interface WorkExperienceType {
[key: string]: any
auth: AuthInfoType
date: string
where: string
wheredef: string
location: string
position: string
description: string
tools: string[]
tasks: string[]
where: string
wheredef: string
location: string
position: string
description: string
tools: string[]
achievements: string[]
tasks: string[]
}
export interface TalksType {
[key: string]: any
auth: AuthInfoType
date: string
title: string
org: string
location: string
description: string[]
title: string
org: string
location: string
description: string[]
}
export interface TeachingType {
[key: string]: any
auth: AuthInfoType
date: string
title: string
org: string
location: string
description: string[]
title: string
org: string
location: string
description: string[]
}
export interface EducationType {
[key: string]: any
auth: AuthInfoType
date: string
title: string
org: string
location: string
title: string
org: string
location: string
cert: string
description: string[]
tools: string[]
description: string[]
tools: string[]
}
export interface ProjectType {
[key: string]: any
auth: AuthInfoType
date: string
name: string
title: string
img: string
site: string
code: string
purpose: string
for: string
position: string
license: string
demo: string
capture: string
description: string
features: string[]
builtwith: string[]
name: string
title: string
img: string
site: string
code: string
purpose: string
for: string
position: string
license: string
demo: string
capture: string
description: string
features: string[]
builtwith: string[]
}
export interface ProfileType {
[key: string]: unknown;
@ -113,49 +114,49 @@ export interface MissionHowType {
export interface DataCoreType {
[key: string]: any
name: string
fullname: string
title1: string
title2: string
imgalt: string
imgsrc: string
email: string
phone: string
address: string
postalcode: string
state: string
city: string
country: string
birthdate: string
status: string
mission: string
mission_how: MissionHowType[]
fullname: string
title1: string
title2: string
imgalt: string
imgsrc: string
email: string
phone: string
address: string
postalcode: string
state: string
city: string
country: string
birthdate: string
status: string
mission: string
mission_how: MissionHowType[]
profile: ProfileType[]
certifications: CertificationType[]
skills: SkillsType[]
soft_skills: SkillsType[]
infra: SkillsType[]
sites: SitesType[]
langs: LangsType[]
certifications: CertificationType[]
skills: SkillsType[]
soft_skills: SkillsType[]
infra: SkillsType[]
sites: SitesType[]
langs: LangsType[]
}
export interface DataLangType {
[key: string]: any
imgalt: string
title1: string
title2: string
country: string
birthdate: string
status: string
mission: string
mission_how: MissionHowType[]
imgalt: string
title1: string
title2: string
country: string
birthdate: string
status: string
mission: string
mission_how: MissionHowType[]
profile: ProfileType[]
certifications: CertificationType[]
work_experiences: WorkExperienceType[]
certifications: CertificationType[]
work_experiences: WorkExperienceType[]
projects: ProjectType[]
education: EducationType[]
talks: TalksType[]
teaching: TeachingType[]
others: OtherType[]
education: EducationType[]
talks: TalksType[]
teaching: TeachingType[]
others: OtherType[]
}
export interface DataLangsType {
[key: string]: DataLangType
@ -188,6 +189,7 @@ export interface ShowWorkExperienceType {
position: boolean
description: boolean
tools: boolean
achievements: boolean
tasks: boolean
}
export interface ShowEducationType {
@ -204,21 +206,21 @@ export interface ShowEducationType {
export interface ShowProjectType {
[key: string]: unknown;
auth: AuthInfoType
name: boolean
img: boolean
title: boolean
purpose: boolean
site: boolean
code: boolean
date: boolean
for: boolean
position: boolean
license: boolean
demo: boolean
capture: boolean
description: boolean
features: boolean
builtwith: boolean
name: boolean
img: boolean
title: boolean
purpose: boolean
site: boolean
code: boolean
date: boolean
for: boolean
position: boolean
license: boolean
demo: boolean
capture: boolean
description: boolean
features: boolean
builtwith: boolean
}
export interface ShowInfoType {
[key: string]: any
@ -231,33 +233,33 @@ export interface ShowInfoType {
// save: boolean
fullname: boolean
personal: boolean
title: boolean
image: boolean
mission: boolean
mission_how: boolean
phone: boolean
address: boolean
status: boolean
birthdate: boolean
sites: boolean
skills: boolean
skills_itms: boolean
soft_skills: boolean
soft_skills_itms: boolean
infra: boolean
certs: boolean
langs: boolean
title: boolean
image: boolean
mission: boolean
mission_how: boolean
phone: boolean
address: boolean
status: boolean
birthdate: boolean
sites: boolean
skills: boolean
skills_itms: boolean
soft_skills: boolean
soft_skills_itms: boolean
infra: boolean
certs: boolean
langs: boolean
profile: boolean
work_experience_itms: boolean
work_experience: ShowWorkExperienceType
project_itms: boolean
projects: ShowProjectType
education_itms: boolean
education: ShowEducationType
education: ShowEducationType
talks_itms: boolean
talks: ShowTalksType
talks: ShowTalksType
teaching_itms: boolean
teaching: ShowTeachingType
teaching: ShowTeachingType
others_itms: boolean
others: boolean
}
@ -280,11 +282,11 @@ export interface InputBtnsType {
show: boolean
}
export enum MessageBoxType {
Save = 'save',
Select = 'select',
Input = 'input',
OneInput = 'oneinput',
NotSet = '',
Save = 'save',
Select = 'select',
Input = 'input',
OneInput = 'oneinput',
NotSet = '',
}
export enum NavPosition {
header = 'header',

View File

@ -17,7 +17,7 @@
@onLoadModel="onLoadModel"
/>
<div v-if="show_content && cvdata.core && cvdata.core.name" class="font-sans antialiased">
<div class="container mx-auto max-w-screen-xl main-container">
<div class="container mx-auto max-w-screen-2xl main-container">
<nav-menu
:position="NavPosition.header"
:openMessageBox="openMessageBox"
@ -25,7 +25,7 @@
:show_infopanel="show_infopanel"
:showinfo="show_info"
:authinfo="auth_info"
:useLogin="false"
:useLogin="false"
:needSave="needSave"
prefix='cv'
@onNavMenu="onNavMenu"
@ -68,7 +68,7 @@
:authinfo="auth_info"
@onItem="onItem"
@onEditor="onEditor" />
</div>
</div>
<div class="prose">
<h2
:class="show_info.profile ? 'section-headline' : `noprint ${auth_info.viewchange ? 'pb-11' : ''}`"
@ -129,7 +129,7 @@
<projects-view
v-if="sec === 'projects' && show_info[`${sec}_itms`]"
:data="data_info[sec]"
:localedata="localedata"
:localedata="localedata"
:showinfo="show_info[sec]"
@onEditor="onEditor"
@onItem="onItem"
@ -137,7 +137,7 @@
<work-experience-view
v-if="sec === 'work_experience' && show_info[`${sec}_itms`]"
:data="data_info[sec]"
:localedata="localedata"
:localedata="localedata"
:showinfo="show_info[sec]"
@onEditor="onEditor"
@onItem="onItem"
@ -145,7 +145,7 @@
<education-view
v-if="sec === 'education' && show_info[`${sec}_itms`]"
:data="data_info[sec]"
:localedata="localedata"
:localedata="localedata"
:showinfo="show_info[sec]"
@onEditor="onEditor"
@onItem="onItem"
@ -153,7 +153,7 @@
<teaching-view
v-if="sec === 'teaching' && show_info[`${sec}_itms`]"
:data="data_info[sec]"
:localedata="localedata"
:localedata="localedata"
:showinfo="show_info[sec]"
@onEditor="onEditor"
@onItem="onItem"
@ -161,7 +161,7 @@
<talks-view
v-if="sec === 'talks' && show_info[`${sec}_itms`]"
:data="data_info[sec]"
:localedata="localedata"
:localedata="localedata"
:showinfo="show_info[sec]"
@onEditor="onEditor"
@onItem="onItem"
@ -169,7 +169,7 @@
<others-view
v-if="sec === 'others' && show_info[`${sec}_itms`]"
:data="data_info.others"
:localedata="localedata"
:localedata="localedata"
:showinfo="show_info"
@onEditor="onEditor"
@onItem="onItem"
@ -188,20 +188,19 @@
>
<div i-carbon-home />
</button>
<info-panel-skills
:data="data_info.core"
:localedata="localedata"
:showinfo="show_info"
:authinfo="auth_info"
@onItem="onItem"
@onEditor="onEditor" />
<info-panel-skills
:data="data_info.core"
:localedata="localedata"
:showinfo="show_info"
:authinfo="auth_info"
@onItem="onItem"
@onEditor="onEditor" />
</div>
</div>
</main>
<div
v-if="show_content && cvdata.core && cvdata.core.name"
v-if="show_content && cvdata.core && cvdata.core.name"
class="mr-auto w-full lg:w-1/2 text-center text-sm py-2 pr-5 text-gray-600 border-gray-300 border-1 border-b-0 rounded-t-lg"
>
<nav-menu
:position="NavPosition.footer"
@ -209,10 +208,10 @@
:show_infopanel="show_infopanel"
:showinfo="show_info"
:authinfo="auth_info"
:useLogin="false"
:useLogin="false"
:needSave="needSave"
prefix='cv'
:openMessageBox="openMessageBox"
:openMessageBox="openMessageBox"
@onNavMenu="onNavMenu"
/>
</div>
@ -292,7 +291,7 @@ const onInput = (btn: InputBtnsType) => {
const current_model = useState().current_model
const select_ops = computed(() => {
if (useState().current_modelid.value) {
return Object.fromEntries(Object.entries(useState().models.value).filter(([key]) => key !== useState().current_modelid.value)) as ModelType
return Object.fromEntries(Object.entries(useState().models.value).filter(([key]) => key !== useState().current_modelid.value)) as ModelType
}
return useState().models.value
})
@ -309,7 +308,7 @@ const show_info = computed(() => {
default:
break
}
useState().authinfo.value = showinfo.auth ? showinfo.auth : { editable: false, viewchange: false, show: true }
useState().authinfo.value = showinfo.auth ? showinfo.auth : { editable: false, viewchange: false, show: true }
return showinfo
})
const auth_info = useState().authinfo
@ -323,28 +322,28 @@ const onItem = (data: { root: string, src: string, _itm: any, idx: number }) =>
switch(data.root) {
case 'info':
const source = useState().datalang.value[i18n.locale.value] && useState().datalang.value[i18n.locale.value].corelang && useState().datalang.value[i18n.locale.value].corelang[data.src] ? 'corelang': 'core'
if (source === 'corelang') {
if (source === 'corelang') {
if (data.idx > -1) {
useState().datalang.value[i18n.locale.value][source][data.src][data.idx].auth.show = !useState().datalang.value[i18n.locale.value][source][data.src][data.idx].auth.show
useState().datalang.value[i18n.locale.value][source][data.src][data.idx].auth.show = !useState().datalang.value[i18n.locale.value][source][data.src][data.idx].auth.show
} else {
useState().datalang.value[i18n.locale.value][source][data.src].auth.show = !useState().datalang.value[i18n.locale.value][source][data.src].auth.show
useState().datalang.value[i18n.locale.value][source][data.src].auth.show = !useState().datalang.value[i18n.locale.value][source][data.src].auth.show
}
} else {
if (data.idx > -1) {
useState().cvdata.value[source][data.src][data.idx].auth.show = !useState().cvdata.value[source][data.src][data.idx].auth.show
useState().cvdata.value[source][data.src][data.idx].auth.show = !useState().cvdata.value[source][data.src][data.idx].auth.show
} else {
useState().cvdata.value[source][data.src].auth.show = !useState().cvdata.value[source][data.src].auth.show
useState().cvdata.value[source][data.src].auth.show = !useState().cvdata.value[source][data.src].auth.show
}
}
break
default:
if (data.src !== '' && data.idx > -1) {
if (useState().datalang.value[i18n.locale.value] && useState().datalang.value[i18n.locale.value][data.src] && useState().datalang.value[i18n.locale.value][data.src][data.idx]) {
useState().datalang.value[i18n.locale.value][data.src][data.idx].auth.show = !useState().datalang.value[i18n.locale.value][data.src][data.idx].auth.show
} else if (useState().cvdata.value[data.src] && useState().cvdata.value[data.src][data.idx]) {
useState().cvdata.value[data.src][data.idx].auth.show = !useState().cvdata.value[data.src][data.idx].auth.show
default:
if (data.src !== '' && data.idx > -1) {
if (useState().datalang.value[i18n.locale.value] && useState().datalang.value[i18n.locale.value][data.src] && useState().datalang.value[i18n.locale.value][data.src][data.idx]) {
useState().datalang.value[i18n.locale.value][data.src][data.idx].auth.show = !useState().datalang.value[i18n.locale.value][data.src][data.idx].auth.show
} else if (useState().cvdata.value[data.src] && useState().cvdata.value[data.src][data.idx]) {
useState().cvdata.value[data.src][data.idx].auth.show = !useState().cvdata.value[data.src][data.idx].auth.show
}
}
}
}
}
const onView = (itm: string) => {
@ -355,27 +354,27 @@ const onNavMenu = (item: { src: string, target: string }) => {
const lng = i18n.locale.value
switch (item.src) {
case 'locale':
track_action(null, { ref: 'locale',text: i18n.locale.value, lng},routeKy.toString())
track_action(null, { ref: 'locale',text: i18n.locale.value, lng},routeKy.toString())
refresh()
break
case 'infopanel':
track_action(null, { ref: 'onNavMenu',text: item.src, lng},routeKy.toString())
track_action(null, { ref: 'onNavMenu',text: item.src, lng},routeKy.toString())
show_infopanel.value = !show_infopanel.value
break
case 'fixmenu':
track_action(null, { ref: 'onNavMenu',text: item.src, lng},routeKy.toString())
track_action(null, { ref: 'onNavMenu',text: item.src, lng},routeKy.toString())
fixMenu.value = !fixMenu.value
break
case 'endinput':
show_input.value = false
break
case 'select':
track_action(null, { ref: 'onNavMenu',text: item.src, lng},routeKy.toString())
track_action(null, { ref: 'onNavMenu',text: item.src, lng},routeKy.toString())
message_type.value = MessageBoxType.Select
openMessageBox.value = true
break
case 'save':
track_action(null, { ref: 'onNavMenu',text: item.src, lng},routeKy.toString())
track_action(null, { ref: 'onNavMenu',text: item.src, lng},routeKy.toString())
input_placeholder.value = `${t('name', 'Name')} o 'data'`
show_input.value = true
message_type.value = MessageBoxType.Save
@ -383,20 +382,20 @@ const onNavMenu = (item: { src: string, target: string }) => {
openMessageBox.value = true
break
case 'editable':
track_action(null, { ref: 'onNavMenu',text: item.src, lng},routeKy.toString())
track_action(null, { ref: 'onNavMenu',text: item.src, lng},routeKy.toString())
useState().authinfo.value.editable = !useState().authinfo.value.editable
const state = useState().authinfo.value.editable ? 'on' : 'off'
const msgTyp = state === 'on' ? MessageType.Warning : MessageType.Info
show_message(msgTyp, `${t('saveload.editMode','Edit Mode')} ${t('cv.'+state,'')}`)
show_message(msgTyp, `${t('saveload.editMode','Edit Mode')} ${t('cv.'+state,'')}`)
break
case 'viewchange':
track_action(null, { ref: 'onNavMenu',text: item.src, lng},routeKy.toString())
track_action(null, { ref: 'onNavMenu',text: item.src, lng},routeKy.toString())
useState().authinfo.value.viewchange = !useState().authinfo.value.viewchange
break
case 'goto':
const dom_id = document.getElementById(item.target)
if (dom_id) {
track_action(null, { ref: 'gotp',text: item.target, lng},routeKy.toString())
track_action(null, { ref: 'gotp',text: item.target, lng},routeKy.toString())
dom_id.scrollIntoView({ behavior: 'smooth', block: 'start', inline: 'nearest' })
setTimeout(() => window.scrollBy(0, -40), 4000)
}
@ -405,7 +404,7 @@ const onNavMenu = (item: { src: string, target: string }) => {
}
const saveData = async(mode: string,val: string) => {
const showinfo: ShowInfoType[] = useState().cvdata.value.showinfo
message_type.value = MessageBoxType.Save
message_type.value = MessageBoxType.Save
const payload = parseJwt(localStorage.getItem(useState().AUTHKEY.value))
const cv: any = {
u: payload.id ? payload.id : '',
@ -413,27 +412,27 @@ const saveData = async(mode: string,val: string) => {
}
cv.data[val]={}
Object.keys(useState().datalang.value).forEach(lng =>
cv.data[val][lng] = useState().datalang.value[lng]
cv.data[val][lng] = useState().datalang.value[lng]
)
cv.data[val].main = useState().cvdata.value
showinfo.forEach((it,idx) => {
if (it.ky === useState().showinfo.value.ky) {
cv.data[val].main[idx] = useState().showinfo.value
cv.data[val].main[idx] = useState().showinfo.value
}
})
const url = useState().CONFURLS.value.send || ''
if (mode == 'send' && url !== '') {
onMessageBox({src: 'done', val: ''})
const res = await send_data(url, cv, true, true, () => {
track_action(null, { ref: 'saveData',text: `${url} -> ${val}`, lng: i18n.locale.value },routeKy.toString())
show_message(MessageType.Success, `${t('saveload.dataSaved','Data saved')}`,2000,() => {
})
track_action(null, { ref: 'saveData',text: `${url} -> ${val}`, lng: i18n.locale.value },routeKy.toString())
show_message(MessageType.Success, `${t('saveload.dataSaved','Data saved')}`,2000,() => {
})
})
console.log(res)
} else {
track_action(null, { ref: 'saveData',text: `local_json -> ${val}`, lng: i18n.locale.value },routeKy.toString())
track_action(null, { ref: 'saveData',text: `local_json -> ${val}`, lng: i18n.locale.value },routeKy.toString())
show_message(MessageType.Warning, `${t('saveload.saveData','Save data')}`,2000,() => {
data_url_encoded.value = `text/json;charset=utf-8,${encodeURIComponent(JSON.stringify(cv))}`
data_url_encoded.value = `text/json;charset=utf-8,${encodeURIComponent(JSON.stringify(cv))}`
})
}
}
@ -451,16 +450,16 @@ const onMessageBox = (item: { src: string, val: string }) => {
const r = async() => {
if (await checkUserAuth(item.val)) {
oneInputType.value='text'
openMessageBox.value = false
if (!await load_currentRoute(router.currentRoute.value)) {
show_message(MessageType.Error, `${t('saveload.loaderror','Load error')}`,2000)
openMessageBox.value = false
if (!await load_currentRoute(router.currentRoute.value)) {
show_message(MessageType.Error, `${t('saveload.loaderror','Load error')}`,2000)
}
} else {
show_message(MessageType.Error, `${t('saveload.autherror','Auth error')}`,2000)
}
}
r()
break
break
case 'endinput':
show_input.value = false
break
@ -492,16 +491,16 @@ const onLoadModel = (model: { id: string}) => {
const url = useState().CONFURLS.value.data || ''
if (useState().models.value[model.id] && url.length > 0 ) {
load_data_model(model.id, url, routeKy as string,true,() => {
show_content.value = false
show_message(MessageType.Success, `${t('saveload.dataLoaded','Data loaded')}`,2000,() => {
show_content.value = true
show_content.value = false
show_message(MessageType.Success, `${t('saveload.dataLoaded','Data loaded')}`,2000,() => {
show_content.value = true
})
})
}
}
}
const update_field = (root: string, field: string, idx: number, data: string | string[]) => {
if (useState().datalang.value[i18n.locale.value] && useState().datalang.value[i18n.locale.value][root]) {
if (idx > -1) {
if (idx > -1) {
if (useState().datalang.value[i18n.locale.value][root][idx]) {
useState().datalang.value[i18n.locale.value][root][idx][field] = data
} else if (useState().datalang.value[i18n.locale.value][root][field][idx]) {
@ -511,9 +510,9 @@ const update_field = (root: string, field: string, idx: number, data: string | s
useState().datalang.value[i18n.locale.value][root][field] = data
}
} else if (useState().cvdata.value[root]) {
if (idx > -1 ) {
if (idx > -1 ) {
if (useState().cvdata.value[root][idx]) {
useState().cvdata.value[root][idx][field] = data
useState().cvdata.value[root][idx][field] = data
} else if (useState().cvdata.value[root][field][idx]) {
useState().cvdata.value[root][field][idx] = data
}
@ -536,9 +535,9 @@ const onEditor = (item: { src: string, field: string, idx: number, data: string,
case 'profile':
case 'mission_how':
if (source === 'corelang' && useState().datalang.value[i18n.locale.value][source][src][item.idx][item.field]) {
useState().datalang.value[i18n.locale.value][source][src][item.idx][item.field] = item.data
useState().datalang.value[i18n.locale.value][source][src][item.idx][item.field] = item.data
} else if (useState().cvdata.value[source][src][item.idx][item.field]) {
useState().cvdata.value[source][src][item.idx][item.field] = item.data
useState().cvdata.value[source][src][item.idx][item.field] = item.data
}
break
default:
@ -597,4 +596,4 @@ onBeforeMount(async() => {
input_placeholder.value='Enter password'
}
})
</script>
</script>

View File

@ -462,18 +462,18 @@ const routeKy = router.currentRoute.value.params.ky || router.currentRoute.value
const assets_path = useState().ASSETS_PATH.value
const showinfo = ref(props.showinfo as ShowInfoType)
const authinfo = computed(() => {
return showinfo.value.auth ? showinfo.value.auth : props.authinfo
return showinfo.auth ? showinfo.auth : props.authinfo
})
const get_data = (itm: string) => {
return props.localedata.value && props.localedata.value.corelang && props.localedata.value.corelang[itm] ? props.localedata.value.corelang[itm] : props.data[itm]
return props.localedata && props.localedata.corelang && props.localedata.corelang[itm] ? props.localedata.corelang[itm] : props.data[itm]
}
const onView = (itm: string) => {
if (typeof showinfo.value[itm] !== 'undefined') {
showinfo.value[itm] = !showinfo.value[itm]
if (typeof showinfo[itm] !== 'undefined') {
showinfo[itm] = !showinfo[itm]
if (itm === 'skills')
useState().showinfo.value.skills = showinfo.value[itm]
useState().showinfo.value.skills = showinfo[itm]
else if (itm === 'soft_skills')
useState().showinfo.value.soft_skills = showinfo.value[itm]
useState().showinfo.value.soft_skills = showinfo[itm]
}
}
const onEditor = (info: { src: string, field: string, idx: number, data: string, ev: Event }) => {

View File

@ -300,14 +300,14 @@ const routeKy = router.currentRoute.value.params.ky || router.currentRoute.value
const assets_path = useState().ASSETS_PATH.value
const showinfo = ref(props.showinfo as ShowInfoType)
const authinfo = computed(() => {
return showinfo.value.auth ? showinfo.value.auth : props.authinfo
return showinfo.auth ? showinfo.auth : props.authinfo
})
const get_data = (itm: string) => {
return props.localedata.value && props.localedata.value.corelang && props.localedata.value.corelang[itm] ? props.localedata.value.corelang[itm] : props.data[itm]
return props.localedata && props.localedata.corelang && props.localedata.corelang[itm] ? props.localedata.corelang[itm] : props.data[itm]
}
const onView = (itm: string) => {
if (typeof showinfo.value[itm] !== 'undefined') {
showinfo.value[itm] = !showinfo.value[itm]
if (typeof showinfo[itm] !== 'undefined') {
showinfo[itm] = !showinfo[itm]
// if (itm === 'skills')
// useState().showinfo.value.skills = showinfo.value[itm]
}

View File

@ -202,15 +202,15 @@ const authinfo = computed(() => {
return showinfo.value.auth ? showinfo.value.auth : props.authinfo
})
const get_data = (itm: string) => {
return props.localedata.value && props.localedata.value.corelang && props.localedata.value.corelang[itm] ? props.localedata.value.corelang[itm] : props.data[itm]
return props.localedata && props.localedata.corelang && props.localedata.corelang[itm] ? props.localedata.corelang[itm] : props.data[itm]
}
const onView = (itm: string) => {
if (typeof showinfo.value[itm] !== 'undefined') {
showinfo.value[itm] = !showinfo.value[itm]
if (typeof showinfo[itm] !== 'undefined') {
showinfo[itm] = !showinfo[itm]
if (itm === 'skills')
useState().showinfo.value.skills = showinfo.value[itm]
useState().showinfo.skills = showinfo[itm]
else if (itm === 'soft_skills')
useState().showinfo.value.soft_skills = showinfo.value[itm]
useState().showinfo.soft_skills = showinfo[itm]
}
}

View File

@ -66,7 +66,7 @@ const props = defineProps({
})
const emit = defineEmits(['onEditor', 'onItem'])
const get_data = (itm: string) => {
return props.localedata.value && props.localedata.value[itm] ? props.localedata.value[itm] : props.data
return props.localedata && props.localedata[itm] ? props.localedata[itm] : props.data
}
const htmlattrs = { ...useState().htmlAttrs, bold: 'itm-title' }
const authinfo = useState().authinfo.value

View File

@ -59,7 +59,7 @@ const props = defineProps({
},
})
const get_data = (itm: string) => {
return props.localedata.value && props.localedata.value.corelang && props.localedata.value.corelang[itm] ? props.localedata.value.corelang[itm] : props.data
return props.localedata && props.localedata.core && props.localedata.core[itm] ? props.localedata.core[itm] : props.data
}
const authinfo = computed(() => {
return props.showinfo.auth ? props.showinfo.auth : props.authinfo

View File

@ -170,7 +170,7 @@ const props = defineProps({
})
const emit = defineEmits(['onEditor', 'onItem'])
const get_data = (itm: string) => {
return props.localedata.value && props.localedata.value[itm] ? props.localedata.value[itm] : props.data
return props.localedata && props.localedata[itm] ? props.localedata[itm] : props.data
}
const routeKy = router.currentRoute.value.params.ky || router.currentRoute.value.query.k || ''
const assets_path = useState().ASSETS_PATH

View File

@ -58,7 +58,7 @@ const props = defineProps({
})
const emit = defineEmits(['onItem'])
const get_data = (itm: string) => {
return props.localedata.value && props.localedata.value.corelang && props.localedata.value.corelang[itm] ? props.localedata.value.corelang[itm] : props.data
return props.localedata && props.localedata.corelang && props.localedata.corelang[itm] ? props.localedata.corelang[itm] : props.data
}
const onItem = (idx: number) => {
emit('onItem', { src: props.src, itm: props.data[idx], idx })

View File

@ -99,7 +99,7 @@ const props = defineProps({
})
const emit = defineEmits(['onEditor', 'onItem'])
const get_data = (itm: string) => {
return props.localedata.value && props.localedata.value[itm] ? props.localedata.value[itm] : props.data
return props.localedata && props.localedata[itm] ? props.localedata[itm] : props.data
}
const authinfo = useState().authinfo.value
const onEditor = (info: { src: string, field: string, idx: number, data: string, ev: Event }) => {

View File

@ -99,7 +99,7 @@ const props = defineProps({
})
const emit = defineEmits(['onEditor', 'onItem'])
const get_data = (itm: string) => {
return props.localedata.value && props.localedata.value[itm] ? props.localedata.value[itm] : props.data
return props.localedata && props.localedata[itm] ? props.localedata[itm] : props.data
}
const authinfo = useState().authinfo.value
const onEditor = (info: { src: string, field: string, idx: number, data: string, ev: Event }) => {

View File

@ -1,5 +1,5 @@
<template>
<div v-for="(item,index) in get_data('work_experiences')" :key="index" class="experience-item">
<div v-for="(item,index) in get_data('work_experience')" :key="index" class="experience-item">
<div class="flex">
<span class="w-4/5 flex-grow" />
<button
@ -8,7 +8,7 @@
@click.prevent="onItem(index)"
>
<div v-if="item.auth.show" class="noprint flex text-gray-400 dark:text-gray-500">
<div i-carbon-view-off />
<div i-carbon-view-off />
<div class="mt-0.2 ml-2">{{ index }}</div>
</div>
<div v-else class="noprint flex text-indigo-400 dark:text-indigo-500">
@ -20,7 +20,7 @@
<div v-if="item.auth.show" :id="`experience-${index}`">
<div v-for="info,key,infoindex in showinfo" :key="infoindex">
<section
v-if="info && item[key] && key !== 'wheredef' && key !== 'tools' && key !== 'tasks' && key !== 'auth'"
v-if="info && item[key] && key !== 'wheredef' && key !== 'tools' && key !== 'achievements' && key !== 'tasks' && key !== 'auth'"
class="mb-0"
>
<div class="left-item">
@ -68,6 +68,29 @@
</span>
</div>
</section>
<section
v-if="key === 'achievements' && item.achievements && Object.keys(item.achievements).length > 0"
class="mt-1"
>
<div class="left-item">
<span class="text-gray-400 dark:text-gray-500">{{ t(key, key).toLocaleLowerCase() }}</span>
</div>
<div class="right-item">
<ul class="list-circle">
<tiptap-editor
v-if="authinfo.editable"
:data="`<li>${item[key].join('</li><li>')}</li>`"
:editable="authinfo.editable"
src="work_experience"
:field="key"
:htmlattrs="{ ...useState().htmlAttrs, bold: 'itm-title font-normal' }"
:idx="index"
@onEditorBlur="onEditor"
/>
<span v-else v-html="`<li>${item[key].join('</li><li>')}</li>`" />
</ul>
</div>
</section>
<section
v-if="key === 'tasks' && item.tasks && Object.keys(item.tasks).length > 0"
class="mt-1"
@ -143,7 +166,7 @@ const props = defineProps({
})
const emit = defineEmits(['onEditor', 'onItem'])
const get_data = (itm: string) => {
return props.localedata.value && props.localedata.value[itm] ? props.localedata.value[itm] : props.data
return props.localedata && props.localedata[itm] ? props.localedata[itm] : props.data
}
const authinfo = useState().authinfo.value
const onEditor = (info: { src: string, field: string, idx: number, data: string, ev: Event }) => {