Skip to content

Commit

Permalink
Merge pull request #8 from upmaru/feature/mobile-nav-for-pricing-matrix
Browse files Browse the repository at this point in the history
Setup mobile nav for pricing matrix
  • Loading branch information
zacksiri authored Dec 25, 2024
2 parents 78c8886 + 60b8da6 commit 7aa5d8b
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 22 deletions.
2 changes: 1 addition & 1 deletion assets/components/categories.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from 'react'
import React from 'react'
import { Menu, MenuButton, MenuItem, MenuItems } from '@headlessui/react'
import {
CheckIcon,
Expand Down
17 changes: 1 addition & 16 deletions assets/components/commands.jsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,7 @@
import React, { useState, useEffect } from 'react'
import { createRoot } from "react-dom/client";
import { createRoot } from "react-dom/client"
import { motion, useAnimate, stagger } from 'framer-motion'

const container = {
hidden: { opacity: 0 },
show: {
opacity: 1,
transition: {
staggerChildren: 0.1
}
}
}

const character = {
hidden: { opacity: 0 },
show: { opacity: 1 }
}

const tabs = [
{
title: 'Logs',
Expand Down
47 changes: 47 additions & 0 deletions assets/components/products.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from 'react'
import { createRoot } from "react-dom/client"
import { Menu, MenuButton, MenuItem, MenuItems } from '@headlessui/react'
import {
CheckIcon,
ChevronUpDownIcon,
} from '@heroicons/react/16/solid'

function Products({ products, interval, selected }) {
return (
<Menu>
<MenuButton className="flex items-center justify-between gap-2 font-medium">
{products.find(({ reference }) => reference === selected)?.name || products[0].name}
<ChevronUpDownIcon className="size-4 fill-slate-900" />
</MenuButton>
<MenuItems
anchor="bottom start"
className="min-w-40 rounded-lg bg-white p-1 shadow-lg ring-1 ring-gray-200 [--anchor-gap:6px] [--anchor-offset:-4px] [--anchor-padding:10px]"
>
{products.map((product) => (
<MenuItem key={`product-${product.index}`}>
<a
href={`/our-product/pricing?interval=${interval}&product=${product.reference}`}
data-phx-link="patch"
data-phx-link-state="push"
data-selected={product.reference === selected ? true : undefined}
className="group grid grid-cols-[16px,1fr] items-center gap-2 rounded-md px-2 py-1 data-[focus]:bg-gray-950/5"
>
<CheckIcon className="hidden size-4 group-data-[selected]:block" />
<p className="col-start-2 text-sm/6">{product.name}</p>
</a>
</MenuItem>
))}
</MenuItems>
</Menu>
)
}

export function mountProducts() {
const domNode = this.el;
const root = createRoot(domNode);
let { products, interval, selected } = this.el.dataset;

products = JSON.parse(products);

root.render(<Products products={products} interval={interval} selected={selected} />)
}
6 changes: 6 additions & 0 deletions assets/js/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import { Technologies } from '../components/technologies';
import { SSHAccess } from '../components/access';
import { Timeline } from '../components/rollback';
import { mountCommands } from '../components/commands';
import { mountProducts } from '../components/products';

function mountTimeline() {
const domNode = this.el;
Expand Down Expand Up @@ -169,6 +170,11 @@ Hooks.MountCategories = {
updated: mountCategories,
}

Hooks.MountProducts = {
mounted: mountProducts,
updated: mountProducts,
}

let csrfToken = document
.querySelector("meta[name='csrf-token']")
.getAttribute("content");
Expand Down
2 changes: 2 additions & 0 deletions lib/opsmaru/content/product.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ defmodule Opsmaru.Content.Product do
use Ecto.Schema
import Ecto.Changeset

@derive {Jason.Encoder, only: [:index, :reference, :name]}

@valid_attrs ~w(id index reference name)a

embedded_schema do
Expand Down
10 changes: 9 additions & 1 deletion lib/opsmaru_web/components/pricing_components.ex
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ defmodule OpsmaruWeb.PricingComponents do
attr :products, :list, required: true
attr :features, :list, required: true
attr :product_features, :list, required: true
attr :focus_product, :string, default: nil

def matrix(assigns) do
~H"""
Expand All @@ -120,19 +121,26 @@ defmodule OpsmaruWeb.PricingComponents do
</th>
<.display
:for={product <- @products}
product={product}
feature={feature}
focus_product={@focus_product}
product_feature={match_product_feature(@product_features, product, feature)}
/>
</tr>
"""
end

attr :feature, Content.Feature, required: true
attr :product, Content.Product, required: true
attr :product_feature, Products.Feature, default: nil
attr :focus_product, :string, default: nil

def display(assigns) do
~H"""
<td class="p-4 data-[selected]:table-cell max-sm:hidden">
<td
data-selected={"#{@focus_product == @product.reference}"}
class="p-4 data-[selected='true']:table-cell max-sm:hidden"
>
<div :if={@feature.display == "remark" && @product_feature} class="text-sm/6">
{@product_feature.remark}
</div>
Expand Down
2 changes: 1 addition & 1 deletion lib/opsmaru_web/live/blog_live/index.ex
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ defmodule OpsmaruWeb.BlogLive.Index do
<div class="flex flex-wrap items-center justify-between gap-2">
<div
id="categories"
data-categories={Jason.encode!(@categories)}
data-categories={Jason.encode_to_iodata!(@categories)}
data-selected={@category}
phx-hook="MountCategories"
>
Expand Down
22 changes: 19 additions & 3 deletions lib/opsmaru_web/live/pricing_live.ex
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ defmodule OpsmaruWeb.PricingLive do
attr :main_nav, Content.Navigation, required: true
attr :interval, :string, default: "month"
attr :products, :list, default: []
attr :focus_product, :string, default: nil

def render(assigns) do
~H"""
Expand Down Expand Up @@ -124,7 +125,15 @@ defmodule OpsmaruWeb.PricingLive do
</tr>
<tr class="sm:hidden">
<td class="p-0">
<div class="relative inline-block"></div>
<div
id="products-mobile-nav"
class="relative inline-block"
data-products={Jason.encode_to_iodata!(@products)}
data-interval={@interval}
data-selected={@focus_product}
phx-hook="MountProducts"
>
</div>
</td>
<td class="p-0 text-right">
<.link
Expand Down Expand Up @@ -162,6 +171,7 @@ defmodule OpsmaruWeb.PricingLive do
</tr>
<PricingComponents.matrix
products={@products}
focus_product={@focus_product}
features={category.features}
product_features={@product_features}
/>
Expand Down Expand Up @@ -219,7 +229,7 @@ defmodule OpsmaruWeb.PricingLive do
end

@impl true
def handle_params(%{"interval" => interval}, _uri, %{assigns: assigns} = socket) do
def handle_params(%{"interval" => interval} = params, _uri, %{assigns: assigns} = socket) do
prices = load_prices(interval)

active_products_names = Enum.map(prices, & &1.product.name)
Expand All @@ -232,16 +242,19 @@ defmodule OpsmaruWeb.PricingLive do
product.reference in active_products_names
end)

focus_product = Map.get(params, "product", List.first(products).reference)

socket =
socket
|> assign(:prices, prices)
|> assign(:interval, interval)
|> assign(:products, products)
|> assign(:focus_product, focus_product)

{:noreply, socket}
end

def handle_params(_, _uri, %{assigns: assigns} = socket) do
def handle_params(params, _uri, %{assigns: assigns} = socket) do
prices = load_prices()
active_products_names = Enum.map(prices, & &1.product.name)

Expand All @@ -253,11 +266,14 @@ defmodule OpsmaruWeb.PricingLive do
product.reference in active_products_names
end)

focus_product = Map.get(params, "product", List.first(products).reference)

socket =
socket
|> assign(:prices, prices)
|> assign(:interval, "month")
|> assign(:products, products)
|> assign(:focus_product, focus_product)

{:noreply, socket}
end
Expand Down

0 comments on commit 7aa5d8b

Please sign in to comment.