feat: open to opportunities
This commit is contained in:
@@ -13,13 +13,8 @@
|
||||
}"
|
||||
>
|
||||
<template #body-content>
|
||||
<div class="grid grid-cols-2 gap-5">
|
||||
<div class="space-y-4">
|
||||
<!-- <Uploader
|
||||
v-model="profile.image.file_url"
|
||||
label="Profile Image"
|
||||
description="Your profile image to help others recognize you."
|
||||
/> -->
|
||||
<div>
|
||||
<div class="grid grid-cols-2 gap-10">
|
||||
<div>
|
||||
<div class="text-xs text-ink-gray-5 mb-1">
|
||||
{{ __('Profile Image') }}
|
||||
@@ -66,26 +61,58 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<FormControl v-model="profile.first_name" :label="__('First Name')" />
|
||||
<FormControl v-model="profile.last_name" :label="__('Last Name')" />
|
||||
<FormControl v-model="profile.headline" :label="__('Headline')" />
|
||||
<Link
|
||||
:label="__('Language')"
|
||||
v-model="profile.language"
|
||||
doctype="Language"
|
||||
<Switch
|
||||
v-model="profile.looking_for_job"
|
||||
:label="__('Open to Opportunities')"
|
||||
:description="
|
||||
__('Show recruiters and others that you are open to work.')
|
||||
"
|
||||
class="!px-0"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div class="mb-4">
|
||||
<div class="mb-1.5 text-sm text-ink-gray-5">
|
||||
{{ __('Bio') }}
|
||||
|
||||
<div class="grid grid-cols-2 gap-10">
|
||||
<div class="space-y-4">
|
||||
<div class="space-y-4">
|
||||
<FormControl
|
||||
v-model="profile.first_name"
|
||||
:label="__('First Name')"
|
||||
/>
|
||||
<FormControl
|
||||
v-model="profile.last_name"
|
||||
:label="__('Last Name')"
|
||||
/>
|
||||
<FormControl v-model="profile.headline" :label="__('Headline')" />
|
||||
|
||||
<FormControl
|
||||
v-model="profile.linkedin"
|
||||
:label="__('LinkedIn ID')"
|
||||
/>
|
||||
<FormControl v-model="profile.github" :label="__('GitHub ID')" />
|
||||
<FormControl
|
||||
v-model="profile.twitter"
|
||||
:label="__('Twitter ID')"
|
||||
/>
|
||||
</div>
|
||||
<TextEditor
|
||||
:fixedMenu="true"
|
||||
@change="(val) => (profile.bio = val)"
|
||||
:content="profile.bio"
|
||||
editorClass="prose-sm py-2 px-2 min-h-[200px] border-outline-gray-2 hover:border-outline-gray-3 rounded-b-md bg-surface-gray-3"
|
||||
</div>
|
||||
<div class="space-y-4">
|
||||
<Link
|
||||
:label="__('Language')"
|
||||
v-model="profile.language"
|
||||
doctype="Language"
|
||||
/>
|
||||
<div>
|
||||
<div class="mb-1.5 text-sm text-ink-gray-5">
|
||||
{{ __('Bio') }}
|
||||
</div>
|
||||
<TextEditor
|
||||
:fixedMenu="true"
|
||||
@change="(val) => (profile.bio = val)"
|
||||
:content="profile.bio"
|
||||
:rows="15"
|
||||
editorClass="prose-sm py-2 px-2 min-h-[200px] border-outline-gray-2 hover:border-outline-gray-3 rounded-b-md bg-surface-gray-3"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -94,11 +121,12 @@
|
||||
</template>
|
||||
<script setup>
|
||||
import {
|
||||
Button,
|
||||
createResource,
|
||||
Dialog,
|
||||
FormControl,
|
||||
FileUploader,
|
||||
Button,
|
||||
createResource,
|
||||
Switch,
|
||||
TextEditor,
|
||||
toast,
|
||||
} from 'frappe-ui'
|
||||
@@ -123,6 +151,10 @@ const profile = reactive({
|
||||
headline: '',
|
||||
bio: '',
|
||||
image: '',
|
||||
looking_for_job: false,
|
||||
linkedin: '',
|
||||
github: '',
|
||||
twitter: '',
|
||||
})
|
||||
|
||||
const imageResource = createResource({
|
||||
@@ -199,6 +231,10 @@ watch(
|
||||
profile.headline = newVal.headline
|
||||
profile.language = newVal.language
|
||||
profile.bio = newVal.bio
|
||||
profile.looking_for_job = newVal.looking_for_job
|
||||
profile.linkedin = newVal.linkedin
|
||||
profile.github = newVal.github
|
||||
profile.twitter = newVal.twitter
|
||||
if (newVal.user_image) imageResource.submit({ image: newVal.user_image })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,26 @@
|
||||
<template>
|
||||
<Tooltip :text="user.full_name">
|
||||
<Avatar
|
||||
class="avatar border border-outline-gray-2 cursor-auto"
|
||||
v-if="user"
|
||||
:label="user.full_name"
|
||||
:image="user.user_image"
|
||||
:size="size"
|
||||
v-bind="$attrs"
|
||||
/>
|
||||
</Tooltip>
|
||||
<Avatar
|
||||
class="avatar border border-outline-gray-2 cursor-auto"
|
||||
v-if="user"
|
||||
:label="user.full_name"
|
||||
:image="user.user_image"
|
||||
:size="size"
|
||||
v-bind="$attrs"
|
||||
>
|
||||
<template v-if="user.looking_for_job" #indicator>
|
||||
<Tooltip :text="__('Open to Opportunities')" placement="right">
|
||||
<div class="rounded-full bg-surface-green-3 w-fit">
|
||||
<BadgeCheckIcon :class="'text-ink-white ' + checkSize" />
|
||||
</div>
|
||||
</Tooltip>
|
||||
</template>
|
||||
</Avatar>
|
||||
</template>
|
||||
<script setup>
|
||||
import { Avatar, Tooltip } from 'frappe-ui'
|
||||
import { BadgeCheckIcon } from 'lucide-vue-next'
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
user: {
|
||||
type: Object,
|
||||
@@ -21,4 +30,15 @@ const props = defineProps({
|
||||
type: String,
|
||||
},
|
||||
})
|
||||
|
||||
const checkSize = computed(() => {
|
||||
let sizeMap = {
|
||||
sm: 'size-1',
|
||||
md: 'size-2',
|
||||
lg: 'size-3',
|
||||
xl: 'size-3',
|
||||
'2xl': 'size-3',
|
||||
}
|
||||
return sizeMap[props.size] || 'size-3'
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -50,12 +50,8 @@
|
||||
class="flex sm:rounded px-3 py-2 sm:h-15 hover:bg-surface-gray-2"
|
||||
>
|
||||
<div class="flex items-center w-full space-x-3">
|
||||
<Avatar
|
||||
:image="participant.user_image"
|
||||
class="size-8 rounded-full object-contain"
|
||||
:label="participant.full_name"
|
||||
size="2xl"
|
||||
/>
|
||||
<UserAvatar :user="participant" size="2xl" />
|
||||
|
||||
<div class="flex flex-col md:flex-row w-full">
|
||||
<div class="flex-1">
|
||||
<div class="text-base font-medium text-ink-gray-8">
|
||||
@@ -115,6 +111,7 @@ import { computed, inject, onMounted, ref } from 'vue'
|
||||
import { GraduationCap } from 'lucide-vue-next'
|
||||
import { sessionStore } from '../stores/session'
|
||||
import EmptyState from '@/components/EmptyState.vue'
|
||||
import UserAvatar from '@/components/UserAvatar.vue'
|
||||
|
||||
const currentCategory = ref('')
|
||||
const filters = ref({})
|
||||
@@ -156,6 +153,7 @@ const categories = createListResource({
|
||||
})
|
||||
|
||||
const updateParticipants = () => {
|
||||
console.log('updating participants')
|
||||
updateFilters()
|
||||
getMemberCount()
|
||||
setQueryParams()
|
||||
@@ -167,6 +165,7 @@ const updateParticipants = () => {
|
||||
}
|
||||
|
||||
const updateFilters = () => {
|
||||
console.log(currentCategory.value)
|
||||
if (currentCategory.value) {
|
||||
filters.value.category = currentCategory.value
|
||||
} else {
|
||||
|
||||
@@ -342,6 +342,7 @@ import {
|
||||
TabButtons,
|
||||
Tooltip,
|
||||
usePageMeta,
|
||||
toast,
|
||||
} from 'frappe-ui'
|
||||
import {
|
||||
computed,
|
||||
@@ -798,6 +799,10 @@ const enrollStudent = () => {
|
||||
onSuccess() {
|
||||
window.location.reload()
|
||||
},
|
||||
onError(err) {
|
||||
toast.error(__(err.messages?.[0] || err))
|
||||
console.error(err)
|
||||
},
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -50,24 +50,51 @@
|
||||
<div class="mx-auto -mt-10 md:-mt-4 max-w-4xl translate-x-0 px-5">
|
||||
<div class="flex flex-col md:flex-row items-center">
|
||||
<div>
|
||||
<img
|
||||
v-if="profile.data.user_image"
|
||||
:src="profile.data.user_image"
|
||||
class="object-cover h-[100px] w-[100px] rounded-full border-4 border-white object-cover"
|
||||
/>
|
||||
<UserAvatar
|
||||
v-else
|
||||
:user="profile.data"
|
||||
class="object-cover h-[100px] w-[100px] rounded-full border-4 border-white object-cover"
|
||||
/>
|
||||
<div class="relative">
|
||||
<img
|
||||
v-if="profile.data.user_image"
|
||||
:src="profile.data.user_image"
|
||||
class="object-cover h-[100px] w-[100px] rounded-full border-4 border-white object-cover"
|
||||
/>
|
||||
<Tooltip
|
||||
v-if="profile.data.looking_for_job"
|
||||
:text="__('Open to Opportunities')"
|
||||
placement="right"
|
||||
>
|
||||
<div
|
||||
class="absolute bottom-3 right-1 p-0.5 bg-surface-white rounded-full"
|
||||
>
|
||||
<div class="rounded-full bg-surface-green-3 w-fit">
|
||||
<BadgeCheckIcon class="text-ink-white size-5" />
|
||||
</div>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ml-6">
|
||||
<h2 class="mt-2 text-3xl font-semibold text-ink-gray-9">
|
||||
<div class="ml-6 mt-5">
|
||||
<h2 class="text-3xl font-semibold text-ink-gray-9">
|
||||
{{ profile.data.full_name }}
|
||||
</h2>
|
||||
<div class="mt-2 text-base text-ink-gray-7">
|
||||
<div class="text-base text-ink-gray-7 mt-1">
|
||||
{{ profile.data.headline }}
|
||||
</div>
|
||||
<div class="flex items-center space-x-4 mt-2">
|
||||
<Twitter
|
||||
v-if="profile.data.twitter"
|
||||
class="size-4 text-ink-gray-5 cursor-pointer"
|
||||
@click="navigateTo(profile.data.twitter)"
|
||||
/>
|
||||
<Linkedin
|
||||
v-if="profile.data.linkedin"
|
||||
class="size-4 text-ink-gray-5 cursor-pointer"
|
||||
@click="navigateTo(profile.data.linkedin)"
|
||||
/>
|
||||
<Github
|
||||
v-if="profile.data.github"
|
||||
class="size-4 text-ink-gray-5 cursor-pointer"
|
||||
@click="navigateTo(profile.data.github)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
v-if="isSessionUser() && !readOnlyMode"
|
||||
@@ -81,7 +108,7 @@
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div class="mb-4 mt-6">
|
||||
<div class="mb-4 mt-10">
|
||||
<TabButtons
|
||||
class="inline-block"
|
||||
:buttons="getTabButtons()"
|
||||
@@ -104,11 +131,19 @@ import {
|
||||
call,
|
||||
createResource,
|
||||
TabButtons,
|
||||
Tooltip,
|
||||
usePageMeta,
|
||||
} from 'frappe-ui'
|
||||
import { computed, inject, watch, ref, onMounted, watchEffect } from 'vue'
|
||||
import { sessionStore } from '@/stores/session'
|
||||
import { Edit, RefreshCcw } from 'lucide-vue-next'
|
||||
import {
|
||||
BadgeCheckIcon,
|
||||
Edit,
|
||||
Github,
|
||||
Linkedin,
|
||||
RefreshCcw,
|
||||
Twitter,
|
||||
} from 'lucide-vue-next'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { convertToTitleCase } from '@/utils'
|
||||
import UserAvatar from '@/components/UserAvatar.vue'
|
||||
@@ -229,6 +264,10 @@ const reloadUser = () => {
|
||||
})
|
||||
}
|
||||
|
||||
const navigateTo = (url) => {
|
||||
window.open(url, '_blank')
|
||||
}
|
||||
|
||||
const breadcrumbs = computed(() => {
|
||||
let crumbs = [
|
||||
{
|
||||
|
||||
@@ -56,11 +56,13 @@
|
||||
</template>
|
||||
<template #body-main>
|
||||
<div class="w-[250px] text-base">
|
||||
<img
|
||||
:src="badge.badge_image"
|
||||
:alt="badge.badge"
|
||||
class="bg-surface-gray-2 rounded-t-md h-[200px] mx-auto"
|
||||
/>
|
||||
<div class="bg-surface-gray-2 rounded-t-md py-5">
|
||||
<img
|
||||
:src="badge.badge_image"
|
||||
:alt="badge.badge"
|
||||
class="h-[200px] mx-auto"
|
||||
/>
|
||||
</div>
|
||||
<div class="p-5">
|
||||
<div class="text-2xl font-semibold mb-2">
|
||||
{{ badge.badge }}
|
||||
|
||||
Reference in New Issue
Block a user