From 6a4845396cdd584eac85d8ad5ce4ecccd5c795be Mon Sep 17 00:00:00 2001 From: Dan <39170265+chillenberger@users.noreply.github.com> Date: Fri, 8 Mar 2024 13:47:03 -0700 Subject: [PATCH 1/4] html for career apply, make split section --- pgml-dashboard/src/api/cms.rs | 12 ++ .../accordian/accordian_controller.js | 5 +- .../carousel/carousel_controller.js | 88 ++++++------ .../components/chatbot/chatbot_controller.js | 133 ++++++++++++------ .../code_block/code_block_controller.js | 88 +++++++----- .../range_group/range_group_controller.js | 120 ++++++++-------- .../inputs/select/select_controller.js | 16 +-- .../inputs/switch/switch_controller.js | 61 ++++---- .../editable_header_controller.js | 36 ++--- .../components/layouts/marketing/base/mod.rs | 7 + .../layouts/marketing/base/template.html | 2 +- .../src/components/loading/message/mod.rs | 2 +- .../src/components/modal/modal_controller.js | 12 +- .../navigation/navbar/marketing/mod.rs | 7 + .../navigation/navbar/marketing/template.html | 2 +- .../pages/article/index/template.html | 16 ++- .../blog/blog_search/call/call_controller.js | 55 ++++---- .../components/pages/careers/apply/apply.scss | 1 + .../pages/careers/apply/apply_controller.js | 12 ++ .../src/components/pages/careers/apply/mod.rs | 23 +++ .../pages/careers/apply/template.html | 83 +++++++++++ .../pages/careers/landing_page/template.html | 2 +- .../src/components/pages/careers/mod.rs | 4 + .../src/components/postgres_logo/mod.rs | 11 +- .../components/postgres_logo/template.html | 11 +- pgml-dashboard/src/components/sections/mod.rs | 4 + .../src/components/sections/split/mod.rs | 45 ++++++ .../src/components/sections/split/split.scss | 92 ++++++++++++ .../sections/split/split_controller.js | 14 ++ .../components/sections/split/template.html | 47 +++++++ .../static_nav/static_nav_controller.js | 8 +- .../tables/large/table/table_controller.js | 8 +- pgml-dashboard/static/css/modules.scss | 2 + .../static/css/scss/components/_navs.scss | 2 +- 34 files changed, 733 insertions(+), 298 deletions(-) create mode 100644 pgml-dashboard/src/components/pages/careers/apply/apply.scss create mode 100644 pgml-dashboard/src/components/pages/careers/apply/apply_controller.js create mode 100644 pgml-dashboard/src/components/pages/careers/apply/mod.rs create mode 100644 pgml-dashboard/src/components/pages/careers/apply/template.html create mode 100644 pgml-dashboard/src/components/sections/split/mod.rs create mode 100644 pgml-dashboard/src/components/sections/split/split.scss create mode 100644 pgml-dashboard/src/components/sections/split/split_controller.js create mode 100644 pgml-dashboard/src/components/sections/split/template.html diff --git a/pgml-dashboard/src/api/cms.rs b/pgml-dashboard/src/api/cms.rs index 1b1978b05..af41f96a1 100644 --- a/pgml-dashboard/src/api/cms.rs +++ b/pgml-dashboard/src/api/cms.rs @@ -773,6 +773,17 @@ async fn get_careers( CAREERS.render(&doc_file_path, &canonical, cluster).await } +#[get("/careers/apply/", rank = 4)] +pub async fn careers_apply(title: PathBuf, cluster: &Cluster) -> Result<ResponseOk, crate::responses::NotFound> { + let mut layout = + crate::components::layouts::marketing::Base::new("Apply for a career", Some(&cluster)).no_transparent_nav(); + + let job_title = title.display().to_string().replace("-", " "); + let page = crate::components::pages::careers::Apply::new().job_title(&job_title); + + Ok(ResponseOk(layout.render(page))) +} + #[get("/docs/<path..>", rank = 5)] async fn get_docs( path: PathBuf, @@ -876,6 +887,7 @@ pub fn routes() -> Vec<Route> { blog_landing_page, docs_landing_page, careers_landing_page, + careers_apply, get_blog, get_blog_asset, get_careers, diff --git a/pgml-dashboard/src/components/accordian/accordian_controller.js b/pgml-dashboard/src/components/accordian/accordian_controller.js index d91ba65f6..ea2ea560c 100644 --- a/pgml-dashboard/src/components/accordian/accordian_controller.js +++ b/pgml-dashboard/src/components/accordian/accordian_controller.js @@ -13,10 +13,9 @@ export default class extends Controller { } else { this.bodies[i].style.maxHeight = this.bodies[i].offsetHeight + "px"; } - } + } } - titleClick(e) { let target = e.currentTarget.getAttribute("data-value"); e.currentTarget.classList.add("selected"); @@ -24,7 +23,7 @@ export default class extends Controller { let body = document.querySelector(`[data-accordian-target="${target}"]`); body.classList.add("selected"); body.style.maxHeight = this.heights.get(body) + "px"; - + for (let i = 0; i < this.bodies.length; i++) { if (body != this.bodies[i]) { this.bodies[i].classList.remove("selected"); diff --git a/pgml-dashboard/src/components/carousel/carousel_controller.js b/pgml-dashboard/src/components/carousel/carousel_controller.js index 9b2266a11..367a3ea49 100644 --- a/pgml-dashboard/src/components/carousel/carousel_controller.js +++ b/pgml-dashboard/src/components/carousel/carousel_controller.js @@ -1,91 +1,87 @@ -import { Controller } from '@hotwired/stimulus' +import { Controller } from "@hotwired/stimulus"; export default class extends Controller { - static targets = [ - "carousel", "carouselTimer", "template" - ] + static targets = ["carousel", "carouselTimer", "template"]; initialize() { - this.paused = false - this.runtime = 0 + this.paused = false; + this.runtime = 0; this.times = 1; } connect() { - // dont cycle carousel if it only hase one item. - if ( this.templateTargets.length > 1 ) { - this.cycle() + // dont cycle carousel if it only hase one item. + if (this.templateTargets.length > 1) { + this.cycle(); } } changeFeatured(next) { - let current = this.carouselTarget.children[0] - let nextItem = next.content.cloneNode(true) - - this.carouselTarget.appendChild(nextItem) + let current = this.carouselTarget.children[0]; + let nextItem = next.content.cloneNode(true); - if( current ) { + this.carouselTarget.appendChild(nextItem); + + if (current) { current.style.marginLeft = "-100%"; - setTimeout( () => { - this.carouselTarget.removeChild(current) - }, 700) + setTimeout(() => { + this.carouselTarget.removeChild(current); + }, 700); } } changeIndicator(current, next) { let timers = this.carouselTimerTargets; let currentTimer = timers[current]; - let nextTimer = timers[next] + let nextTimer = timers[next]; - if ( currentTimer ) { - currentTimer.classList.remove("timer-active") - currentTimer.style.width = "1rem" + if (currentTimer) { + currentTimer.classList.remove("timer-active"); + currentTimer.style.width = "1rem"; + } + if (nextTimer) { + nextTimer.style.width = "4rem"; + nextTimer.classList.add("timer-active"); } - if( nextTimer) { - nextTimer.style.width = "4rem" - nextTimer.classList.add("timer-active") - } } Pause() { - this.paused = true + this.paused = true; } Resume() { - this.paused = false + this.paused = false; } cycle() { this.interval = setInterval(() => { // maintain paused state through entire loop - let paused = this.paused + let paused = this.paused; - let activeTimer = document.getElementsByClassName("timer-active")[0] - if( paused ) { - if( activeTimer ) { - activeTimer.classList.add("timer-pause") + let activeTimer = document.getElementsByClassName("timer-active")[0]; + if (paused) { + if (activeTimer) { + activeTimer.classList.add("timer-pause"); } } else { - if( activeTimer && activeTimer.classList.contains("timer-pause")) { - activeTimer.classList.remove("timer-pause") + if (activeTimer && activeTimer.classList.contains("timer-pause")) { + activeTimer.classList.remove("timer-pause"); } } - if( !paused && this.runtime % 5 == 0 ) { - let currentIndex = this.times % this.templateTargets.length - let nextIndex = (this.times + 1) % this.templateTargets.length - - this.changeIndicator(currentIndex, nextIndex) - this.changeFeatured( - this.templateTargets[nextIndex] - ) - this.times ++ + if (!paused && this.runtime % 5 == 0) { + let currentIndex = this.times % this.templateTargets.length; + let nextIndex = (this.times + 1) % this.templateTargets.length; + + this.changeIndicator(currentIndex, nextIndex); + this.changeFeatured(this.templateTargets[nextIndex]); + this.times++; } - if( !paused ) { - this.runtime++ + if (!paused) { + this.runtime++; } - }, 1000) + }, 1000); } disconnect() { diff --git a/pgml-dashboard/src/components/chatbot/chatbot_controller.js b/pgml-dashboard/src/components/chatbot/chatbot_controller.js index 29f9415e5..ea81b8492 100644 --- a/pgml-dashboard/src/components/chatbot/chatbot_controller.js +++ b/pgml-dashboard/src/components/chatbot/chatbot_controller.js @@ -6,7 +6,7 @@ import * as marked from "marked"; const getRandomInt = () => { return Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); -} +}; const LOADING_MESSAGE = ` <div class="d-flex align-items-end"> @@ -20,13 +20,13 @@ const getBackgroundImageURLForSide = (side, brain) => { return "/dashboard/static/images/chatbot_user.webp"; } else { if (brain == "teknium/OpenHermes-2.5-Mistral-7B") { - return "/dashboard/static/images/logos/openhermes.webp" + return "/dashboard/static/images/logos/openhermes.webp"; } else if (brain == "Gryphe/MythoMax-L2-13b") { - return "/dashboard/static/images/logos/mythomax.webp" + return "/dashboard/static/images/logos/mythomax.webp"; } else if (brain == "berkeley-nest/Starling-LM-7B-alpha") { - return "/dashboard/static/images/logos/starling.webp" + return "/dashboard/static/images/logos/starling.webp"; } else if (brain == "openai") { - return "/dashboard/static/images/logos/openai.webp" + return "/dashboard/static/images/logos/openai.webp"; } } }; @@ -73,15 +73,15 @@ const knowledgeBaseIdToName = (knowledgeBase) => { const brainIdToName = (brain) => { if (brain == "teknium/OpenHermes-2.5-Mistral-7B") { - return "OpenHermes" + return "OpenHermes"; } else if (brain == "Gryphe/MythoMax-L2-13b") { - return "MythoMax" + return "MythoMax"; } else if (brain == "berkeley-nest/Starling-LM-7B-alpha") { - return "Starling" + return "Starling"; } else if (brain == "openai") { - return "ChatGPT" + return "ChatGPT"; } -} +}; const createKnowledgeBaseNotice = (knowledgeBase) => { return ` @@ -92,12 +92,12 @@ const createKnowledgeBaseNotice = (knowledgeBase) => { }; class Message { - constructor(id, side, brain, text, is_partial=false) { - this.id = id - this.side = side - this.brain = brain - this.text = text - this.is_partial = is_partial + constructor(id, side, brain, text, is_partial = false) { + this.id = id; + this.side = side; + this.brain = brain; + this.text = text; + this.is_partial = is_partial; } get_html() { @@ -106,7 +106,7 @@ class Message { } class RawMessage extends Message { - constructor(id, side, text, is_partial=false) { + constructor(id, side, text, is_partial = false) { super(id, side, text, is_partial); } @@ -126,17 +126,28 @@ class MessageHistory { this.messageHistory[knowledgeBase] = []; } if (message.is_partial) { - let current_message = this.messageHistory[knowledgeBase].find(item => item.id == message.id); + let current_message = this.messageHistory[knowledgeBase].find( + (item) => item.id == message.id, + ); if (!current_message) { this.messageHistory[knowledgeBase].push(message); } else { current_message.text += message.text; } } else { - if (this.messageHistory[knowledgeBase].length == 0 || message.side != "system") { - this.messageHistory[knowledgeBase].push(message); - } else if (this.messageHistory[knowledgeBase][this.messageHistory[knowledgeBase].length -1].side == "system") { - this.messageHistory[knowledgeBase][this.messageHistory[knowledgeBase].length -1] = message + if ( + this.messageHistory[knowledgeBase].length == 0 || + message.side != "system" + ) { + this.messageHistory[knowledgeBase].push(message); + } else if ( + this.messageHistory[knowledgeBase][ + this.messageHistory[knowledgeBase].length - 1 + ].side == "system" + ) { + this.messageHistory[knowledgeBase][ + this.messageHistory[knowledgeBase].length - 1 + ] = message; } else { this.messageHistory[knowledgeBase].push(message); } @@ -156,7 +167,7 @@ export default class extends Controller { initialize() { this.messageHistory = new MessageHistory(); this.messageIdToKnowledgeBaseId = {}; - + this.expanded = false; this.chatbot = document.getElementById("chatbot"); this.expandContractImage = document.getElementById( @@ -179,7 +190,14 @@ export default class extends Controller { } openConnection() { - const url = ((window.location.protocol === "https:") ? "wss://" : "ws://") + window.location.hostname + (((window.location.port != 80) && (window.location.port != 443)) ? ":" + window.location.port : "") + window.location.pathname + "/get-answer"; + const url = + (window.location.protocol === "https:" ? "wss://" : "ws://") + + window.location.hostname + + (window.location.port != 80 && window.location.port != 443 + ? ":" + window.location.port + : "") + + window.location.pathname + + "/get-answer"; this.socket = new WebSocket(url); this.socket.onmessage = (message) => { let result = JSON.parse(message.data); @@ -190,11 +208,20 @@ export default class extends Controller { } else { let message; if (result.partial_result) { - message = new Message(result.id, "bot", this.brain, result.partial_result, true); + message = new Message( + result.id, + "bot", + this.brain, + result.partial_result, + true, + ); } else { message = new Message(result.id, "bot", this.brain, result.result); } - this.messageHistory.add_message(message, this.messageIdToKnowledgeBaseId[message.id]); + this.messageHistory.add_message( + message, + this.messageIdToKnowledgeBaseId[message.id], + ); this.redrawChat(); } this.chatHistory.scrollTop = this.chatHistory.scrollHeight; @@ -215,10 +242,16 @@ export default class extends Controller { const result = await fetch("/chatbot/get-history"); const history = await result.json(); if (history.error) { - console.log("Error getting chat history", history.error) + console.log("Error getting chat history", history.error); } else { for (const message of history.result) { - const newMessage = new Message(getRandomInt(), message.side, message.brain, message.content, false); + const newMessage = new Message( + getRandomInt(), + message.side, + message.brain, + message.content, + false, + ); console.log(newMessage); this.messageHistory.add_message(newMessage, message.knowledge_base); } @@ -239,12 +272,15 @@ export default class extends Controller { // Hide or show example questions this.hideExampleQuestions(); - if (messages.length == 0 || (messages.length == 1 && messages[0].side == "system")) { + if ( + messages.length == 0 || + (messages.length == 1 && messages[0].side == "system") + ) { document .getElementById(`chatbot-example-questions-${this.knowledgeBase}`) .style.setProperty("display", "flex", "important"); } - + this.chatHistory.scrollTop = this.chatHistory.scrollHeight; } @@ -255,20 +291,25 @@ export default class extends Controller { this.hideExampleQuestions(); this.redrawChat(); - let loadingMessage = new Message("loading", "bot", this.brain, LOADING_MESSAGE); + let loadingMessage = new Message( + "loading", + "bot", + this.brain, + LOADING_MESSAGE, + ); this.chatHistory.insertAdjacentHTML( "beforeend", createHistoryMessage(loadingMessage), ); this.chatHistory.scrollTop = this.chatHistory.scrollHeight; - + let id = getRandomInt(); this.messageIdToKnowledgeBaseId[id] = this.knowledgeBase; let socketData = { id, question, model: this.brain, - knowledge_base: this.knowledgeBase + knowledge_base: this.knowledgeBase, }; this.socket.send(JSON.stringify(socketData)); } @@ -293,8 +334,7 @@ export default class extends Controller { e.preventDefault(); // Don't continue if the question is empty const question = this.questionInput.value.trim(); - if (question.length == 0) - return; + if (question.length == 0) return; // Handle resetting the input // There is probably a better way to do this, but this was the best/easiest I found this.questionInput.value = ""; @@ -305,18 +345,20 @@ export default class extends Controller { } handleBrainChange() { - let selected = document.querySelector('input[name="chatbot-brain-options"]:checked').value; - if (selected == this.brain) - return; + let selected = document.querySelector( + 'input[name="chatbot-brain-options"]:checked', + ).value; + if (selected == this.brain) return; this.brain = selected; this.questionInput.focus(); this.addBrainAndKnowledgeBaseChangedSystemMessage(); } handleKnowledgeBaseChange() { - let selected = document.querySelector('input[name="chatbot-knowledge-base-options"]:checked').value; - if (selected == this.knowledgeBase) - return; + let selected = document.querySelector( + 'input[name="chatbot-knowledge-base-options"]:checked', + ).value; + if (selected == this.knowledgeBase) return; this.knowledgeBase = selected; this.redrawChat(); this.questionInput.focus(); @@ -327,7 +369,12 @@ export default class extends Controller { let knowledge_base = knowledgeBaseIdToName(this.knowledgeBase); let brain = brainIdToName(this.brain); let content = `Chatting with ${brain} about ${knowledge_base}`; - const newMessage = new Message(getRandomInt(), "system", this.brain, content); + const newMessage = new Message( + getRandomInt(), + "system", + this.brain, + content, + ); this.messageHistory.add_message(newMessage, this.knowledgeBase); this.redrawChat(); } @@ -355,7 +402,7 @@ export default class extends Controller { const toastElement = createToast(message, level); showToast(toastElement, { autohide: true, - delay: 7000 + delay: 7000, }); } diff --git a/pgml-dashboard/src/components/code_block/code_block_controller.js b/pgml-dashboard/src/components/code_block/code_block_controller.js index 3a4f92483..127d4a6b5 100644 --- a/pgml-dashboard/src/components/code_block/code_block_controller.js +++ b/pgml-dashboard/src/components/code_block/code_block_controller.js @@ -6,10 +6,13 @@ import { javascript } from "@codemirror/lang-javascript"; import { rust } from "@codemirror/lang-rust"; import { json } from "@codemirror/lang-json"; import { EditorView, ViewPlugin, Decoration } from "@codemirror/view"; -import { RangeSetBuilder, Facet} from "@codemirror/state"; +import { RangeSetBuilder, Facet } from "@codemirror/state"; import { HighlightStyle, syntaxHighlighting } from "@codemirror/language"; -import { highlightStyle, editorTheme } from "../../../static/js/utilities/code_mirror_theme"; +import { + highlightStyle, + editorTheme, +} from "../../../static/js/utilities/code_mirror_theme"; const buildEditorView = (target, content, languageExtension, classes) => { let editorView = new EditorView({ @@ -17,48 +20,55 @@ const buildEditorView = (target, content, languageExtension, classes) => { extensions: [ basicSetup, languageExtension !== null ? languageExtension() : [], // if no language chosen do not highlight syntax - EditorView.theme(editorTheme), + EditorView.theme(editorTheme), syntaxHighlighting(HighlightStyle.define(highlightStyle)), EditorView.contentAttributes.of({ contenteditable: false }), addClasses.of(classes), - highlight + highlight, ], parent: target, - highlightActiveLine: false + highlightActiveLine: false, }); return editorView; }; -const highlight = ViewPlugin.fromClass(class { - constructor(view) { - this.decorations = highlightLine(view) - } +const highlight = ViewPlugin.fromClass( + class { + constructor(view) { + this.decorations = highlightLine(view); + } - update(update) { - if (update.docChanged || update.viewportChanged) - this.decorations = highlightLine(update.view) - } -}, { - decorations: v => v.decorations -}) + update(update) { + if (update.docChanged || update.viewportChanged) + this.decorations = highlightLine(update.view); + } + }, + { + decorations: (v) => v.decorations, + }, +); function highlightLine(view) { - let builder = new RangeSetBuilder() - let classes = view.state.facet(addClasses).shift() - for (let {from, to} of view.visibleRanges) { - for (let pos = from; pos <= to;) { - let lineClasses = classes.shift() - let line = view.state.doc.lineAt(pos) - builder.add(line.from, line.from, Decoration.line({attributes: {class: lineClasses}})) - pos = line.to + 1 + let builder = new RangeSetBuilder(); + let classes = view.state.facet(addClasses).shift(); + for (let { from, to } of view.visibleRanges) { + for (let pos = from; pos <= to; ) { + let lineClasses = classes.shift(); + let line = view.state.doc.lineAt(pos); + builder.add( + line.from, + line.from, + Decoration.line({ attributes: { class: lineClasses } }), + ); + pos = line.to + 1; } } - return builder.finish() + return builder.finish(); } const addClasses = Facet.define({ - combone: values => values -}) + combone: (values) => values, +}); const language = (element) => { switch (element.getAttribute("language")) { @@ -77,26 +87,26 @@ const language = (element) => { default: return null; } -} +}; const codeBlockCallback = (element) => { - let highlights = element.getElementsByClassName("highlight") + let highlights = element.getElementsByClassName("highlight"); let classes = []; - for(let lineNum = 0; lineNum < highlights.length; lineNum++) { - classes.push(highlights[lineNum].classList) + for (let lineNum = 0; lineNum < highlights.length; lineNum++) { + classes.push(highlights[lineNum].classList); } - - let content = element.textContent.trim() + + let content = element.textContent.trim(); element.innerHTML = ""; - return [element, content, classes] -} + return [element, content, classes]; +}; // Add Codemirror with data controller export default class extends Controller { connect() { - let [element, content, classes] = codeBlockCallback(this.element) - let lang = language(this.element) + let [element, content, classes] = codeBlockCallback(this.element); + let lang = language(this.element); buildEditorView(element, content, lang, classes); } @@ -107,11 +117,11 @@ class CodeBlockA extends HTMLElement { constructor() { super(); - this.language = language(this) + this.language = language(this); } connectedCallback() { - let [element, content, classes] = codeBlockCallback(this) + let [element, content, classes] = codeBlockCallback(this); buildEditorView(element, content, this.language, classes); } diff --git a/pgml-dashboard/src/components/inputs/range_group/range_group_controller.js b/pgml-dashboard/src/components/inputs/range_group/range_group_controller.js index 77cb092ba..c6110f697 100644 --- a/pgml-dashboard/src/components/inputs/range_group/range_group_controller.js +++ b/pgml-dashboard/src/components/inputs/range_group/range_group_controller.js @@ -1,7 +1,6 @@ -import { Controller } from '@hotwired/stimulus' +import { Controller } from "@hotwired/stimulus"; export default class extends Controller { - static targets = [ "range", "text", @@ -9,40 +8,47 @@ export default class extends Controller { "line", "tick", "tickText", - "smScreenText" - ] + "smScreenText", + ]; static values = { bounds: Object, - initial: Number - } + initial: Number, + }; initialize() { - this.textTarget.value = this.rangeTarget.value - this.updateTicks(this.rangeTarget.value) - this.updateTicksText(this.rangeTarget.value) + this.textTarget.value = this.rangeTarget.value; + this.updateTicks(this.rangeTarget.value); + this.updateTicksText(this.rangeTarget.value); } updateText(e) { - this.textTarget.value = e.target.value - this.element.dataset.detail = e.target.value - this.groupTarget.dispatchEvent(new CustomEvent("rangeInput", { detail: e.target.value })) + this.textTarget.value = e.target.value; + this.element.dataset.detail = e.target.value; + this.groupTarget.dispatchEvent( + new CustomEvent("rangeInput", { detail: e.target.value }), + ); } updateRange(e) { - if( e.target.value < this.boundsValue.min - || !e.target.value || !this.isNumeric(e.target.value)) { - this.rangeTarget.value = this.boundsValue.min - this.textTarget.value = this.boundsValue.min - } else if( e.target.value > this.boundsValue.max) { - this.rangeTarget.value = this.boundsValue.max - this.textTarget.value = this.boundsValue.max + if ( + e.target.value < this.boundsValue.min || + !e.target.value || + !this.isNumeric(e.target.value) + ) { + this.rangeTarget.value = this.boundsValue.min; + this.textTarget.value = this.boundsValue.min; + } else if (e.target.value > this.boundsValue.max) { + this.rangeTarget.value = this.boundsValue.max; + this.textTarget.value = this.boundsValue.max; } else { - this.rangeTarget.value = e.target.value + this.rangeTarget.value = e.target.value; } - this.element.dataset.detail = this.rangeTarget.value - this.groupTarget.dispatchEvent(new CustomEvent("rangeInput", { detail: this.rangeTarget.value })) + this.element.dataset.detail = this.rangeTarget.value; + this.groupTarget.dispatchEvent( + new CustomEvent("rangeInput", { detail: this.rangeTarget.value }), + ); } isNumeric(n) { @@ -50,75 +56,77 @@ export default class extends Controller { } reset() { - this.rangeTarget.value = this.initialValue - this.textTarget.value = this.initialValue - this.updateTicks(this.initialValue) - this.updateTicksText(this.initialValue) - this.element.dataset.detail = this.initialValue - this.groupTarget.dispatchEvent(new CustomEvent("rangeInput", { detail: this.rangeTarget.value })) + this.rangeTarget.value = this.initialValue; + this.textTarget.value = this.initialValue; + this.updateTicks(this.initialValue); + this.updateTicksText(this.initialValue); + this.element.dataset.detail = this.initialValue; + this.groupTarget.dispatchEvent( + new CustomEvent("rangeInput", { detail: this.rangeTarget.value }), + ); } - on_grab () { - if( this.hasLineTarget ) { - this.lineTarget.classList.add("grab-brightness") + on_grab() { + if (this.hasLineTarget) { + this.lineTarget.classList.add("grab-brightness"); } - if( this.hasTickTarget ) { + if (this.hasTickTarget) { this.tickTargets.forEach((tick, index) => { - if( index < this.rangeTarget.value ) { - tick.classList.add("grab-brightness") + if (index < this.rangeTarget.value) { + tick.classList.add("grab-brightness"); } else { - tick.classList.remove("grab-brightness") + tick.classList.remove("grab-brightness"); } - }) + }); } } on_release() { - if( this.hasLineTarget ) { - this.lineTarget.classList.remove("grab-brightness") + if (this.hasLineTarget) { + this.lineTarget.classList.remove("grab-brightness"); } - if( this.hasTickTarget ) { + if (this.hasTickTarget) { this.tickTargets.forEach((tick, index) => { - if( index < this.rangeTarget.value ) { - tick.classList.remove("grab-brightness") + if (index < this.rangeTarget.value) { + tick.classList.remove("grab-brightness"); } - }) + }); } } updateTicks(value) { - if(!this.hasTickTarget) return; + if (!this.hasTickTarget) return; this.tickTargets.forEach((tick, index) => { - if( index < value ) { - tick.classList.add("active-color") + if (index < value) { + tick.classList.add("active-color"); } else { - tick.classList.remove("active-color") + tick.classList.remove("active-color"); } - }) + }); } updateTicksText(value) { - if(this.hasTickTextTarget && this.hasSmScreenTextTarget) { + if (this.hasTickTextTarget && this.hasSmScreenTextTarget) { this.tickTextTargets.forEach((tickText, index) => { - if( index + 1 == value ) { - tickText.classList.add("active-color") - this.smScreenTextTargets[index].style.display = "flex" + if (index + 1 == value) { + tickText.classList.add("active-color"); + this.smScreenTextTargets[index].style.display = "flex"; } else { - tickText.classList.remove("active-color") - this.smScreenTextTargets[index].style.display = "none" + tickText.classList.remove("active-color"); + this.smScreenTextTargets[index].style.display = "none"; } - }) + }); } } updateTicksEventWrapper(e) { - this.updateTicks(e.target.value) + this.updateTicks(e.target.value); } updateTicksTextEventWrapper(e) { - this.updateTicksText(e.target.value) + this.updateTicksText(e.target.value); } } diff --git a/pgml-dashboard/src/components/inputs/select/select_controller.js b/pgml-dashboard/src/components/inputs/select/select_controller.js index d5321f1b0..35d479da2 100644 --- a/pgml-dashboard/src/components/inputs/select/select_controller.js +++ b/pgml-dashboard/src/components/inputs/select/select_controller.js @@ -1,19 +1,19 @@ -import { Controller } from '@hotwired/stimulus' +import { Controller } from "@hotwired/stimulus"; export default class extends Controller { - static targets = ["input", "value"] + static targets = ["input", "value"]; choose(e) { - this.setValue(e.target.innerHTML) + this.setValue(e.target.innerHTML); } - + resetSelect() { - this.setValue(this.element.dataset.initial) + this.setValue(this.element.dataset.initial); } setValue(value) { - this.inputTarget.value = value - this.valueTarget.innerHTML = value - this.inputTarget.dispatchEvent(new Event('change')) + this.inputTarget.value = value; + this.valueTarget.innerHTML = value; + this.inputTarget.dispatchEvent(new Event("change")); } } diff --git a/pgml-dashboard/src/components/inputs/switch/switch_controller.js b/pgml-dashboard/src/components/inputs/switch/switch_controller.js index cffc1ff16..9ad18e66a 100644 --- a/pgml-dashboard/src/components/inputs/switch/switch_controller.js +++ b/pgml-dashboard/src/components/inputs/switch/switch_controller.js @@ -1,52 +1,51 @@ -import { Controller } from '@hotwired/stimulus' +import { Controller } from "@hotwired/stimulus"; export default class extends Controller { - static targets = [ - "toggle", - "toggleText", - "toggleIcon", - ] + static targets = ["toggle", "toggleText", "toggleIcon"]; static values = { - "left": String, - "right": String, - "initial": String, - "leftIcon": String, - "rightIcon": String, - } + left: String, + right: String, + initial: String, + leftIcon: String, + rightIcon: String, + }; toggle() { - if (this.toggleTarget.classList.contains('right')) { - this.onToggleLeft() + if (this.toggleTarget.classList.contains("right")) { + this.onToggleLeft(); } else { - this.onToggleRight() + this.onToggleRight(); } } onToggleLeft() { - this.toggleTarget.classList.remove('right') - this.toggleTarget.classList.add('left') - this.toggleTextTarget.innerHTML = this.leftValue - this.toggleIconTarget.innerHTML = this.leftIconValue - this.element.dispatchEvent(new CustomEvent('toggle', {detail: this.leftValue})) + this.toggleTarget.classList.remove("right"); + this.toggleTarget.classList.add("left"); + this.toggleTextTarget.innerHTML = this.leftValue; + this.toggleIconTarget.innerHTML = this.leftIconValue; + this.element.dispatchEvent( + new CustomEvent("toggle", { detail: this.leftValue }), + ); } onToggleRight() { - this.toggleTarget.classList.remove('left') - this.toggleTarget.classList.add('right') - this.toggleTextTarget.innerHTML = this.rightValue - this.toggleIconTarget.innerHTML = this.rightIconValue - this.element.dispatchEvent(new CustomEvent('toggle', {detail: this.rightValue})) + this.toggleTarget.classList.remove("left"); + this.toggleTarget.classList.add("right"); + this.toggleTextTarget.innerHTML = this.rightValue; + this.toggleIconTarget.innerHTML = this.rightIconValue; + this.element.dispatchEvent( + new CustomEvent("toggle", { detail: this.rightValue }), + ); } reset() { - if( this.initialValue == "left" ) { - console.log("toggling left") - this.onToggleLeft() + if (this.initialValue == "left") { + console.log("toggling left"); + this.onToggleLeft(); } else { - console.log("toggling right") - this.onToggleRight() + console.log("toggling right"); + this.onToggleRight(); } } - } diff --git a/pgml-dashboard/src/components/inputs/text/editable_header/editable_header_controller.js b/pgml-dashboard/src/components/inputs/text/editable_header/editable_header_controller.js index b5195a087..bf92a9d9d 100644 --- a/pgml-dashboard/src/components/inputs/text/editable_header/editable_header_controller.js +++ b/pgml-dashboard/src/components/inputs/text/editable_header/editable_header_controller.js @@ -1,41 +1,41 @@ -import { Controller } from '@hotwired/stimulus' +import { Controller } from "@hotwired/stimulus"; export default class extends Controller { - static targets = ["input", "header", "error"] + static targets = ["input", "header", "error"]; focusout(e) { - this.headerTarget.innerHTML = e.target.value - this.toggleEditor() + this.headerTarget.innerHTML = e.target.value; + this.toggleEditor(); } blur() { - this.inputTarget.blur() + this.inputTarget.blur(); } toggleEditor(e) { // dont toggle if click inside input - if( e && this.inputTarget.contains(e.target)) { - return + if (e && this.inputTarget.contains(e.target)) { + return; } - if(this.inputTarget.style.display == "none") { - this.inputTarget.style.display = "block" - this.headerTarget.style.display = "none" - this.inputTarget.focus() + if (this.inputTarget.style.display == "none") { + this.inputTarget.style.display = "block"; + this.headerTarget.style.display = "none"; + this.inputTarget.focus(); } else { - this.inputTarget.style.display = "none" - this.headerTarget.style.display = "flex" + this.inputTarget.style.display = "none"; + this.headerTarget.style.display = "flex"; } } error(e) { - this.errorTarget.innerHTML = e.detail - this.errorTarget.style.display = "block" - this.headerTarget.classList.add("error") + this.errorTarget.innerHTML = e.detail; + this.errorTarget.style.display = "block"; + this.headerTarget.classList.add("error"); } clear() { - this.errorTarget.style.display = "none" - this.headerTarget.classList.remove("error") + this.errorTarget.style.display = "none"; + this.headerTarget.classList.remove("error"); } } diff --git a/pgml-dashboard/src/components/layouts/marketing/base/mod.rs b/pgml-dashboard/src/components/layouts/marketing/base/mod.rs index ce80e1655..5d1ee0d36 100644 --- a/pgml-dashboard/src/components/layouts/marketing/base/mod.rs +++ b/pgml-dashboard/src/components/layouts/marketing/base/mod.rs @@ -34,6 +34,7 @@ pub struct Base { pub alert_banner: AlertBanner, pub user: Option<User>, pub theme: Theme, + pub no_transparent_nav: bool, } impl Base { @@ -54,6 +55,7 @@ impl Base { footer, alert_banner: AlertBanner::from_notification(Notification::next_alert(context)), user, + no_transparent_nav: false, ..Default::default() } } @@ -90,6 +92,11 @@ impl Base { self } + pub fn no_transparent_nav(mut self) -> Self { + self.no_transparent_nav = true; + self + } + pub fn render<T>(mut self, template: T) -> String where T: sailfish::TemplateOnce, diff --git a/pgml-dashboard/src/components/layouts/marketing/base/template.html b/pgml-dashboard/src/components/layouts/marketing/base/template.html index 6d3387be8..e73e656c8 100644 --- a/pgml-dashboard/src/components/layouts/marketing/base/template.html +++ b/pgml-dashboard/src/components/layouts/marketing/base/template.html @@ -16,7 +16,7 @@ <main> <%+ alert_banner %> - <%+ MarketingNavbar::new(user) %> + <%+ MarketingNavbar::new(user).no_transparent_nav(no_transparent_nav) %> <%- content.unwrap_or_default() %> <%- footer.unwrap_or_default() %> diff --git a/pgml-dashboard/src/components/loading/message/mod.rs b/pgml-dashboard/src/components/loading/message/mod.rs index eabb3ea2a..399b5b877 100644 --- a/pgml-dashboard/src/components/loading/message/mod.rs +++ b/pgml-dashboard/src/components/loading/message/mod.rs @@ -1,5 +1,5 @@ -use sailfish::TemplateOnce; use pgml_components::component; +use sailfish::TemplateOnce; #[derive(TemplateOnce, Default)] #[template(path = "loading/message/template.html")] diff --git a/pgml-dashboard/src/components/modal/modal_controller.js b/pgml-dashboard/src/components/modal/modal_controller.js index 5c411dbd8..69b98eeb0 100644 --- a/pgml-dashboard/src/components/modal/modal_controller.js +++ b/pgml-dashboard/src/components/modal/modal_controller.js @@ -1,19 +1,17 @@ -import { Controller } from '@hotwired/stimulus' +import { Controller } from "@hotwired/stimulus"; export default class extends Controller { - static targets = [ - 'modal', - ]; + static targets = ["modal"]; connect() { - this.modal = new bootstrap.Modal(this.modalTarget) + this.modal = new bootstrap.Modal(this.modalTarget); } show() { - this.modal.show() + this.modal.show(); } hide() { - this.modal.hide() + this.modal.hide(); } } diff --git a/pgml-dashboard/src/components/navigation/navbar/marketing/mod.rs b/pgml-dashboard/src/components/navigation/navbar/marketing/mod.rs index 7b8df0f88..211b6e69a 100644 --- a/pgml-dashboard/src/components/navigation/navbar/marketing/mod.rs +++ b/pgml-dashboard/src/components/navigation/navbar/marketing/mod.rs @@ -9,6 +9,7 @@ pub struct Marketing { pub current_user: Option<models::User>, pub standalone_dashboard: bool, pub style_alt: bool, + pub no_transparent_nav: bool, } impl Marketing { @@ -17,6 +18,7 @@ impl Marketing { current_user: user, standalone_dashboard: config::standalone_dashboard(), style_alt: false, + no_transparent_nav: false, } } @@ -24,6 +26,11 @@ impl Marketing { self.style_alt = true; self } + + pub fn no_transparent_nav(mut self, no_transparent_nav: bool) -> Self { + self.no_transparent_nav = no_transparent_nav; + self + } } component!(Marketing); diff --git a/pgml-dashboard/src/components/navigation/navbar/marketing/template.html b/pgml-dashboard/src/components/navigation/navbar/marketing/template.html index af250f339..054a27bcc 100644 --- a/pgml-dashboard/src/components/navigation/navbar/marketing/template.html +++ b/pgml-dashboard/src/components/navigation/navbar/marketing/template.html @@ -35,7 +35,7 @@ %> <div class="sticky-top-nav" data-controller="navigation-navbar-marketing"> - <nav class='navbar-marketing-site horizontal navbar-expand-xl <% if style_alt {%><%- "alt-color"%><% } %>' data-controller='search topnav-styling' data-topnav-styling-alt-styling-value="<%- style_alt %>"> + <nav class='navbar-marketing-site horizontal navbar-expand-xl<% if style_alt {%> alt-color<% } %><% if no_transparent_nav { %> no-transparent<% } %>' data-controller='search topnav-styling' data-topnav-styling-alt-styling-value="<%- style_alt %>"> <div class='container<% if style_alt {%><%- "-fluid p-0" %><%} %> column-gap-4'> <div class="controls"> <%+ PostgresLogo::new("/") %> diff --git a/pgml-dashboard/src/components/pages/article/index/template.html b/pgml-dashboard/src/components/pages/article/index/template.html index 2521aa85d..47eee8516 100644 --- a/pgml-dashboard/src/components/pages/article/index/template.html +++ b/pgml-dashboard/src/components/pages/article/index/template.html @@ -24,6 +24,20 @@ } else { doc.title.clone() }; + + let career_apply_path = if !document_not_found{ + format!("/careers/apply/{}", doc.title.clone()) + } else { + String::from("careers") + }; + + let career_apply_url = if is_career { + let mut path = doc.url.split("/").collect::<Vec<&str>>(); + path.insert(path.len()-1, "apply"); + (path.join("/").to_string(), "Apply Now!") + } else { + (String::from("/contact"),"Contact") + }; %> <div data-controller="pages-article-index" class="tuck-under-navbar"> @@ -114,7 +128,7 @@ <h2 class="h2 mb-3">Have Questions?</h2> </div> <div class="d-flex show mt-5"> - <a class="btn btn-primary-web-app" href="/contact">Contact</a> + <a class="btn btn-primary-web-app" href="<%- career_apply_url.0 %>"><%- career_apply_url.1 %></a> </div> <% } %> </article> diff --git a/pgml-dashboard/src/components/pages/blog/blog_search/call/call_controller.js b/pgml-dashboard/src/components/pages/blog/blog_search/call/call_controller.js index 0075fab59..79a4bd368 100644 --- a/pgml-dashboard/src/components/pages/blog/blog_search/call/call_controller.js +++ b/pgml-dashboard/src/components/pages/blog/blog_search/call/call_controller.js @@ -1,57 +1,52 @@ -import { Controller } from '@hotwired/stimulus' +import { Controller } from "@hotwired/stimulus"; export default class extends Controller { - static targets = [ - 'searchFrame', - 'searchInput', - 'tagLink', - 'removeTags' - ] + static targets = ["searchFrame", "searchInput", "tagLink", "removeTags"]; - static classes = ["selected"] + static classes = ["selected"]; - static outlets = [] + static outlets = []; connect() { - this.timer - this.tags = "" + this.timer; + this.tags = ""; } search() { - clearTimeout(this.timer) + clearTimeout(this.timer); this.timer = setTimeout(() => { - this.searchFrameTarget.src = `/search_blog?query=${this.searchInputTarget.value}&tag=${this.tags}` - }, 250) + this.searchFrameTarget.src = `/search_blog?query=${this.searchInputTarget.value}&tag=${this.tags}`; + }, 250); } tag(e) { - if( e.target.classList.contains(this.selectedClass) ) { - e.target.classList.remove(this.selectedClass) - this.tags = "" - this.removeTagsTarget.classList.add(this.selectedClass) + if (e.target.classList.contains(this.selectedClass)) { + e.target.classList.remove(this.selectedClass); + this.tags = ""; + this.removeTagsTarget.classList.add(this.selectedClass); } else { - e.target.classList.add(this.selectedClass) - this.tags = e.params.tag - this.removeTagsTarget.classList.remove(this.selectedClass) + e.target.classList.add(this.selectedClass); + this.tags = e.params.tag; + this.removeTagsTarget.classList.remove(this.selectedClass); } - for( let tag of this.tagLinkTargets) { - if( tag != e.target) { - tag.classList.remove(this.selectedClass) + for (let tag of this.tagLinkTargets) { + if (tag != e.target) { + tag.classList.remove(this.selectedClass); } } - this.search() + this.search(); } removeTags() { - for( let tag of this.tagLinkTargets) { - tag.classList.remove(this.selectedClass) + for (let tag of this.tagLinkTargets) { + tag.classList.remove(this.selectedClass); } - this.removeTagsTarget.classList.add(this.selectedClass) + this.removeTagsTarget.classList.add(this.selectedClass); - this.tags = "" - this.search() + this.tags = ""; + this.search(); } } diff --git a/pgml-dashboard/src/components/pages/careers/apply/apply.scss b/pgml-dashboard/src/components/pages/careers/apply/apply.scss new file mode 100644 index 000000000..280f219c0 --- /dev/null +++ b/pgml-dashboard/src/components/pages/careers/apply/apply.scss @@ -0,0 +1 @@ +div[data-controller="pages-careers-apply"] {} diff --git a/pgml-dashboard/src/components/pages/careers/apply/apply_controller.js b/pgml-dashboard/src/components/pages/careers/apply/apply_controller.js new file mode 100644 index 000000000..4c3ce7c3d --- /dev/null +++ b/pgml-dashboard/src/components/pages/careers/apply/apply_controller.js @@ -0,0 +1,12 @@ +import { Controller } from "@hotwired/stimulus"; + +export default class extends Controller { + static targets = []; + static outlets = []; + + initialize() {} + + connect() {} + + disconnect() {} +} diff --git a/pgml-dashboard/src/components/pages/careers/apply/mod.rs b/pgml-dashboard/src/components/pages/careers/apply/mod.rs new file mode 100644 index 000000000..4d8c8a7ff --- /dev/null +++ b/pgml-dashboard/src/components/pages/careers/apply/mod.rs @@ -0,0 +1,23 @@ +use pgml_components::component; +use sailfish::TemplateOnce; + +#[derive(TemplateOnce, Default)] +#[template(path = "pages/careers/apply/template.html")] +pub struct Apply { + job_title: String, +} + +impl Apply { + pub fn new() -> Apply { + Apply { + job_title: String::from(""), + } + } + + pub fn job_title(mut self, job_title: &str) -> Apply { + self.job_title = job_title.to_owned(); + self + } +} + +component!(Apply); diff --git a/pgml-dashboard/src/components/pages/careers/apply/template.html b/pgml-dashboard/src/components/pages/careers/apply/template.html new file mode 100644 index 000000000..5eca71f87 --- /dev/null +++ b/pgml-dashboard/src/components/pages/careers/apply/template.html @@ -0,0 +1,83 @@ + +<% + use pgml_components::Component; + use crate::components::sections::Split; + use crate::components::PostgresLogo; + + let back_link = format!("/careers/{}", "job_title"); + + let eyebrow_formated = r#"<span class="text-white-300">APPLY NOW</span>"#; + + let display_area = format!(r#" + <div class="card border-1"> + <div class="card-body"> + <form action="/careers/apply" method="post"> + <div class="d-flex flex-column justify-content-center align-items-center gap-4"> + + <div class="d-flex justify-content-center"> + {} + </div> + + <div class="w-100 d-flex justify-content-start"> + <button class="btn btn-tertiary ps-0" onclick="history.back()"> + <span class="material-symbols-outlined icon-back-btn" style="font-size: 22px"> + arrow_back + </span> + Back + </button> + </div> + + <div class="d-flex flex-column gap-3"> + <div class="mb-3"> + <label class="form-label">Full Name</label> + <input class="form-control" type="text" name="name" placeholder="Owl Hootington" size="42" required> + </div> + + <div class="mb-3"> + <label class="form-label">Email</label> + <input class="form-control" type="email" name="email" placeholder="example@email.com" size="42" required> + </div> + + <div class="mb-3"> + <label class="form-label">Phone Number</label> + <input class="form-control" type="phone" name="phone" placeholder="(415)123-4567" size="42" required> + </div> + + <div class="mb-3"> + <label class="form-label">LinkedIn URL</label> + <input class="form-control" type="email" name="linkedin" placeholder="PostgresML" size="42" required> + </div> + + <div class="mb-3 w-100"> + <label class="form-label">Resume</label> + <input class="form-control" type="file" name="resume" placeholder="my_resume" required> + </div> + + <div class="mb-3"> + <label class="form-label">Github/Portfolio URL</label> + <input class="form-control" type="text" name="portfolio" placeholder="mywebsite.com" size="42"> + </div> + + <div class="mb-3 w-100"> + <label class="form-label">Note</label> + <textarea class="form-control" name="note" maxlength="1000" aria-label="With textarea" placeholder="Tell us about yourself"></textarea> + </div> + + <button class="btn btn-primary-web-app">Apply</button> + </div> + </div> + </form> + </div> + </div> + "#, + PostgresLogo::new("/").bigger().render_once().unwrap() + ); +%> + +<%+ + Split::new() + .eyebrow(Component::from(eyebrow_formated)) + .title(Component::from(job_title)) + .display_area(Component::from(display_area)) + .with_navbar() +%> diff --git a/pgml-dashboard/src/components/pages/careers/landing_page/template.html b/pgml-dashboard/src/components/pages/careers/landing_page/template.html index a9da14d45..ae0214be2 100644 --- a/pgml-dashboard/src/components/pages/careers/landing_page/template.html +++ b/pgml-dashboard/src/components/pages/careers/landing_page/template.html @@ -39,7 +39,7 @@ <h4><%- position.title%></h4> <div class="col"> <div class="card generic-card card-generic-job-position h-100"> - <a class="card-body d-flex flex-column" href="/contact"> + <a class="card-body d-flex flex-column" href="/careers/apply/generic-position"> <h4>Don't see an exact fit?</h4> <p class="text-white-300">We still want to hear from you if you’re passionate about contributing to PostgresML. Contact us.</p> <span class="material-symbols-outlined goto-arrow goto-shift-animation mt-auto ms-auto text-white">arrow_forward</span> diff --git a/pgml-dashboard/src/components/pages/careers/mod.rs b/pgml-dashboard/src/components/pages/careers/mod.rs index 4108a925b..d0b007669 100644 --- a/pgml-dashboard/src/components/pages/careers/mod.rs +++ b/pgml-dashboard/src/components/pages/careers/mod.rs @@ -1,6 +1,10 @@ // This file is automatically generated. // You shouldn't modify it manually. +// src/components/pages/careers/apply +pub mod apply; +pub use apply::Apply; + // src/components/pages/careers/landing_page pub mod landing_page; pub use landing_page::LandingPage; diff --git a/pgml-dashboard/src/components/postgres_logo/mod.rs b/pgml-dashboard/src/components/postgres_logo/mod.rs index fdeef1100..49ca8b888 100644 --- a/pgml-dashboard/src/components/postgres_logo/mod.rs +++ b/pgml-dashboard/src/components/postgres_logo/mod.rs @@ -5,11 +5,20 @@ use sailfish::TemplateOnce; #[template(path = "postgres_logo/template.html")] pub struct PostgresLogo { link: String, + bigger: bool, } impl PostgresLogo { pub fn new(link: &str) -> PostgresLogo { - PostgresLogo { link: link.to_owned() } + PostgresLogo { + link: link.to_owned(), + bigger: false, + } + } + + pub fn bigger(mut self) -> PostgresLogo { + self.bigger = true; + self } } diff --git a/pgml-dashboard/src/components/postgres_logo/template.html b/pgml-dashboard/src/components/postgres_logo/template.html index 6a0fd2ced..0d5be76dc 100644 --- a/pgml-dashboard/src/components/postgres_logo/template.html +++ b/pgml-dashboard/src/components/postgres_logo/template.html @@ -1,5 +1,12 @@ +<% + let image_dimensions = if bigger { "31" } else { "24" }; + let postgres_size = if bigger { "h4 fw-semibold" } else { "h5 fw-normal" }; + let ml_size = if bigger { "fw-bold" } else { "h5 fw-semibold" }; +%> + <a class="postgres-logo navbar-brand" href="<%- link %>"> - <img src="/dashboard/static/images/owl_gradient.svg" alt="PostgresML Logo" height="24" width="24"> - <span class="fw-normal position-relative overflow-visible">Postgres<span class="fw-semibold">ML</span> + <img src="/dashboard/static/images/owl_gradient.svg" alt="PostgresML Logo" height="<%- image_dimensions%>" width="<%- image_dimensions%>"> + <span class="position-relative overflow-visible text-white <%- postgres_size %> mb-0"> + Postgres<span class="<%- ml_size %>">ML</span> </span> </a> diff --git a/pgml-dashboard/src/components/sections/mod.rs b/pgml-dashboard/src/components/sections/mod.rs index 30bbdc9f6..90ff2249d 100644 --- a/pgml-dashboard/src/components/sections/mod.rs +++ b/pgml-dashboard/src/components/sections/mod.rs @@ -19,3 +19,7 @@ pub use have_questions::HaveQuestions; // src/components/sections/related_articles pub mod related_articles; pub use related_articles::RelatedArticles; + +// src/components/sections/split +pub mod split; +pub use split::Split; diff --git a/pgml-dashboard/src/components/sections/split/mod.rs b/pgml-dashboard/src/components/sections/split/mod.rs new file mode 100644 index 000000000..25d627f80 --- /dev/null +++ b/pgml-dashboard/src/components/sections/split/mod.rs @@ -0,0 +1,45 @@ +use pgml_components::component; +use pgml_components::Component; +use sailfish::TemplateOnce; + +#[derive(TemplateOnce, Default)] +#[template(path = "sections/split/template.html")] +pub struct Split { + eyebrow: Component, + title: Component, + display_area: Component, + with_navbar: bool, +} + +impl Split { + pub fn new() -> Split { + Split { + eyebrow: Component::from(String::from("")), + title: Component::from(String::from("")), + display_area: Component::from(String::from("")), + with_navbar: false, + } + } + + pub fn eyebrow(mut self, eyebrow: Component) -> Split { + self.eyebrow = eyebrow; + self + } + + pub fn title(mut self, title: Component) -> Split { + self.title = title; + self + } + + pub fn display_area(mut self, display_area: Component) -> Split { + self.display_area = display_area; + self + } + + pub fn with_navbar(mut self) -> Split { + self.with_navbar = true; + self + } +} + +component!(Split); diff --git a/pgml-dashboard/src/components/sections/split/split.scss b/pgml-dashboard/src/components/sections/split/split.scss new file mode 100644 index 000000000..6ec9fc6f4 --- /dev/null +++ b/pgml-dashboard/src/components/sections/split/split.scss @@ -0,0 +1,92 @@ +div[data-controller="sections-split"] { + .greeting { + margin-left: 3vw; + margin-right: 3vw; + @include media-breakpoint-up(lg) { + margin-left: 10vw; + } + } + + .signup-left { + background: #{$gray-700}; + } + + .signup-right { + position: relative; + background-color: #{$gray-800}; + overflow: hidden; + min-height: 100vh; + + .card { + max-width: 30rem; + } + } + + .left-center-navbar { + top: 88px; + height: 100%; + max-height: calc( 100vh - 88px ); + } + + .left-center { + top: 0px; + height: 100%; + max-height: 100vh; + } + + .glow-1 { + overflow: hidden; + left: 50%; + top: 65%; + position: absolute; + width: 1329.767px; + height: 602.685px; + transform: rotate(-47.563deg); + flex-shrink: 0; + border-radius: 1329.767px; + background: radial-gradient(76.18% 64.48% at 55.97% 35.8%, rgba(255, 152, 214, 0.60) 0%, rgba(26, 6, 255, 0.60) 73.96%); + filter: blur(168.74745178222656px); + } + + .glow-2 { + overflow: hidden; + left: 50%; + top: 65%; + position: absolute; + width: 521.519px; + height: 665.196px; + transform: rotate(-138.124deg); + flex-shrink: 0; + border-radius: 665.196px; + background: radial-gradient(55.54% 61.91% at 93.5% 14.5%, rgba(66, 132, 199, 0.40) 0%, rgba(152, 203, 255, 0.40) 100%); + filter: blur(112.498291015625px); + } + + .glow-3 { + overflow: hidden; + left: 50%; + top: 65%; + position: absolute; + width: 608.173px; + height: 456.083px; + transform: rotate(-39.836deg); + flex-shrink: 0; + border-radius: 608.173px; + background: radial-gradient(50% 50% at 50% 50%, #8B44FF 0%, #FF783F 100%); + filter: blur(168.74745178222656px); + } + + .glow-4 { + overflow: hidden; + left: 50%; + top: 65%; + position: absolute; + width: 726.853px; + height: 371.406px; + transform: rotate(-59.934deg); + flex-shrink: 0; + border-radius: 726.853px; + background: radial-gradient(46.38% 45.17% at 22.72% 36.9%, rgba(85, 66, 199, 0.60) 26.4%, rgba(174, 110, 255, 0.60) 100%); + filter: blur(224.99658203125px); + } +} diff --git a/pgml-dashboard/src/components/sections/split/split_controller.js b/pgml-dashboard/src/components/sections/split/split_controller.js new file mode 100644 index 000000000..f7872801a --- /dev/null +++ b/pgml-dashboard/src/components/sections/split/split_controller.js @@ -0,0 +1,14 @@ +import { Controller } from "@hotwired/stimulus"; + +export default class extends Controller { + static targets = []; + static outlets = []; + + initialize() { + console.log("Initialized sections-split"); + } + + connect() {} + + disconnect() {} +} diff --git a/pgml-dashboard/src/components/sections/split/template.html b/pgml-dashboard/src/components/sections/split/template.html new file mode 100644 index 000000000..4895b8967 --- /dev/null +++ b/pgml-dashboard/src/components/sections/split/template.html @@ -0,0 +1,47 @@ +<% + use pgml_components::Component; + + + let greeting = format!(r#" + <div class="py-5 text-center text-lg-start greeting"> + <h6 class="h6 text-uppercase mb-0"> + <small class="eyebrow-text"> + {} + </small> + </h6> + <h2 class="display-1 fw-bold" style="text-transform: capitalize"> + {} + </h2> + </div> + "#, + eyebrow.render_once().unwrap(), + title.render_once().unwrap()); + + +%> + +<div data-controller="sections-split" class="min-vh-lg-100"> + <div class="row h-100 min-vh-lg-100 gx-0"> + <!-- left --> + <div class="col-6 d-none d-lg-block min-vh-lg-100"> + <div class="d-flex flex-column min-vh-lg-100 signup-left" style="height: 100%;"> + <div class="d-flex flex-column position-sticky justify-content-center left-center<% if with_navbar {%>-navbar<% } %>"> + <%+ Component::from(greeting.clone()) %> + </div> + </div> + </div> + + <!-- right --> + <div class="col-12 col-lg-6 min-vh-lg-100"> + <div class="d-flex flex-column align-items-center justify-content-center min-vh-lg-100 signup-right pt-lg-5 pt-0 pb-5 px-3"> + <div class="glow-1"></div> + <div class="glow-2"></div> + <div class="glow-3"></div> + <div class="glow-4"></div> + <div class="d-flex d-lg-none"><%+ Component::from(greeting) %></div> + + <%+ display_area %> + </div> + </div> + </div> +</div> diff --git a/pgml-dashboard/src/components/static_nav/static_nav_controller.js b/pgml-dashboard/src/components/static_nav/static_nav_controller.js index 94a144f92..eaa1df5b4 100644 --- a/pgml-dashboard/src/components/static_nav/static_nav_controller.js +++ b/pgml-dashboard/src/components/static_nav/static_nav_controller.js @@ -1,11 +1,11 @@ -import { Controller } from '@hotwired/stimulus' +import { Controller } from "@hotwired/stimulus"; export default class extends Controller { - static targets = [] - static outlets = [] + static targets = []; + static outlets = []; initialize() { - console.log('Initialized static-nav') + console.log("Initialized static-nav"); } connect() {} diff --git a/pgml-dashboard/src/components/tables/large/table/table_controller.js b/pgml-dashboard/src/components/tables/large/table/table_controller.js index 7ad631e22..c535f6436 100644 --- a/pgml-dashboard/src/components/tables/large/table/table_controller.js +++ b/pgml-dashboard/src/components/tables/large/table/table_controller.js @@ -1,10 +1,10 @@ -import { Controller } from '@hotwired/stimulus' +import { Controller } from "@hotwired/stimulus"; export default class extends Controller { - static targets = ['row'] + static targets = ["row"]; selectRow(event) { - this.rowTargets.forEach(row => row.classList.remove('active')) - event.currentTarget.classList.add('active') + this.rowTargets.forEach((row) => row.classList.remove("active")); + event.currentTarget.classList.add("active"); } } diff --git a/pgml-dashboard/static/css/modules.scss b/pgml-dashboard/static/css/modules.scss index 71d508af8..bdc59774e 100644 --- a/pgml-dashboard/static/css/modules.scss +++ b/pgml-dashboard/static/css/modules.scss @@ -35,6 +35,7 @@ @import "../../src/components/pages/blog/blog_search/call/call.scss"; @import "../../src/components/pages/blog/blog_search/response/response.scss"; @import "../../src/components/pages/blog/landing_page/landing_page.scss"; +@import "../../src/components/pages/careers/apply/apply.scss"; @import "../../src/components/pages/careers/landing_page/landing_page.scss"; @import "../../src/components/pages/docs/article/article.scss"; @import "../../src/components/pages/docs/landing_page/landing_page.scss"; @@ -45,6 +46,7 @@ @import "../../src/components/sections/footers/marketing_footer/marketing_footer.scss"; @import "../../src/components/sections/have_questions/have_questions.scss"; @import "../../src/components/sections/related_articles/related_articles.scss"; +@import "../../src/components/sections/split/split.scss"; @import "../../src/components/star/star.scss"; @import "../../src/components/static_nav/static_nav.scss"; @import "../../src/components/tables/large/row/row.scss"; diff --git a/pgml-dashboard/static/css/scss/components/_navs.scss b/pgml-dashboard/static/css/scss/components/_navs.scss index 0fe957839..fb3090106 100644 --- a/pgml-dashboard/static/css/scss/components/_navs.scss +++ b/pgml-dashboard/static/css/scss/components/_navs.scss @@ -24,7 +24,7 @@ --bs-navbar-padding-x: 20px; min-height: $navbar-height; - &.pinned { + &.pinned, &.no-transparent { background: #{$gray-900}; } From 326e6c28a9fde4d9d3856e36007171316b1b6b0d Mon Sep 17 00:00:00 2001 From: Dan <39170265+chillenberger@users.noreply.github.com> Date: Tue, 12 Mar 2024 08:24:12 -0600 Subject: [PATCH 2/4] remove dead code, add turbo-frame for career form fail and success, use new split page --- pgml-dashboard/src/api/cms.rs | 2 +- .../pages/article/index/template.html | 6 - .../src/components/pages/careers/apply/mod.rs | 7 + .../pages/careers/apply/template.html | 144 +++++++++++------- 4 files changed, 95 insertions(+), 64 deletions(-) diff --git a/pgml-dashboard/src/api/cms.rs b/pgml-dashboard/src/api/cms.rs index af41f96a1..0a58f3b33 100644 --- a/pgml-dashboard/src/api/cms.rs +++ b/pgml-dashboard/src/api/cms.rs @@ -775,7 +775,7 @@ async fn get_careers( #[get("/careers/apply/<title>", rank = 4)] pub async fn careers_apply(title: PathBuf, cluster: &Cluster) -> Result<ResponseOk, crate::responses::NotFound> { - let mut layout = + let layout = crate::components::layouts::marketing::Base::new("Apply for a career", Some(&cluster)).no_transparent_nav(); let job_title = title.display().to_string().replace("-", " "); diff --git a/pgml-dashboard/src/components/pages/article/index/template.html b/pgml-dashboard/src/components/pages/article/index/template.html index 47eee8516..f492fe783 100644 --- a/pgml-dashboard/src/components/pages/article/index/template.html +++ b/pgml-dashboard/src/components/pages/article/index/template.html @@ -25,12 +25,6 @@ doc.title.clone() }; - let career_apply_path = if !document_not_found{ - format!("/careers/apply/{}", doc.title.clone()) - } else { - String::from("careers") - }; - let career_apply_url = if is_career { let mut path = doc.url.split("/").collect::<Vec<&str>>(); path.insert(path.len()-1, "apply"); diff --git a/pgml-dashboard/src/components/pages/careers/apply/mod.rs b/pgml-dashboard/src/components/pages/careers/apply/mod.rs index 4d8c8a7ff..d75a91b4a 100644 --- a/pgml-dashboard/src/components/pages/careers/apply/mod.rs +++ b/pgml-dashboard/src/components/pages/careers/apply/mod.rs @@ -5,12 +5,14 @@ use sailfish::TemplateOnce; #[template(path = "pages/careers/apply/template.html")] pub struct Apply { job_title: String, + success: Option<bool>, } impl Apply { pub fn new() -> Apply { Apply { job_title: String::from(""), + success: None, } } @@ -18,6 +20,11 @@ impl Apply { self.job_title = job_title.to_owned(); self } + + pub fn success(mut self, success: bool) -> Apply { + self.success = Some(success); + self + } } component!(Apply); diff --git a/pgml-dashboard/src/components/pages/careers/apply/template.html b/pgml-dashboard/src/components/pages/careers/apply/template.html index 5eca71f87..eb864cd24 100644 --- a/pgml-dashboard/src/components/pages/careers/apply/template.html +++ b/pgml-dashboard/src/components/pages/careers/apply/template.html @@ -3,75 +3,105 @@ use pgml_components::Component; use crate::components::sections::Split; use crate::components::PostgresLogo; - - let back_link = format!("/careers/{}", "job_title"); + use crate::utils::config::site_domain; let eyebrow_formated = r#"<span class="text-white-300">APPLY NOW</span>"#; - let display_area = format!(r#" - <div class="card border-1"> - <div class="card-body"> - <form action="/careers/apply" method="post"> - <div class="d-flex flex-column justify-content-center align-items-center gap-4"> + let path = format!("/careers/apply/{}",job_title.replace(" ", "-").to_lowercase()); + + let form = format!(r#" + <form action="{}" method="post" enctype="multipart/form-data"> + <div class="d-flex flex-column justify-content-center align-items-center gap-4"> + + <div class="d-flex justify-content-center"> + {} + </div> + + <div class="w-100 d-flex justify-content-start"> + <button class="btn btn-tertiary ps-0" onclick="history.back()"> + <span class="material-symbols-outlined icon-back-btn" style="font-size: 22px"> + arrow_back + </span> + Back + </button> + </div> - <div class="d-flex justify-content-center"> - {} + <div class="d-flex flex-column gap-3"> + <div class="mb-3"> + <label class="form-label">Full Name</label> + <input class="form-control" type="text" name="name" placeholder="Owl Hootington" size="42" required> </div> - <div class="w-100 d-flex justify-content-start"> - <button class="btn btn-tertiary ps-0" onclick="history.back()"> - <span class="material-symbols-outlined icon-back-btn" style="font-size: 22px"> - arrow_back - </span> - Back - </button> + <div class="mb-3"> + <label class="form-label">Email</label> + <input class="form-control" type="email" name="email" placeholder="example@email.com" size="42" required> </div> - <div class="d-flex flex-column gap-3"> - <div class="mb-3"> - <label class="form-label">Full Name</label> - <input class="form-control" type="text" name="name" placeholder="Owl Hootington" size="42" required> - </div> - - <div class="mb-3"> - <label class="form-label">Email</label> - <input class="form-control" type="email" name="email" placeholder="example@email.com" size="42" required> - </div> - - <div class="mb-3"> - <label class="form-label">Phone Number</label> - <input class="form-control" type="phone" name="phone" placeholder="(415)123-4567" size="42" required> - </div> - - <div class="mb-3"> - <label class="form-label">LinkedIn URL</label> - <input class="form-control" type="email" name="linkedin" placeholder="PostgresML" size="42" required> - </div> - - <div class="mb-3 w-100"> - <label class="form-label">Resume</label> - <input class="form-control" type="file" name="resume" placeholder="my_resume" required> - </div> - - <div class="mb-3"> - <label class="form-label">Github/Portfolio URL</label> - <input class="form-control" type="text" name="portfolio" placeholder="mywebsite.com" size="42"> - </div> - - <div class="mb-3 w-100"> - <label class="form-label">Note</label> - <textarea class="form-control" name="note" maxlength="1000" aria-label="With textarea" placeholder="Tell us about yourself"></textarea> - </div> - - <button class="btn btn-primary-web-app">Apply</button> + <div class="mb-3"> + <label class="form-label">Phone Number</label> + <input class="form-control" type="phone" name="phone" placeholder="(415)123-4567" size="42"> + </div> + + <div class="mb-3"> + <label class="form-label">LinkedIn URL</label> + <input class="form-control" type="linkedin" name="linkedin" placeholder="PostgresML" size="42"> </div> + + <div class="mb-3 w-100"> + <label class="form-label">Resume <span class="legal-text text-white-300">(.pdf)</span></label> + <input class="form-control" type="file" name="resume" accept=".pdf" required="true" placeholder=".pdf"> + </div> + + <div class="mb-3"> + <label class="form-label">Github/Portfolio URL</label> + <input class="form-control" type="text" name="portfolio" placeholder="mywebsite.com" size="42"> + </div> + + <div class="mb-3 w-100"> + <label class="form-label">Note</label> + <textarea class="form-control" name="note" maxlength="1000" aria-label="With textarea" placeholder="Tell us about yourself"></textarea> + </div> + + <input type="hidden" name="position" value="{}"> + + <button class="btn btn-primary-web-app" type="submit">Apply</button> </div> - </form> + </div> + </form> + "#, + path, + PostgresLogo::new("/").bigger().render_once().unwrap(), + job_title + ); + + let success_message = format!(r#" + <div class="d-flex flex-column gap-2 p-2"> + <p class="text-center">You have successfully applied for the <span class="text-capitalize">{}</span> role! We’ll be in contract with you shortly. </p> + <a class="btn btn-primary-web-app mx-auto" href="/careers" data-turbo-frame="_top">Careers</a> + </div> + "#, job_title); + + let failure_message = format!(r#" + <div class="d-flex flex-column gap-2 p-2"> + <p class="text-center">Something went wrong!</p> + <a class="btn btn-primary-web-app mx-auto" href="/careers" data-turbo-frame="_top">Careers</a> + </div> + "#); + + let display_area = format!(r#" + <div class="card border-1"> + <div class="card-body"> + <turbo-frame id="career-display-area"> + {} + </turbo-frame> </div> </div> - "#, - PostgresLogo::new("/").bigger().render_once().unwrap() - ); + "#, + match success { + Some(true) => &success_message, + Some(false) => &failure_message, + None => &form + }); %> <%+ From 6e3a012eeca0921352c0af5f6deec064fdc62277 Mon Sep 17 00:00:00 2001 From: Dan <39170265+chillenberger@users.noreply.github.com> Date: Tue, 12 Mar 2024 09:38:57 -0600 Subject: [PATCH 3/4] fix split section height, remove dead code --- .../pages/careers/apply/apply_controller.js | 12 ------- .../src/components/sections/split/split.scss | 31 +++++++++++++++++-- .../sections/split/split_controller.js | 14 --------- .../components/sections/split/template.html | 16 +++++----- 4 files changed, 36 insertions(+), 37 deletions(-) delete mode 100644 pgml-dashboard/src/components/pages/careers/apply/apply_controller.js delete mode 100644 pgml-dashboard/src/components/sections/split/split_controller.js diff --git a/pgml-dashboard/src/components/pages/careers/apply/apply_controller.js b/pgml-dashboard/src/components/pages/careers/apply/apply_controller.js deleted file mode 100644 index 4c3ce7c3d..000000000 --- a/pgml-dashboard/src/components/pages/careers/apply/apply_controller.js +++ /dev/null @@ -1,12 +0,0 @@ -import { Controller } from "@hotwired/stimulus"; - -export default class extends Controller { - static targets = []; - static outlets = []; - - initialize() {} - - connect() {} - - disconnect() {} -} diff --git a/pgml-dashboard/src/components/sections/split/split.scss b/pgml-dashboard/src/components/sections/split/split.scss index 6ec9fc6f4..d4c03751d 100644 --- a/pgml-dashboard/src/components/sections/split/split.scss +++ b/pgml-dashboard/src/components/sections/split/split.scss @@ -34,6 +34,11 @@ div[data-controller="sections-split"] { max-height: 100vh; } + .right-center-navbar { + height: 100%; + min-height: calc( 100vh - 88px ); + } + .glow-1 { overflow: hidden; left: 50%; @@ -77,16 +82,38 @@ div[data-controller="sections-split"] { } .glow-4 { - overflow: hidden; left: 50%; top: 65%; - position: absolute; width: 726.853px; height: 371.406px; + overflow: hidden; + position: absolute; transform: rotate(-59.934deg); flex-shrink: 0; border-radius: 726.853px; background: radial-gradient(46.38% 45.17% at 22.72% 36.9%, rgba(85, 66, 199, 0.60) 26.4%, rgba(174, 110, 255, 0.60) 100%); filter: blur(224.99658203125px); } + + .glow-5 { + overflow: hidden; + position: absolute; + left: 50%; + top: -75px; + width: 121.519px; + height: 265.196px; + transform: rotate(-138.124deg); + flex-shrink: 0; + border-radius: 665.196px; + background: radial-gradient(55.54% 61.91% at 93.5% 14.5%, rgba(66, 132, 199, 0.40) 0%, rgba(152, 203, 255, 0.40) 100%); + filter: blur(112.498291015625px); + + @include media-breakpoint-up(md) { + left: 50%; + top: -10%; + width: 321.519px; + height: 465.196px; + } + } + } diff --git a/pgml-dashboard/src/components/sections/split/split_controller.js b/pgml-dashboard/src/components/sections/split/split_controller.js deleted file mode 100644 index f7872801a..000000000 --- a/pgml-dashboard/src/components/sections/split/split_controller.js +++ /dev/null @@ -1,14 +0,0 @@ -import { Controller } from "@hotwired/stimulus"; - -export default class extends Controller { - static targets = []; - static outlets = []; - - initialize() { - console.log("Initialized sections-split"); - } - - connect() {} - - disconnect() {} -} diff --git a/pgml-dashboard/src/components/sections/split/template.html b/pgml-dashboard/src/components/sections/split/template.html index 4895b8967..3e1a1bb4a 100644 --- a/pgml-dashboard/src/components/sections/split/template.html +++ b/pgml-dashboard/src/components/sections/split/template.html @@ -1,7 +1,6 @@ <% use pgml_components::Component; - let greeting = format!(r#" <div class="py-5 text-center text-lg-start greeting"> <h6 class="h6 text-uppercase mb-0"> @@ -16,15 +15,13 @@ <h2 class="display-1 fw-bold" style="text-transform: capitalize"> "#, eyebrow.render_once().unwrap(), title.render_once().unwrap()); - - %> -<div data-controller="sections-split" class="min-vh-lg-100"> - <div class="row h-100 min-vh-lg-100 gx-0"> +<div data-controller="sections-split" class=""> + <div class="row h-100 gx-0"> <!-- left --> - <div class="col-6 d-none d-lg-block min-vh-lg-100"> - <div class="d-flex flex-column min-vh-lg-100 signup-left" style="height: 100%;"> + <div class="col-6 d-none d-lg-block"> + <div class="d-flex flex-column signup-left" style="height: 100%;"> <div class="d-flex flex-column position-sticky justify-content-center left-center<% if with_navbar {%>-navbar<% } %>"> <%+ Component::from(greeting.clone()) %> </div> @@ -32,12 +29,13 @@ <h2 class="display-1 fw-bold" style="text-transform: capitalize"> </div> <!-- right --> - <div class="col-12 col-lg-6 min-vh-lg-100"> - <div class="d-flex flex-column align-items-center justify-content-center min-vh-lg-100 signup-right pt-lg-5 pt-0 pb-5 px-3"> + <div class="col-12 col-lg-6 "> + <div class="d-flex flex-column align-items-center justify-content-center signup-right pt-lg-5 pt-0 pb-5 px-3 right-center<% if with_navbar {%>-navbar<% } %>"> <div class="glow-1"></div> <div class="glow-2"></div> <div class="glow-3"></div> <div class="glow-4"></div> + <div class="glow-5"></div> <div class="d-flex d-lg-none"><%+ Component::from(greeting) %></div> <%+ display_area %> From 92aca28765ac6860a77a34168358d7741e144bfd Mon Sep 17 00:00:00 2001 From: Dan <39170265+chillenberger@users.noreply.github.com> Date: Tue, 12 Mar 2024 09:53:15 -0600 Subject: [PATCH 4/4] remove unused import --- pgml-dashboard/src/components/pages/careers/apply/template.html | 1 - 1 file changed, 1 deletion(-) diff --git a/pgml-dashboard/src/components/pages/careers/apply/template.html b/pgml-dashboard/src/components/pages/careers/apply/template.html index eb864cd24..5343e2e25 100644 --- a/pgml-dashboard/src/components/pages/careers/apply/template.html +++ b/pgml-dashboard/src/components/pages/careers/apply/template.html @@ -3,7 +3,6 @@ use pgml_components::Component; use crate::components::sections::Split; use crate::components::PostgresLogo; - use crate::utils::config::site_domain; let eyebrow_formated = r#"<span class="text-white-300">APPLY NOW</span>"#;