mirror of
https://github.com/qdrant/landing_page.git
synced 2026-10-03 09:58:30 +02:00
Elastic lucene lp (#2013)
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
<div class="callout">
|
||||
<div class="callout__square-grid-overlay"></div>
|
||||
<div class="callout__illustration" style="background-image: url('{{ .Params.image.src }}');"></div>
|
||||
<div class="callout__lights-overlay"></div>
|
||||
<div class="callout__content">
|
||||
<h5 class="callout__title">{{ .Params.title | safeHTML }}</h5>
|
||||
<div class="callout__description">{{ .Params.description | safeHTML }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,20 @@
|
||||
{{ with (.Site.GetPage "/elastic-lucene/elastic-lucene-features") }}
|
||||
<section class="grey-bg py-5">
|
||||
<div class="container">
|
||||
<h3 class="text-center mb-5">{{ .Params.title }}</h3>
|
||||
<div class="row g-4">
|
||||
{{ range $index, $feature := .Params.features }}
|
||||
<div class="col-12 {{ if eq $index 0 }}col-md-12{{ else }}col-md-6{{ end }} col-xl-4">
|
||||
<a href="{{ $feature.link.url }}" class="card d-flex flex-column gap-3">
|
||||
<img src="{{ $feature.icon.src }}" alt="{{ $feature.icon.alt }}" width="24" height="24" />
|
||||
<p class="mb-0 text-dark">{{ $feature.description }}</p>
|
||||
<p class="m-0">
|
||||
<span class="link link_md">{{ $feature.link.text }}</span>
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{{ end }}
|
||||
@@ -0,0 +1,184 @@
|
||||
<script>
|
||||
hbspt.forms.create({
|
||||
portalId: '139603372',
|
||||
formId: '814b303f-2f24-460a-8a81-367146d98786',
|
||||
region: 'eu1',
|
||||
sfdcCampaignId: '701fI00000M2FnuQAF',
|
||||
target: '#qdrant-contact-form',
|
||||
cssClass: 'luceneForm',
|
||||
submitButtonClass: 'button button_contained button_lg',
|
||||
|
||||
onFormReady: function ($form) {
|
||||
// Normalize to a plain DOM element
|
||||
var formEl;
|
||||
if ($form && $form.nodeType === 1) {
|
||||
formEl = $form;
|
||||
} else if ($form && $form[0] && $form[0].nodeType === 1) {
|
||||
formEl = $form[0];
|
||||
}
|
||||
if (!formEl) return;
|
||||
|
||||
/* ──────────────────────────────
|
||||
Hidden field: last_conversion_campaign_name
|
||||
───────────────────────────────*/
|
||||
var hidden = document.createElement('input');
|
||||
hidden.type = 'hidden';
|
||||
hidden.name = 'last_conversion_campaign_name';
|
||||
hidden.value = '2025.Q4_Website_Contact Us Form_Elastic_LP';
|
||||
formEl.appendChild(hidden);
|
||||
|
||||
/* ──────────────────────────────
|
||||
Progressive steps logic
|
||||
───────────────────────────────*/
|
||||
|
||||
// Helper: get the .hs-form-field wrapper for a given input/select/textarea
|
||||
function wrapperForField(selector) {
|
||||
var field = formEl.querySelector(selector);
|
||||
return field && field.closest('.hs-form-field');
|
||||
}
|
||||
|
||||
// Step 0: email (only visible on load)
|
||||
var step0 = [wrapperForField('input[name="email"]')];
|
||||
|
||||
// Step 1: first/last/company/jobtitle
|
||||
var step1 = [
|
||||
wrapperForField('input[name="firstname"]'),
|
||||
wrapperForField('input[name="lastname"]'),
|
||||
wrapperForField('input[name="company"]'),
|
||||
wrapperForField('input[name="jobtitle"]'),
|
||||
];
|
||||
|
||||
// Step 2: number_of_vectors + message
|
||||
var step2 = [wrapperForField('input[name="number_of_vectors"]'), wrapperForField('textarea[name="message"]')];
|
||||
|
||||
// Step 3: country
|
||||
var step3 = [wrapperForField('select[name="country"]')];
|
||||
|
||||
// Clean out any null entries
|
||||
var steps = [step0, step1, step2, step3].map(function (group) {
|
||||
return group.filter(function (el) {
|
||||
return !!el;
|
||||
});
|
||||
});
|
||||
|
||||
// Submit button wrapper (HubSpot’s markup varies a bit, so be lenient)
|
||||
var submitGroup = formEl.querySelector('.hs-submit, .hs_submit, .actions');
|
||||
if (submitGroup) submitGroup.style.display = 'none';
|
||||
|
||||
// Hide all steps except the first (email)
|
||||
steps.forEach(function (group, index) {
|
||||
if (index === 0) return; // keep email visible
|
||||
group.forEach(function (el) {
|
||||
el.style.display = 'none';
|
||||
});
|
||||
});
|
||||
|
||||
// REQUIRED fields that gate each step
|
||||
// 0: email
|
||||
// 1: firstname, lastname, company (jobtitle optional)
|
||||
// 2: message (number_of_vectors optional)
|
||||
// 3: no additional requirement – we only show it when step 2 is done
|
||||
var requiredSelectorsByStep = [
|
||||
['input[name="email"]'],
|
||||
['input[name="firstname"]', 'input[name="lastname"]', 'input[name="company"]'],
|
||||
['textarea[name="message"]'],
|
||||
[],
|
||||
];
|
||||
|
||||
function isStepFilled(stepIndex) {
|
||||
var selectors = requiredSelectorsByStep[stepIndex] || [];
|
||||
for (var i = 0; i < selectors.length; i++) {
|
||||
var field = formEl.querySelector(selectors[i]);
|
||||
if (!field) continue; // don’t block if missing
|
||||
var val = field.value;
|
||||
if (!val || !val.trim()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function showGroup(group) {
|
||||
group.forEach(function (el) {
|
||||
el.style.display = '';
|
||||
});
|
||||
}
|
||||
|
||||
function maybeShowNext(stepIndex) {
|
||||
if (!isStepFilled(stepIndex)) return;
|
||||
|
||||
var nextIndex = stepIndex + 1;
|
||||
var nextStep = steps[nextIndex];
|
||||
|
||||
if (nextStep) {
|
||||
// Reveal the next step
|
||||
showGroup(nextStep);
|
||||
|
||||
// If this is the last step (country), also reveal the submit button
|
||||
if (nextIndex === steps.length - 1 && submitGroup) {
|
||||
submitGroup.style.display = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function attach(stepIndex, selectors) {
|
||||
selectors.forEach(function (sel) {
|
||||
var field = formEl.querySelector(sel);
|
||||
if (!field) return;
|
||||
|
||||
['input', 'change', 'blur'].forEach(function (evt) {
|
||||
field.addEventListener(evt, function () {
|
||||
maybeShowNext(stepIndex);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Attach listeners:
|
||||
|
||||
// After email → show first/last/company/jobtitle
|
||||
attach(0, ['input[name="email"]']);
|
||||
|
||||
// After first/last/company → show message + vectors
|
||||
attach(1, [
|
||||
'input[name="firstname"]',
|
||||
'input[name="lastname"]',
|
||||
'input[name="company"]',
|
||||
'input[name="jobtitle"]',
|
||||
]);
|
||||
|
||||
// After message (vectors optional) → show country + submit
|
||||
attach(2, ['input[name="number_of_vectors"]', 'textarea[name="message"]']);
|
||||
|
||||
// Step 3 (country) doesn’t gate anything right now, but we could attach here if needed:
|
||||
// attach(3, ['select[name="country"]']);
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
// shows a fallback content if HubSpot forms library is not loaded
|
||||
// what can happen if the user has trackers blocking policy turned on
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
if (typeof hbspt === 'undefined' || !hbspt.forms) {
|
||||
const fallbackButtonContainer = document.createElement('div');
|
||||
fallbackButtonContainer.className = 'd-flex flex-column align-content-center px-5 py-5';
|
||||
const fallbackText = document.createElement('p');
|
||||
fallbackText.className = 'text-white text-center mb-4';
|
||||
fallbackText.innerHTML = {{- .Params.form.fallback.text -}};
|
||||
fallbackButtonContainer.appendChild(fallbackText);
|
||||
|
||||
// Create a fallback button only if the link is provided
|
||||
// warning: check if content via the link is not blocked as well
|
||||
{{ if .Params.form.fallback.link }}
|
||||
const fallbackButton = document.createElement('a');
|
||||
fallbackButton.href = {{- .Params.form.fallback.link -}};
|
||||
fallbackButton.target = '_blank';
|
||||
fallbackButton.className = 'button button_contained button_lg';
|
||||
fallbackButton.textContent = {{- .Params.form.fallback.buttonText -}};
|
||||
fallbackButtonContainer.appendChild(fallbackButton);
|
||||
{{ end }}
|
||||
|
||||
document.getElementsByClassName("elastic-lucene-form__content")[0].appendChild(fallbackButtonContainer);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,17 @@
|
||||
{{ with (.Site.GetPage "/elastic-lucene/elastic-lucene-form") }}
|
||||
<section class="elastic-lucene-form">
|
||||
<div class="elastic-lucene-form__illustration" style="background-image: url('{{ .Params.image.src }}');"></div>
|
||||
<div class="container">
|
||||
<div class="row position-relative">
|
||||
<div class="col-12 col-lg-6 offset-0 offset-lg-6 elastic-lucene-form__content">
|
||||
<h2 class="elastic-lucene-form__title text-white mb-4">{{ .Params.title }}</h2>
|
||||
<div class="elastic-lucene-form__description">
|
||||
{{ .Params.content | safeHTML }}
|
||||
</div>
|
||||
<div id="qdrant-contact-form"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ partial "top-and-bottom-overlay" (dict "context" . "class" "elastic-lucene-form") }}
|
||||
</section>
|
||||
{{ end }}
|
||||
@@ -0,0 +1,30 @@
|
||||
<section class="elastic-lucene-hero" style="--bg-image: url('{{ .Params.image.src }}');">
|
||||
<div class="elastic-lucene-hero__illustration"></div>
|
||||
<div class="container">
|
||||
<div class="row align-items-lg-center">
|
||||
<div class="elastic-lucene-hero__content col-12 col-lg-8">
|
||||
<h1 class="elastic-lucene-hero__title">{{ .Params.title }}</h1>
|
||||
<p class="elastic-lucene-hero__description">{{ .Params.description }}</p>
|
||||
<div class="elastic-lucene-hero__quotes">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="1"
|
||||
height="85"
|
||||
viewBox="0 0 1 85"
|
||||
fill="none"
|
||||
class="elastic-lucene-hero__quotes-line"
|
||||
>
|
||||
<path d="M0.5 0.5V84.5" stroke="#8F98B3" stroke-linecap="round" />
|
||||
</svg>
|
||||
<div class="elastic-lucene-hero__quotes-list">
|
||||
{{ range .Params.quotes }}
|
||||
<p>{{ . }}</p>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
<p class="elastic-lucene-hero__closing">{{ .Params.closingText }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="elastic-lucene-hero__overlay"></div>
|
||||
</section>
|
||||
@@ -0,0 +1,44 @@
|
||||
{{ with (.Site.GetPage "/elastic-lucene/elastic-lucene-lessons") }}
|
||||
<section class="outlined-card-group grey-bg pt-6">
|
||||
<div class="container">
|
||||
<div class="outlined-card-group__cards row gy-0">
|
||||
<div class="col-12 p-0">
|
||||
<div class="card outlined-card-group__header-card">
|
||||
<h4 class="outlined-card-group__header-title text-center mb-0">
|
||||
{{ .Params.title | safeHTML }}
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 p-0 d-flex flex-column flex-lg-row justify-content-between gap-3">
|
||||
{{ range .Params.lessons }}
|
||||
<div class="card outlined-card-group__card">
|
||||
<div class="og-card__images-row">
|
||||
<div>
|
||||
<img src="{{ .imageLeft.src }}" width="100%" alt="{{ .imageLeft.alt }}" />
|
||||
</div>
|
||||
<div>
|
||||
<a href="{{ .link.url }}">
|
||||
<img src="{{ .imageMiddle.src }}" width="100%" alt="{{ .imageMiddle.alt }}" />
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<img src="{{ .imageRight.src }}" width="100%" alt="{{ .imageRight.alt }}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="outlined-card-group__content px-0">
|
||||
<div class="outlined-card-group__text">
|
||||
<h6 class="outlined-card-group__title">{{ .title | safeHTML }}</h6>
|
||||
<p class="outlined-card-group__description">{{ .description | safeHTML }}</p>
|
||||
</div>
|
||||
<a href="{{ .link.url }}" class="link outlined-card-group__link">
|
||||
{{ .link.text }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{{ end }}
|
||||
@@ -0,0 +1,40 @@
|
||||
{{ with (.Site.GetPage "/elastic-lucene/elastic-lucene-migration") }}
|
||||
<section class="outlined-card-group grey-bg pt-5 pb-6">
|
||||
<div class="container">
|
||||
<div class="outlined-card-group__cards row gy-0">
|
||||
<div class="col-12 p-0">
|
||||
<div class="card outlined-card-group__header-card">
|
||||
<h4 class="outlined-card-group__header-title text-center mb-0">
|
||||
{{ .Params.headerTitle | safeHTML }}
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 p-0">
|
||||
<div class="card outlined-card-group__card outlined-card-group__card--jumbo">
|
||||
<div class="outlined-card-group__content outlined-card-group__content--jumbo">
|
||||
<div class="outlined-card-group__illustration">
|
||||
<img src="{{ .Params.image.src }}" alt="{{ .Params.image.alt }}" />
|
||||
</div>
|
||||
<div class="outlined-card-group__text">
|
||||
<h3 class="outlined-card-group__title outlined-card-group__title--large">{{ .Params.title }}</h3>
|
||||
<p class="outlined-card-group__subtitle">{{ .Params.subtitle }}</p>
|
||||
<p class="outlined-card-group__description outlined-card-group__description--small">
|
||||
{{ .Params.description }}
|
||||
</p>
|
||||
<p class="outlined-card-group__description outlined-card-group__description--small">
|
||||
{{ .Params.descriptionSecond }}
|
||||
</p>
|
||||
<a
|
||||
href="{{ .Params.button.url }}"
|
||||
class="button button_contained button_lg outlined-card-group__button"
|
||||
>
|
||||
{{ .Params.button.text }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{{ end }}
|
||||
@@ -0,0 +1,24 @@
|
||||
{{ with (.Site.GetPage "/elastic-lucene/elastic-lucene-optimization") }}
|
||||
<section class="outlined-card-group grey-bg py-5">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<h3 class="text-center col-12 mb-5">{{ .Params.title }}</h3>
|
||||
</div>
|
||||
<div class="outlined-card-group__cards">
|
||||
<div class="row g-3">
|
||||
{{ range .Params.features }}
|
||||
<div class="col-12 col-md-6 col-xl-3 d-flex">
|
||||
<div class="card outlined-card-group__card w-100">
|
||||
<div class="d-flex flex-column gap-3">
|
||||
<img class="outlined-card-group__icon" src="{{ .icon.src }}" alt="{{ .icon.alt }}" />
|
||||
<h6 class="outlined-card-group__title outlined-card-group__title--small">{{ .title }}</h6>
|
||||
<p class="outlined-card-group__description">{{ .description }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{{ end }}
|
||||
@@ -0,0 +1,32 @@
|
||||
{{ with (.Site.GetPage "/elastic-lucene/why-qdrant") }}
|
||||
<section class="py-5 grey-bg">
|
||||
<div class="container">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-12 col-lg-6 mb-4 mb-lg-0">
|
||||
<div class="split-section__content">
|
||||
<h3 class="split-section__title">{{ .Params.title }}</h3>
|
||||
<div class="split-section__description">
|
||||
<p>{{ .Params.description }}</p>
|
||||
<p>{{ .Params.descriptionSecond }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6">
|
||||
<div class="card split-section__testimonial-card width-auto">
|
||||
<div class="split-section__logo-container">
|
||||
<img
|
||||
class="split-section__logo"
|
||||
src="{{ .Params.testimonial.logo.src }}"
|
||||
alt="{{ .Params.testimonial.logo.alt }}"
|
||||
/>
|
||||
</div>
|
||||
<p class="split-section__testimonial-text">{{ .Params.testimonial.text }}</p>
|
||||
<div class="split-section__link-wrapper">
|
||||
<a class="link link_md" href="{{ .Params.testimonial.link.url }}">{{ .Params.testimonial.link.text }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{{ end }}
|
||||
@@ -1,6 +1,6 @@
|
||||
{{ $section := .Section }}
|
||||
{{ with (.Site.GetPage "/headless/menu") }}
|
||||
<div class="main-menu z-2">
|
||||
<div class="main-menu">
|
||||
<a href="/">
|
||||
{{ partial "logo.html" . }}
|
||||
</a>
|
||||
|
||||
Reference in New Issue
Block a user