Skip to content

Commit

Permalink
feat: view candidate cv (#1281)
Browse files Browse the repository at this point in the history
  • Loading branch information
djaiss committed Aug 30, 2021
1 parent 672bf12 commit a2f2f8c
Show file tree
Hide file tree
Showing 9 changed files with 355 additions and 88 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
class DashboardHRCandidateController extends Controller
{
/**
* Show the detail of a job opening.
* Show the detail of a candidate.
*
* @param Request $request
* @param integer $companyId
Expand Down Expand Up @@ -84,7 +84,58 @@ public function show(Request $request, int $companyId, int $jobOpeningId, int $c
}

/**
* Show the detail of a job opening.
* Show the cv of a candidate.
*
* @param Request $request
* @param integer $companyId
* @param integer $jobOpeningId
* @param integer $candidateId
* @return mixed
*/
public function showCV(Request $request, int $companyId, int $jobOpeningId, int $candidateId): mixed
{
$company = InstanceHelper::getLoggedCompany();
$loggedEmployee = InstanceHelper::getLoggedEmployee();

// is this person HR?
if ($loggedEmployee->permission_level > config('officelife.permission_level.hr')) {
return redirect('home');
}

try {
$jobOpening = JobOpening::where('company_id', $company->id)
->with('team')
->with('position')
->with('sponsors')
->findOrFail($jobOpeningId);
} catch (ModelNotFoundException $e) {
return redirect('home');
}

try {
$candidate = Candidate::where('company_id', $company->id)
->findOrFail($candidateId);
} catch (ModelNotFoundException $e) {
return redirect('home');
}

$jobOpeningInfo = DashboardHRCandidatesViewHelper::jobOpening($company, $jobOpening);
$candidateInfo = DashboardHRCandidatesViewHelper::candidate($company, $jobOpening, $candidate);
$otherJobOpenings = DashboardHRCandidatesViewHelper::otherJobOpenings($company, $candidate, $jobOpening);
$documents = DashboardHRCandidatesViewHelper::documents($candidate);

return Inertia::render('Dashboard/HR/JobOpenings/Candidates/CV', [
'notifications' => NotificationHelper::getNotifications($loggedEmployee),
'jobOpening' => $jobOpeningInfo,
'candidate' => $candidateInfo,
'otherJobOpenings' => $otherJobOpenings,
'documents' => $documents,
'tab' => 'cv',
]);
}

/**
* Show the detail of a candidate.
*
* @param Request $request
* @param integer $companyId
Expand Down Expand Up @@ -118,7 +169,7 @@ public function store(Request $request, int $companyId, int $jobOpeningId, int $
}

/**
* Show the detail of a job opening at a given stage.
* Show the detail of a candidate at a given stage.
*
* @param Request $request
* @param integer $companyId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace App\Http\ViewHelpers\Dashboard\HR;

use App\Helpers\DateHelper;
use App\Helpers\FileHelper;
use App\Helpers\ImageHelper;
use App\Helpers\StringHelper;
use App\Models\Company\Company;
Expand Down Expand Up @@ -98,6 +99,16 @@ public static function candidate(Company $company, JobOpening $jobOpening, Candi
'jobOpening' => $jobOpening,
'candidate' => $candidate,
]),
'url_stages' => route('dashboard.hr.candidates.show', [
'company' => $company,
'jobOpening' => $jobOpening,
'candidate' => $candidate,
]),
'url_cv' => route('dashboard.hr.candidates.cv', [
'company' => $company,
'jobOpening' => $jobOpening,
'candidate' => $candidate,
]),
];
}

Expand Down Expand Up @@ -130,6 +141,10 @@ public static function otherJobOpenings(Company $company, Candidate $candidate,
'reference_number' => $candidate->jobOpening->reference_number,
'active' => $candidate->jobOpening->active,
'fulfilled' => $candidate->jobOpening->fulfilled,
'url' => route('dashboard.hr.openings.show', [
'company' => $company,
'jobOpening' => $candidate->jobOpening,
]),
]);
}

Expand Down Expand Up @@ -273,6 +288,24 @@ public static function potentialParticipants(Company $company, CandidateStage $s
return $potentialEmployeesCollection;
}

/**
* Get the information about the notes in a stage.
*
* @param Candidate $candidate
* @return Collection|null
*/
public static function documents(Candidate $candidate): ?Collection
{
return $candidate->files->map(function ($file) {
return [
'id' => $file->id,
'size' => FileHelper::getSize($file->size),
'filename' => $file->name,
'download_url' => $file->cdn_url,
];
});
}

/**
* Get the information about the notes in a stage.
*
Expand Down
102 changes: 102 additions & 0 deletions resources/js/Pages/Dashboard/HR/JobOpenings/Candidates/CV.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<style lang="scss" scoped>
.document-list {
li:first-child:hover {
border-top-left-radius: 10px;
border-top-right-radius: 10px;
}
li:last-child {
border-bottom: 0;
&:hover {
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
}
}
}
</style>

<template>
<layout :notifications="notifications">
<div class="ph2 ph5-ns">
<breadcrumb
:root-url="'/' + $page.props.auth.company.id + '/dashboard'"
:root="$t('app.breadcrumb_dashboard')"
:previous-url="'/' + $page.props.auth.company.id + '/dashboard/hr/job-openings/' + jobOpening.id"
:previous="$t('app.breadcrumb_dashboard_job_opening_detail')"
>
{{ $t('app.breadcrumb_dashboard_job_opening_candidate') }}
</breadcrumb>

<!-- BODY -->
<div class="mw8 center br3 mb5 relative z-1">
<!-- information about the candidate -->
<information :candidate="candidate"
:tab="tab"
:job-opening="jobOpening"
:other-job-openings="otherJobOpenings"
/>

<!-- central part -->
<div class="center">
<div class="bg-white box">
<ul class="list ma0 pl0 document-list">
<li v-for="document in documents" :key="document.id" class="bb bb-gray bb-gray-hover pa3">
<a :href="document.download_url" :download="document.download_url">{{ document.filename }}</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</layout>
</template>

<script>
import Layout from '@/Shared/Layout';
import Breadcrumb from '@/Shared/Layout/Breadcrumb';
import Information from '@/Pages/Dashboard/HR/JobOpenings/Candidates/Partials/Information';
export default {
components: {
Layout,
Breadcrumb,
Information,
},
props: {
notifications: {
type: Array,
default: null,
},
jobOpening: {
type: Object,
default: null,
},
candidate: {
type: Object,
default: null,
},
otherJobOpenings: {
type: Object,
default: null,
},
documents: {
type: Object,
default: null,
},
tab: {
type: String,
default: null,
},
},
mounted() {
if (localStorage.success) {
this.flash(localStorage.success, 'success');
localStorage.removeItem('success');
}
},
};
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<style lang="scss" scoped>
.box-bottom {
border-bottom-left-radius: 11px;
border-bottom-right-radius: 11px;
}
.warning {
box-shadow: 0 0 0 1px #e3e8ee;
background-color: #f7fafc;
}
.badge {
padding: 1px 6px;
border-radius: 4px;
&.active {
background-color: #cbf4c9;
}
&.closed {
background-color: #e3e8ee;
}
}
</style>

<template>
<div>
<div class="box bg-white mb4">
<div class="pa3 flex justify-between items-center bb bb-gray">
<!-- name + summary -->
<div>
<h2 class="mt0 mb2 relative fw4">
{{ candidate.name }}
</h2>

<ul class="list pa0 ma0 f7 gray">
<li class="di mr3">
{{ $t('dashboard.job_opening_show_candidate_applied', { date: candidate.created_at }) }}
</li>
<li class="di mr3">{{ candidate.email }}</li>
</ul>
</div>

<inertia-link v-if="! jobOpening.fulfilled" :href="candidate.url_hire" class="btn">{{ $t('dashboard.job_opening_show_candidate_hire') }}</inertia-link>
</div>

<div class="bg-gray pa3 f7 box-bottom">
<p class="ma0">{{ $t('dashboard.job_opening_show_candidate_job_opening') }} <inertia-link :href="jobOpening.url">{{ jobOpening.title }}</inertia-link></p>
</div>
</div>

<!-- has the candidate applied to other jobs in the company -->
<div v-if="otherJobOpenings.length > 0" class="warning pa3 br3 mb4">
<p class="ma0 mb3 f6"><span class="mr1">⚠️</span> {{ $t('dashboard.job_opening_show_other_jobs', { count: otherJobOpenings.length }) }}</p>
<ul class="list ma0 pl0">
<li v-for="job in otherJobOpenings" :key="job.id" class="mb2 mr2">
<inertia-link :href="job.url" class="mr2">{{ job.title }}</inertia-link>
<span v-if="job.active" class="badge f7 active">{{ $t('dashboard.job_opening_show_other_jobs_active') }}</span>
<span v-else class="badge f7 closed">{{ $t('dashboard.job_opening_show_other_jobs_closed') }}</span>
</li>
</ul>
</div>

<!-- tab -->
<div class="center br3 mb5 tc">
<div class="cf dib btn-group">
<inertia-link :href="candidate.url_cv" :class="{ 'selected': tab == 'cv' }" class="f6 fl ph3 pv2 dib pointer no-underline">
{{ $t('dashboard.job_opening_show_candidate_tab_cv') }}
</inertia-link>
<inertia-link :href="candidate.url_stages" :class="{ 'selected': tab == 'recruiting' }" class="f6 fl ph3 pv2 dib pointer no-underline">
{{ $t('dashboard.job_opening_show_candidate_tab_recruiting') }}
</inertia-link>
</div>
</div>
</div>
</template>

<script>
export default {
props: {
jobOpening: {
type: Object,
default: null,
},
candidate: {
type: Object,
default: null,
},
otherJobOpenings: {
type: Object,
default: null,
},
tab: {
type: String,
default: null,
},
},
};
</script>

0 comments on commit a2f2f8c

Please sign in to comment.