<script setup lang="ts">
import { useWindowScroll } from '@vueuse/core'
import { computed, onMounted, ref } from 'vue'
import { Form, Field } from 'vee-validate'
import { useRoute, useRouter } from 'vue-router'
const route = useRoute()
const router = useRouter()
import { useJobOpening } from '/@src/stores/jobOpening'
import { useJobApplication } from '/@src/stores/jobApplication'
import { useI18n } from 'vue-i18n'
import * as yup from 'yup'
import axios from 'axios'
import { Notyf } from 'notyf'
const companySize = ref('')
const businessType = ref('')
const productToDemo = ref('')
const date = ref(new Date())
const { y } = useWindowScroll()
const notyf = new Notyf()
const { t } = useI18n()
const jobApplication = useJobApplication()
const jobOpening = useJobOpening()
let upbutton = ref(-1)
const isStuck = computed(() => {
return y.value > 30
})
// Define a validation schema
const schema = yup.object({
email: yup.string().required(t('jobapplication.common.required')),
name: yup.string().required(t('jobapplication.common.required')),
})
let formAnswers = ref([])
const videoLinks = ref([])
let old_file: any[] = []
let progress = ref(0)
let recordedBlob = {} as any
let config = {
headers: { 'content-type': 'multipart/form-data' },
}
const calculateProgress = () => {
let fa = 0
jobOpening.data.question.forEach((element: any, index: number) => {
if (
formAnswers.value[index] &&
formAnswers.value[index] != null &&
formAnswers.value[index] != ''
) {
fa = fa + 1
}
})
progress.value = Math.round(
(100 * (fa + videoLinks.value.length)) /
(jobOpening.data.question.length + jobOpening.data.video_question.length)
)
}
const calculateTextQuestionProgress = () => {
let fa = 0
jobOpening.data.question.forEach((element: any, index: number) => {
if (
formAnswers.value[index] &&
formAnswers.value[index] != null &&
formAnswers.value[index] != ''
) {
fa = fa + 1
}
})
return fa
}
const updateInterview = async (values: typeof schema) => {
if (formAnswers.value.length == 0 && jobOpening.data.question.length > 0) {
return notyf.error('You must answer the questions!')
} else if (
jobApplication.data.video_answers.length == 0 &&
jobOpening.data.video_question.length > 0
) {
return notyf.error('You must attempt the video interview!')
}
jobApplication.data.answers = []
jobOpening.data.question.forEach((element: any, index: number) => {
jobApplication.data.answers.push({
job_opening_id: element.job_opening_id,
job_application_id: Number(route.query.job),
job_opening_question_id: element.id,
question: element.question,
answer: formAnswers.value[index],
})
})
jobApplication.data.user_id = 1
jobApplication.data.job_opening_id = jobOpening.data.id
jobApplication.save().then((data: any) => {
if (data.data.status == true) {
jobApplication.pc.process_complete = 'yes'
notyf.success('Job Application submitted successfully!')
router.push('/job/' + jobOpening.data.id)
} else {
notyf.error('Something Went Wrong!')
}
})
}
const uploadTheVideo = async (item: any, index: any) => {
let formData = new FormData()
if (old_file.length > 0) {
let findex = -1
for (let i = 0; i < old_file.length; i++) {
if (old_file[i] == index) {
findex = index
break
}
}
if (findex > -1) {
formData.append(
'old_file',
jobApplication.data.video_answers[findex].video
)
}
}
formData.append('file', recordedBlob)
formData.append('extension', 'mp4')
let res: any = await axios.post(
'https://api.tenrol.com/job-application-question/v1/video-upload',
formData,
config
)
if (res.status == 200) {
upbutton.value = -1
calculateProgress()
jobApplication.data.video_answers[index] = {
job_opening_id: item.job_opening_id,
job_application_id: Number(route.query.job),
job_opening_video_question_id: item.id,
question: item.question,
length: item.length,
video: res.data.data,
}
old_file.push(index)
notyf.success(res.data.msg)
}
}
function Record(length: string, idx: number, item: any) {
var seconds = 0
var flag = false
var flag2 = false
function incrementSeconds() {
seconds += 1
if (seconds == Number(length)) {
flag = true
if (!flag2) {
stopButton.click()
}
}
}
var cancel = setInterval(incrementSeconds, 1000)
jobOpening.start_text[idx] = 'Stop'
let iddx = idx + 1
let preview: any = document.getElementById('preview' + iddx)
let stopButton: any = document.getElementById('stopButton' + iddx)
let recordingTimeMS = Number(length) * 1000
let rec = {} as any
let recorded = {} as any
function startRecording(stream: any, lengthInMS: any) {
let recorder = new MediaRecorder(stream)
let data: any = []
recorder.ondataavailable = (event) => data.push(event.data)
recorder.start()
let stopped = new Promise((resolve, reject) => {
recorder.onstop = resolve
recorder.onerror = (event: any) => reject(event.name)
})
rec = recorder
return Promise.all([stopped, recorded]).then(() => data)
}
function stop_recorder() {
recorded = () => rec.state == 'recording' && rec.stop()
}
function stop(stream: any) {
stream.getTracks().forEach((track: any) => track.stop())
}
//Start Record----------
navigator.mediaDevices
.getUserMedia({
video: true,
audio: true,
})
.then((stream: any) => {
preview.srcObject = stream
preview.captureStream = preview.captureStream || preview.mozCaptureStream
return new Promise((resolve) => (preview.onplaying = resolve))
})
.then(() => startRecording(preview.captureStream(), recordingTimeMS))
.then((recordedChunks) => {
recordedBlob = new Blob(recordedChunks, {
type: 'video/webm',
})
if (!flag) {
flag2 = true
stop(preview.srcObject)
stop_recorder()
}
uploadTheVideo(item, idx)
jobOpening.start_text[idx] = 'Retake'
videoLinks.value[idx] = URL.createObjectURL(recordedBlob)
})
.catch(log)
function log(msg: any) {
alert(msg)
return
}
stopButton.addEventListener(
'click',
function () {
upbutton.value = idx
stop(preview.srcObject)
stop_recorder()
},
false
)
}
onMounted(() => {
jobOpening.getCurrentData(
route.fullPath.split('/job/question_answer?job=')[1]
)
if (jobApplication.is_basic_info == true) {
jobApplication.data.user_id = jobApplication.basic_info.user_id
jobApplication.data.email = jobApplication.basic_info.email
jobApplication.data.job_opening_id =
jobApplication.basic_info.job_opening_id
jobApplication.data.status = jobApplication.basic_info.status
jobApplication.data.name = jobApplication.basic_info.name
jobApplication.data.phone = jobApplication.basic_info.phone
jobApplication.data.cv = jobApplication.basic_info.cv
} else if (jobApplication.data == undefined) {
notyf.error('Fill the basic info first!')
router.push('/job/' + route.fullPath.split('/job/question_answer?job=')[1])
} else if (jobApplication.data.email === '') {
notyf.error('Fill the basic info first!')
router.push('/job/' + route.fullPath.split('/job/question_answer?job=')[1])
}
})
</script>
<template>
<!-- Content Wrapper -->
<Form
:validation-schema="schema"
class="form-layout"
:initial-values="jobOpening.isEdit ? jobOpening.data : {}"
@submit="prevent"
>
<div class="form-outer">
<div :class="[isStuck && 'is-stuck']" class="form-header stuck-header">
<div class="form-header-inner">
<div class="left">
<h3>
Progress {{ progress }}%
<!-- <div class="progress-bar">
<VProgress size="tiny" :value="progress" />
</div> -->
</h3>
</div>
<div class="right">
<VButtons v-if="jobOpening.showQIndex > -1">
<VButton disabled> Previous </VButton>
<VButton
:disabled="
calculateTextQuestionProgress() <
jobOpening.data.question.length
"
color="primary"
@click="jobOpening.changeIndexes"
>
Next Step
</VButton>
</VButtons>
<VButtons v-if="jobOpening.showVideoIndex > -1">
<VButton
v-if="
jobOpening.showVideoIndex == 0 &&
jobOpening.data.question.length > 0
"
@click="jobOpening.prevStep"
>
Previous
</VButton>
<VButton
v-if="jobOpening.showVideoIndex > 0"
@click="jobOpening.decrease"
>
Previous
</VButton>
<VButton
color="primary"
v-if="
jobOpening.showVideoIndex <
jobOpening.data.video_question.length - 1
"
@click="jobOpening.increase"
:disabled="!videoLinks[jobOpening.showVideoIndex]"
>
Next Step {{ videoLinks.length }} - ({{
jobOpening.showVideoIndex
}})
</VButton>
<VButton
v-if="
progress == 100 &&
((jobOpening.data.question.length == 0 &&
jobOpening.showVideoIndex ==
jobOpening.data.video_question.length - 1) ||
(jobOpening.data.video_question.length == 0 &&
jobOpening.showQIndex ==
jobOpening.data.question.length - 1) ||
(jobOpening.data.question.length != 0 &&
jobOpening.data.video_question.length - 1 ==
jobOpening.showVideoIndex))
"
color="primary"
@click="updateInterview"
>
Complete Interview
</VButton>
<VButton
v-if="
progress < 100 &&
jobOpening.showVideoIndex ==
jobOpening.data.video_question.length - 1
"
color="primary"
@click="updateInterview"
disabled
>
Complete Interview
</VButton>
</VButtons>
</div>
</div>
</div>
<div class="progress-bar">
<VProgress size="tiny" :value="progress" />
</div>
<div class="form-body">
<!-- Question text -->
<div
v-if="jobOpening.showQIndex > -1"
class="columns wrapper-outer m-h-420 form-fieldset"
>
<div class="column is-12 wrapper-inner">
<div class="action-box">
<div>
<div
v-for="(item, index) in jobOpening.data.question"
:key="index"
>
<div class="box-content">
<VField v-if="item.type == 'Text'">
<div class="fieldset-heading">
<h4>
<VTag
color="primary"
:label="'Question ' + (index + 1)"
tiny
/>
</h4>
<h4>
{{ item.question }}
</h4>
<p>
Please answer the question by entering the text in the
field below
</p>
</div>
<VControl>
<textarea
v-model="formAnswers[index]"
class="textarea"
rows="4"
@keyup="calculateProgress"
></textarea>
</VControl>
</VField>
<VField v-if="item.type == 'Number'">
<div class="fieldset-heading">
<h4>
<VTag
color="primary"
:label="'Question ' + (index + 1)"
tiny
/>
</h4>
<h4>
{{ item.question }}
</h4>
<p>
This will help you to add new jobs and publish the
share link
</p>
</div>
<VControl>
<input
v-model="formAnswers[index]"
class="input"
type="number"
@keyup="calculateProgress"
/>
</VControl>
</VField>
<VField v-if="item.type == 'Date'">
<div class="fieldset-heading">
<h4>
<VTag
color="primary"
:label="'Question ' + (index + 1)"
tiny
/>
<h4>
{{ item.question }}
</h4>
</h4>
<p>Select the date below to answer</p>
</div>
<VControl>
<input
v-model="formAnswers[index]"
class="input"
type="date"
@change="calculateProgress"
/>
</VControl>
</VField>
<VField v-if="item.type == 'Yes/No'">
<div class="fieldset-heading">
<h4>
<VTag
color="primary"
:label="'Question ' + (index + 1)"
tiny
/>
<h4>
{{ item.question }}
</h4>
</h4>
<p>Please select the correct answer (Yes or No)</p>
</div>
<VControl>
<VRadio
v-model="formAnswers[index]"
value="Yes"
label="Yes"
name="outlined_radio"
color="primary"
@change="calculateProgress"
/>
<VRadio
v-model="formAnswers[index]"
value="No"
label="No"
name="outlined_radio"
color="primary"
@change="calculateProgress"
/>
</VControl>
</VField>
</div>
<hr
v-if="index != jobOpening.data.question.length - 1"
class="m-t-35 m-b-35"
/>
</div>
</div>
</div>
</div>
</div>
<!-- Question Video -->
<div
v-if="jobOpening.data.video_question.length > 0"
class="promotion-page-wrapper form-fieldset"
>
<div
v-for="(item, index) in jobOpening.data.video_question"
:key="item.id"
>
<div v-if="jobOpening.showVideoIndex == index" class="columns">
<div class="column is-5 wrapper-inner">
<div class="fieldset-heading">
<h4>
<VTag
color="primary"
:label="
'Question ' +
(index + 1) +
'/' +
jobOpening.data.video_question.length
"
tiny
/>
</h4>
<h4>{{ item.question }}</h4>
<p>
{{ item.description }}
</p>
</div>
</div>
<div class="column is-7 side-wrapper">
<div class="side-inner">
<div>
<div id="footage" class="box-video">
<div class="fieldset-heading fs-inf">
<h4>
<VTag
v-tooltip.light="'Time to answer the question'"
color="danger"
:label="
Number(item.length) > 59
? ' ' +
Math.floor(Number(item.length) / 60) +
' Min' +
' ' +
Math.round(Number(item.length) % 60) +
' Sec'
: ' ' + item.length + ' Sec'
"
tiny
danger
/>
<!-- Microphone -->
<VTag
v-if="true"
label="Microphone ok"
v-tooltip.light="
'Microphone was detected on the device'
"
/>
<VTag
v-else-if="false"
label="No Microphone"
v-tooltip.light="
'Microphone permission was not allowed on the device'
"
/>
<VTag
v-else
color="warning"
label="No Microphone"
v-tooltip.light="
'Could not detect any microphone on the device'
"
/>
<!-- Camera -->
<VTag
v-if="true"
label="Camera ok"
v-tooltip.light="
'Microphone was detected on the device'
"
/>
<VTag
v-else-if="false"
label="No Microphone"
v-tooltip.light="
'Camera permission was not allowed on the device'
"
/>
<VTag
v-else
color="warning"
label="No Camera"
v-tooltip.light="
'Could not detect any Camera on the device'
"
/>
</h4>
</div>
<div
v-if="upbutton == jobOpening.showVideoIndex"
class="videoheight"
style=""
></div>
<video
v-else
:id="'preview' + (index + 1)"
width="300"
height="250"
autoplay=""
muted=""
>
<source :src="videoLinks[index]" />
</video>
<div class="m-b-20">
<VButtons>
<VButton
v-if="jobOpening.start_text[index] == 'Start'"
color="primary"
outlined
class="fw-btn"
icon="feather:video"
@click="Record(item.length, index, item)"
>
<!-- {{ jobOpening.start_text[index] }} -->
Start recording
</VButton>
<VButton
v-if="jobOpening.start_text[index] == 'Retake'"
color="primary"
outlined
class="fw-btn"
icon="feather:refresh-cw"
@click="Record(item.length, index, item)"
>
<!-- {{ jobOpening.start_text[index] }} -->
Retake Video
</VButton>
</VButtons>
<div :id="'stopButton' + (index + 1)">
<VButton
v-if="jobOpening.start_text[index] == 'Stop'"
color="primary"
outlined
class="fw-btn"
icon="feather:stop-circle"
>Stop recording
</VButton>
</div>
<button
class="fw-btn"
:id="'stopButton' + (index + 1)"
style="display: none"
>
Stop
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</Form>
<div class="power-up-2">
<div class="power-up-1">
<div class="power">
Powered by
<a href="/" target="_blank"
><span class="color_of_tenrol">Tenrol </span></a
>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
@import '../../../../scss/abstracts/_mixins.scss';
@import '../../../../scss/pages/generic/_forms.scss';
@import '../../../../scss/pages/generic/_forms-stepper.scss';
.form-body {
min-height: 720px;
padding-top: 60px !important;
}
.columns {
margin: 0px !important;
}
.is-* {
padding-top: 0;
}
.fs-inf {
position: absolute;
padding-left: 3px;
z-index: 999;
}
video {
width: 100%;
border-radius: 0.25rem;
background-color: #000000;
background-image: linear-gradient(360deg, #000000 0%, #434343 74%);
}
.fieldset-heading {
margin-bottom: 0px !important;
p {
margin-bottom: 5px;
}
}
.form-fieldset .columns .column {
padding-top: 0rem !important;
padding-bottom: 0rem !important;
}
.wrapper-inner {
padding-top: 0rem !important;
padding-bottom: 0rem !important;
}
.buttons:not(:last-child) {
margin-bottom: 0rem !important;
}
.tag {
// background: #41b983 !important;
padding: 4px 6px !important;
line-height: 9px !important;
height: 17px !important;
margin: 0 4px 0px 0px !important;
border-radius: 3px !important;
// color: white !important;
}
.view-wrapper .is-stuck {
position: fixed;
top: 0;
left: 0;
margin-left: 0px;
width: 100% !important;
z-index: 14;
}
.devider {
padding-bottom: 20px;
background: #f0f0f0;
}
.stepper-form {
margin-bottom: 0px !important;
.form-sections {
padding-right: 0px !important;
}
.output {
height: auto !important;
padding-top: 16px !important;
}
}
// Custom override
.color_of_tenrol {
color: rgb(114, 192, 109);
font-size: 2rem;
}
.power {
font-size: 1.5rem;
margin-right: 0.75rem;
color: rgb(95, 104, 117);
line-height: 1.78;
}
.power-up-1 {
display: flex;
-webkit-box-align: center;
align-items: center;
-webkit-box-pack: center;
justify-content: center;
}
.power-up-2 {
padding-top: 40px;
position: static;
width: 100%;
bottom: 0px;
left: 0px;
text-align: center;
box-sizing: border-box;
}
@media only screen and (min-width: 600px) {
.m-h-420 {
min-height: 420px;
}
}
.grid-radio {
display: grid;
}
@media only screen and (min-width: 600px) {
.left {
flex-grow: 2;
max-width: 50%;
.progress-stats {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 8px;
span {
display: block;
&:first-child {
font-family: var(--font-alt);
font-size: 0.9rem;
font-weight: 600;
color: var(--dark-text);
}
&:nth-child(2) {
font-size: 0.9rem;
color: var(--light-text);
}
}
}
.progress {
margin-bottom: 0;
}
}
}
.left {
flex-grow: 2;
width: 100%;
.progress-stats {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 8px;
span {
display: block;
&:first-child {
font-family: var(--font-alt);
font-size: 0.9rem;
font-weight: 600;
color: var(--dark-text);
}
&:nth-child(2) {
font-size: 0.9rem;
color: var(--light-text);
}
}
}
.progress {
margin-bottom: 0;
}
}
.review-progress {
margin-top: 15px;
.progress-stats {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 8px;
span {
display: block;
&:first-child {
font-family: var(--font-alt);
font-size: 0.9rem;
font-weight: 600;
color: var(--dark-text);
}
&:nth-child(2) {
font-size: 0.9rem;
color: var(--light-text);
}
}
}
.progress {
margin-bottom: 0;
}
}
hr {
margin: 10px;
}
.item-row {
background: whitesmoke;
padding: 5px;
margin: 0 0 50px 0 !important;
border-radius: 0.25rem;
border: 1px solid #dbdbdb;
.question {
margin-bottom: 20px;
padding: 15px;
border-radius: 0.25rem;
background: #e7e7e7;
padding: 15px;
}
.answer {
padding: 25px;
border-radius: 0.25rem;
background: white;
border: 1px solid #dbdbdb;
}
}
.application-details {
text-align: left !important;
}
.company-dashboard {
video {
width: 100%;
border-radius: 0.25rem;
}
.company-header {
display: flex;
padding: 20px;
background: var(--white);
border: 1px solid var(--fade-grey-dark-3);
border-radius: var(--radius-large);
margin-bottom: 1.5rem;
.header-item {
width: 25%;
border-right: 1px solid var(--fade-grey-dark-3);
&:last-child {
border-right: none;
}
.item-inner {
text-align: center;
.lnil,
.lnir {
font-size: 1.8rem;
margin-bottom: 6px;
color: var(--primary);
}
span {
display: block;
font-family: var(--font);
font-weight: 600;
font-size: 1.6rem;
color: var(--dark-text);
}
p {
font-family: var(--font-alt);
font-size: 0.95rem;
}
}
}
}
.widget {
height: 100%;
}
.dashboard-card {
@include vuero-s-card();
height: 100%;
&.is-company {
text-align: center;
padding: 30px;
.v-avatar {
display: block;
margin: 0 auto 10px auto;
.button {
position: absolute;
bottom: 0;
right: 0;
max-width: 35px;
}
}
> h3 {
color: var(--dark-text);
font-family: var(--font-alt);
font-size: 1.2rem;
font-weight: 600;
}
> p {
font-size: 0.9rem;
}
.description {
padding: 10px 0 0 0;
}
.company-stats {
display: flex;
padding-top: 20px;
margin-top: 20px;
border-top: 1px solid var(--fade-grey-dark-3);
.company-stat {
width: 33.3%;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
span {
display: block;
font-family: var(--font);
&:first-child {
text-transform: uppercase;
font-family: var(--font-alt);
font-size: 0.75rem;
color: var(--light-text);
}
&:nth-child(2) {
color: var(--dark-text);
font-size: 1.4rem;
font-weight: 600;
}
}
}
}
}
&.is-base-chart {
padding: 0;
display: flex;
flex-direction: column;
.content-box {
padding: 30px;
.revenue-stats {
display: flex;
padding-bottom: 20px;
border-bottom: 1px solid var(--fade-grey-dark-3);
.revenue-stat {
margin-right: 30px;
font-family: var(--font);
span {
display: block;
&:first-child {
text-transform: uppercase;
font-family: var(--font-alt);
font-size: 0.75rem;
color: var(--light-text);
}
&:nth-child(2) {
color: var(--dark-text);
font-size: 1.6rem;
font-weight: 600;
}
&.current {
color: var(--primary);
}
}
}
}
}
.chart-container {
margin-top: auto;
}
}
&.is-tickets {
padding: 30px;
.ticket-list {
padding: 10px 0;
align-content: center;
.media-flex {
+ .media-flex {
margin-top: 20px;
padding-top: 20px;
border-top: 1px solid var(--fade-grey-dark-3);
}
.flex-meta {
span {
&:nth-child(2) {
font-size: 1rem;
margin: 4px 0;
color: var(--light-text-dark-20);
max-width: 430px;
}
&:nth-child(3) {
font-size: 0.9rem;
color: var(--light-text);
}
}
}
}
}
}
.card-head {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 20px;
h3 {
font-family: var(--font-alt);
font-size: 1rem;
font-weight: 600;
color: var(--dark-text);
}
}
}
.table-wrapper {
min-height: 0;
}
.dataTable-wrapper {
.dataTable-top {
padding: 0 !important;
margin: 0 !important;
}
}
}
.is-dark {
.company-dashboard {
.dashboard-card {
@include vuero-card--dark();
}
}
.review-progress {
.progress-stats {
span {
&:first-child {
color: var(--dark-dark-text);
}
&:nth-child(2) {
color: var(--dark-dark-text);
}
}
}
}
.item-row {
background: var(--dark-sidebar-light-4);
border: 1px solid #333;
.question {
background: var(--dark-sidebar-light-4);
}
.answer {
background: dimgray;
border: 1px solid #333;
}
}
}
@media only screen and (max-width: 767px) {
.company-dashboard {
.company-header {
flex-wrap: wrap;
.header-item {
width: 50%;
border-right: none;
border: none;
padding: 16px 0;
}
}
.dashboard-card {
&.is-tickets {
padding: 30px;
.ticket-list {
align-content: center;
.media-flex {
.flex-meta {
margin-bottom: 1rem;
}
}
}
}
}
}
}
/* ==========================================================================
1. Confirm Account
========================================================================== */
.fw-btn {
width: 100%;
}
.videoheight {
height: 187px;
width: 250;
border-radius: 0.25rem;
background-color: #5b6467;
background-image: linear-gradient(315deg, #5b6467 0%, #8b939a 74%);
background-image: linear-gradient(360deg, #000000 0%, #434343 74%);
animation-duration: 3s;
animation-fill-mode: forwards;
animation-iteration-count: infinite;
animation-name: placeHolderShimmer;
animation-timing-function: linear;
background: fff;
background: linear-gradient(to right, #434343 8%, #000000 25%, #434343 50%);
width: 100%;
padding-top: 50px;
border-radius: 0.35rem;
}
@keyframes placeHolderShimmer {
0% {
background-position: 0px 0;
}
100% {
background-position: 100em 0;
}
}
.submitcomplete {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
min-height: 60px;
margin: 0 auto;
}
video {
height: 187px;
width: 248;
background-color: #000;
border-radius: 0.35rem;
}
.custom-card {
border: 0;
backdrop-filter: whitesmoke;
}
@media only screen and (min-width: 600px) {
.promotion-page-wrapper {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
margin: 0 auto;
max-width: 840px;
.wrapper-outer {
// @include vuero-s-card();
display: flex;
padding: 0;
width: 100%;
.wrapper-inner {
.action-box {
border: none;
background: none;
border-radius: 0;
border-right: 1px solid var(--fade-grey-dark-3);
// min-height: 420px;
.price {
text-align: center;
padding-top: 8px;
span {
display: block;
font-family: var(--font);
&:first-child {
font-size: 2.8rem;
font-weight: 600;
color: var(--dark-text);
line-height: 1;
&::before {
position: relative;
top: -12px;
content: '$';
font-size: 60%;
}
}
&:nth-child(2) {
font-size: 0.75rem;
color: var(--light-text);
text-transform: uppercase;
}
}
}
}
}
.side-wrapper {
flex-grow: 2;
padding: 40px;
min-width: 40%;
.side-inner {
.side-title {
font-family: var(--font);
margin-bottom: 16px;
h3 {
font-family: var(--font-alt);
font-weight: 600;
color: var(--dark-text);
}
p {
font-size: 0.9rem;
}
}
.action-list {
.media-flex {
.icon-wrap {
display: flex;
justify-content: center;
align-items: center;
height: 32px;
width: 32px;
min-width: 32px;
border-radius: var(--radius-rounded);
background: var(--white);
border: 1px solid var(--fade-grey-dark-3);
box-shadow: var(--light-box-shadow);
color: var(--primary);
svg {
width: 16px;
height: 16px;
stroke-width: 3px;
}
}
.flex-meta {
span {
font-weight: 400;
font-size: 0.9rem;
}
p {
font-size: 0.9rem;
max-width: 240px;
}
}
}
}
}
}
}
.wrapper-inner {
.action-box {
@include vuero-s-card();
padding: 40px;
.box-content {
text-align: left;
font-family: var(--font);
img {
display: block;
width: 100%;
max-width: 220px;
margin: 0 auto 8px auto;
&.is-larger {
max-width: 300px;
}
}
h3 {
font-size: 1.1rem;
font-family: var(--font-alt);
font-weight: 600;
// max-width: 320px;
margin: 0 auto 8px auto;
span {
color: var(--primary);
}
}
p {
font-size: 0.9rem;
}
.buttons {
margin: 0 auto;
display: flex;
justify-content: center;
padding-top: 30px;
.button {
margin: 0 4px;
min-width: 180px;
}
}
}
}
}
}
}
.promotion-page-wrapper {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
margin: 0 auto;
.wrapper-outer {
// @include vuero-s-card();
display: flex;
padding: 0;
.wrapper-inner {
.action-box {
border: none;
background: none;
border-radius: 0;
// border-right: 1px solid var(--fade-grey-dark-3);
.price {
text-align: center;
padding-top: 8px;
span {
display: block;
font-family: var(--font);
&:first-child {
font-size: 2.8rem;
font-weight: 600;
color: var(--dark-text);
line-height: 1;
&::before {
position: relative;
top: -12px;
content: '$';
font-size: 60%;
}
}
&:nth-child(2) {
font-size: 0.75rem;
color: var(--light-text);
text-transform: uppercase;
}
}
}
}
}
.side-wrapper {
flex-grow: 2;
padding: 40px;
min-width: 40%;
.side-inner {
.side-title {
font-family: var(--font);
margin-bottom: 16px;
h3 {
font-family: var(--font-alt);
font-weight: 600;
color: var(--dark-text);
}
p {
font-size: 0.9rem;
}
}
.action-list {
.media-flex {
.icon-wrap {
display: flex;
justify-content: center;
align-items: center;
height: 32px;
width: 32px;
min-width: 32px;
border-radius: var(--radius-rounded);
background: var(--white);
border: 1px solid var(--fade-grey-dark-3);
box-shadow: var(--light-box-shadow);
color: var(--primary);
svg {
width: 16px;
height: 16px;
stroke-width: 3px;
}
}
.flex-meta {
span {
font-weight: 400;
font-size: 0.9rem;
}
p {
font-size: 0.9rem;
max-width: 240px;
}
}
}
}
}
}
}
.wrapper-inner {
.action-box {
@include vuero-s-card();
padding: 40px;
.box-content {
text-align: left;
font-family: var(--font);
img {
display: block;
width: 100%;
max-width: 220px;
margin: 0 auto 8px auto;
&.is-larger {
max-width: 300px;
}
}
h3 {
font-size: 1.1rem;
font-family: var(--font-alt);
font-weight: 600;
// max-width: 320px;
margin: 0 auto 8px auto;
span {
color: var(--primary);
}
}
p {
font-size: 0.9rem;
}
.buttons {
margin: 0 auto;
display: flex;
justify-content: center;
padding-top: 30px;
.button {
margin: 0 4px;
min-width: 180px;
}
}
}
}
}
}
.is-dark {
.promotion-page-wrapper {
.wrapper-inner {
.action-box {
@include vuero-card--dark();
}
}
.wrapper-outer {
@include vuero-card--dark();
}
}
}
@media only screen and (max-width: 767px) {
.promotion-page-wrapper {
.wrapper-outer {
flex-direction: column;
.wrapper-inner {
.action-box {
padding: 20px 20px 40px 20px;
border-right: none;
border-bottom: 1px solid var(--fade-grey-dark-3);
.box-content {
.buttons {
.button {
min-width: 130px;
}
}
}
}
}
.side-wrapper {
padding: 40px 35px;
}
}
}
}
.form-fieldset {
max-width: 100% !important;
padding: 0 !important;
}
</style>