feat: open to opportunities

This commit is contained in:
Jannat Patel
2025-12-16 20:27:00 +05:30
parent 94a3afdc9b
commit b3119f5295
11 changed files with 544 additions and 251 deletions

View File

@@ -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 })
}
}

View File

@@ -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>

View File

@@ -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 {

View File

@@ -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)
},
}
)
}

View File

@@ -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 = [
{

View File

@@ -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 }}