chore: remove tailwind

I prefer plain css files over tailwind.

I converted some default components,
but it's still a work in progress.
This commit is contained in:
Ivan R. 2024-07-06 21:25:42 +05:00
parent c80f439840
commit c6de8dce34
Signed by: lumin
GPG key ID: E0937DC7CD6D3817
11 changed files with 481 additions and 182 deletions

View file

@ -1,5 +1,48 @@
@import "tailwindcss/base"; @import "./core_components.css";
@import "tailwindcss/components";
@import "tailwindcss/utilities";
/* This file is for your main application CSS */ :root {
--bg: #13151a;
--accent: #b283e5;
}
html {
font-family: Georgia, serif;
background-color: var(--bg);
background-size: 224px;
color: white;
font-size: 16px;
}
*::selection {
background-color: var(--accent);
color: var(--bg);
}
a {
color: var(--accent);
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
h1 {
margin-top: 36px;
margin-bottom: 24px;
}
h2 {
margin-top: 32px;
}
header,
main,
footer {
justify-content: center;
}
.limiter {
max-width: 800px;
width: 100%;
margin: auto;
}

View file

@ -0,0 +1,363 @@
.label {
display: block;
font-size: 0.875rem;
font-weight: 600;
line-height: 1.5rem;
}
.error {
display: flex;
margin-top: 0.75rem;
font-size: 0.875rem;
line-height: 1.5rem;
gap: 0.75rem;
}
.list {
margin-top: 3.5rem;
}
.list-description {
margin-top: -1rem;
margin-bottom: -1rem;
border-top-width: 1px;
}
.list-item {
display: flex;
padding-top: 1rem;
padding-bottom: 1rem;
font-size: 0.875rem;
line-height: 1.5rem;
gap: 1rem;
}
@media (min-width: 640px) {
.list-item {
gap: 2rem;
}
}
.list-item-title {
flex: none;
width: 25%;
}
.list-item-description {
}
.modal {
display: none;
position: relative;
z-index: 50;
}
.modal-bg {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
transition-property: opacity;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 300ms;
}
.modal-body {
overflow-y: auto;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
padding: 1rem;
width: 100%;
max-width: 48rem;
}
@media (min-width: 640px) {
.modal-body {
padding: 1.5rem;
}
}
@media (min-width: 1024px) {
.modal-body {
padding-top: 2rem;
padding-bottom: 2rem;
}
}
.modal-close-button-container {
position: absolute;
right: 1.25rem;
top: 1.5rem;
}
.modal-close-button {
padding: 0.75rem;
margin: -0.75rem;
flex: none;
opacity: 0.2;
}
.modal-close-button:hover {
opacity: 0.4;
}
.modal-close-button-icon {
width: 1.25rem;
height: 1.25rem;
}
.modal-container {
display: none;
position: relative;
padding: 3.5rem;
border-radius: 1rem;
box-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
background-color: #ffffff;
transition-property: background-color, border-color, color, fill, stroke, opacity, box-shadow, transform;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 300ms;
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
}
.flash {
position: fixed;
top: 0.5rem;
right: 0.5rem;
z-index: 50;
padding: 0.75rem;
margin-right: 0.5rem;
border-radius: 0.5rem;
box-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
width: 20rem;
}
@media (min-width: 640px) {
.flash {
width: 24rem;
}
}
.flash-title {
display: flex;
gap: 0.375rem;
align-items: center;
font-size: 0.875rem;
font-weight: 600;
line-height: 1.5rem;
}
.flash-close-button {
position: absolute;
top: 0.25rem;
right: 0.25rem;
padding: 0.5rem;
}
.flash-close-button-icon {
width: 1.25rem;
height: 1.25rem;
opacity: 0.4;
}
.simple-form {
margin-top: 2rem;
background-color: #ffffff;
}
.simple-form-action {
display: flex;
margin-top: 0.5rem;
gap: 1.5rem;
justify-content: space-between;
align-items: center;
}
.button {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
padding-left: 0.75rem;
padding-right: 0.75rem;
border-radius: 0.5rem;
font-size: 0.875rem;
font-weight: 600;
line-height: 1.5rem;
color: #ffffff;
}
.input {
display: block;
margin-top: 0.5rem;
border-radius: 0.5rem;
width: 100%;
}
@media (min-width: 640px) {
.input {
font-size: 0.875rem;
line-height: 1.5rem;
}
}
.textarea {
display: block;
margin-top: 0.5rem;
border-radius: 0.5rem;
width: 100%;
}
@media (min-width: 640px) {
.textarea {
font-size: 0.875rem;
line-height: 1.5rem;
}
}
.select {
display: block;
margin-top: 0.5rem;
border-radius: 0.375rem;
border-width: 1px;
border-color: #D1D5DB;
width: 100%;
background-color: #ffffff;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
}
@media (min-width: 640px) {
.select {
font-size: 0.875rem;
line-height: 1.25rem;
}
}
.checkbox-label {
display: flex;
gap: 1rem;
align-items: center;
font-size: 0.875rem;
line-height: 1.5rem;
}
.checkbox-input {
border-radius: 0.25rem;
}
.show {
transition-property: all;
transition-duration: 300ms;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
--transform-translate-y: 1rem;
opacity: 0;
opacity: 1;
}
@media (min-width: 640px) {
.show {
--transform-scale-x: 1;
--transform-scale-y: 1;
--transform-translate-y: 0;
}
}
.hide {
transition-property: all;
transition-duration: 300ms;
transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
--transform-translate-y: 1rem;
opacity: 0;
opacity: 1;
}
@media (min-width: 640px) {
.hide {
--transform-scale-x: .95;
--transform-scale-y: .95;
--transform-translate-y: 0;
}
}
.show-modal {
transition-property: all;
transition-duration: 300ms;
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
}
.hide-modal {
transition-property: all;
transition-duration: 200ms;
transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
opacity: 1;
}
.back-nav-link {
font-size: 0.875rem;
line-height: 1.25rem;
font-weight: 600;
line-height: 1.5rem;
}
.table-container {
overflow-y: auto;
padding-left: 1rem;
padding-right: 1rem;
}
@media (min-width: 640px) {
.table-container {
overflow: visible;
padding-left: 0;
padding-right: 0;
}
}
.table {
margin-top: 2.75rem;
width: 40rem;
}
@media (min-width: 640px) {
.table {
width: 100%;
}
}
.thead {
font-size: 0.875rem;
line-height: 1.25rem;
line-height: 1.5rem;
text-align: left;
}
.th {
padding: 0;
padding-bottom: 1rem;
padding-right: 1.5rem;
font-weight: 400;
}
.th-actions {
position: relative;
padding: 0;
padding-bottom: 1rem;
}
.tbody {
position: relative;
border-top-width: 1px;
border-top-width: 1px;
font-size: 0.875rem;
line-height: 1.25rem;
line-height: 1.5rem;
}
.td {
position: relative;
padding: 0;
}

View file

@ -21,6 +21,7 @@ import "phoenix_html"
import {Socket} from "phoenix" import {Socket} from "phoenix"
import {LiveSocket} from "phoenix_live_view" import {LiveSocket} from "phoenix_live_view"
import topbar from "../vendor/topbar" import topbar from "../vendor/topbar"
import "../css/app.css"
let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content") let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
let liveSocket = new LiveSocket("/live", Socket, { let liveSocket = new LiveSocket("/live", Socket, {

View file

@ -1,75 +0,0 @@
// See the Tailwind configuration guide for advanced usage
// https://tailwindcss.com/docs/configuration
const plugin = require("tailwindcss/plugin")
const fs = require("fs")
const path = require("path")
module.exports = {
content: [
"./js/**/*.js",
"../lib/comfycamp_web.ex",
"../lib/comfycamp_web/**/*.*ex"
],
theme: {
extend: {
colors: {
brand: "#FD4F00",
}
},
},
plugins: [
require("@tailwindcss/forms"),
// Allows prefixing tailwind classes with LiveView classes to add rules
// only when LiveView classes are applied, for example:
//
// <div class="phx-click-loading:animate-ping">
//
plugin(({addVariant}) => addVariant("phx-no-feedback", [".phx-no-feedback&", ".phx-no-feedback &"])),
plugin(({addVariant}) => addVariant("phx-click-loading", [".phx-click-loading&", ".phx-click-loading &"])),
plugin(({addVariant}) => addVariant("phx-submit-loading", [".phx-submit-loading&", ".phx-submit-loading &"])),
plugin(({addVariant}) => addVariant("phx-change-loading", [".phx-change-loading&", ".phx-change-loading &"])),
// Embeds Heroicons (https://heroicons.com) into your app.css bundle
// See your `CoreComponents.icon/1` for more information.
//
plugin(function({matchComponents, theme}) {
let iconsDir = path.join(__dirname, "../deps/heroicons/optimized")
let values = {}
let icons = [
["", "/24/outline"],
["-solid", "/24/solid"],
["-mini", "/20/solid"],
["-micro", "/16/solid"]
]
icons.forEach(([suffix, dir]) => {
fs.readdirSync(path.join(iconsDir, dir)).forEach(file => {
let name = path.basename(file, ".svg") + suffix
values[name] = {name, fullPath: path.join(iconsDir, dir, file)}
})
})
matchComponents({
"hero": ({name, fullPath}) => {
let content = fs.readFileSync(fullPath).toString().replace(/\r?\n|\r/g, "")
let size = theme("spacing.6")
if (name.endsWith("-mini")) {
size = theme("spacing.5")
} else if (name.endsWith("-micro")) {
size = theme("spacing.4")
}
return {
[`--hero-${name}`]: `url('data:image/svg+xml;utf8,${content}')`,
"-webkit-mask": `var(--hero-${name})`,
"mask": `var(--hero-${name})`,
"mask-repeat": "no-repeat",
"background-color": "currentColor",
"vertical-align": "middle",
"display": "inline-block",
"width": size,
"height": size
}
}
}, {values})
})
]
}

View file

@ -41,18 +41,6 @@ config :esbuild,
env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)} env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)}
] ]
# Configure tailwind (the version is required)
config :tailwind,
version: "3.4.0",
comfycamp: [
args: ~w(
--config=tailwind.config.js
--input=css/app.css
--output=../priv/static/assets/app.css
),
cd: Path.expand("../assets", __DIR__)
]
# Configures Elixir's Logger # Configures Elixir's Logger
config :logger, :console, config :logger, :console,
format: "$time $metadata[$level] $message\n", format: "$time $metadata[$level] $message\n",

View file

@ -25,8 +25,7 @@ config :comfycamp, ComfycampWeb.Endpoint,
debug_errors: true, debug_errors: true,
secret_key_base: "6TPjZ6GJcs5FerDbAdr2pHRL5JASsi04nah6WbeQfbPmnuHz0lAUu4e60HNBkKVv", secret_key_base: "6TPjZ6GJcs5FerDbAdr2pHRL5JASsi04nah6WbeQfbPmnuHz0lAUu4e60HNBkKVv",
watchers: [ watchers: [
esbuild: {Esbuild, :install_and_run, [:comfycamp, ~w(--sourcemap=inline --watch)]}, esbuild: {Esbuild, :install_and_run, [:comfycamp, ~w(--sourcemap=inline --watch)]}
tailwind: {Tailwind, :install_and_run, [:comfycamp, ~w(--watch)]}
] ]
# ## SSL Support # ## SSL Support

View file

@ -48,34 +48,32 @@ defmodule ComfycampWeb.CoreComponents do
phx-mounted={@show && show_modal(@id)} phx-mounted={@show && show_modal(@id)}
phx-remove={hide_modal(@id)} phx-remove={hide_modal(@id)}
data-cancel={JS.exec(@on_cancel, "phx-remove")} data-cancel={JS.exec(@on_cancel, "phx-remove")}
class="relative z-50 hidden" class="modal"
> >
<div id={"#{@id}-bg"} class="bg-zinc-50/90 fixed inset-0 transition-opacity" aria-hidden="true" /> <div id={"#{@id}-bg"} class="modal-bg" aria-hidden="true" />
<div <div
class="fixed inset-0 overflow-y-auto" class="modal-body"
aria-labelledby={"#{@id}-title"} aria-labelledby={"#{@id}-title"}
aria-describedby={"#{@id}-description"} aria-describedby={"#{@id}-description"}
role="dialog" role="dialog"
aria-modal="true" aria-modal="true"
tabindex="0" tabindex="0"
> >
<div class="flex min-h-full items-center justify-center">
<div class="w-full max-w-3xl p-4 sm:p-6 lg:py-8">
<.focus_wrap <.focus_wrap
id={"#{@id}-container"} id={"#{@id}-container"}
phx-window-keydown={JS.exec("data-cancel", to: "##{@id}")} phx-window-keydown={JS.exec("data-cancel", to: "##{@id}")}
phx-key="escape" phx-key="escape"
phx-click-away={JS.exec("data-cancel", to: "##{@id}")} phx-click-away={JS.exec("data-cancel", to: "##{@id}")}
class="shadow-zinc-700/10 ring-zinc-700/10 relative hidden rounded-2xl bg-white p-14 shadow-lg ring-1 transition" class="modal-container"
> >
<div class="absolute top-6 right-5"> <div class="modal-close-button-container">
<button <button
phx-click={JS.exec("data-cancel", to: "##{@id}")} phx-click={JS.exec("data-cancel", to: "##{@id}")}
type="button" type="button"
class="-m-3 flex-none p-3 opacity-20 hover:opacity-40" class="modal-close-button"
aria-label={gettext("close")} aria-label={gettext("close")}
> >
<.icon name="hero-x-mark-solid" class="h-5 w-5" /> <.icon name="hero-x-mark-solid" class="modal-close-button-icon" />
</button> </button>
</div> </div>
<div id={"#{@id}-content"}> <div id={"#{@id}-content"}>
@ -84,8 +82,6 @@ defmodule ComfycampWeb.CoreComponents do
</.focus_wrap> </.focus_wrap>
</div> </div>
</div> </div>
</div>
</div>
""" """
end end
@ -115,20 +111,20 @@ defmodule ComfycampWeb.CoreComponents do
phx-click={JS.push("lv:clear-flash", value: %{key: @kind}) |> hide("##{@id}")} phx-click={JS.push("lv:clear-flash", value: %{key: @kind}) |> hide("##{@id}")}
role="alert" role="alert"
class={[ class={[
"fixed top-2 right-2 mr-2 w-80 sm:w-96 z-50 rounded-lg p-3 ring-1", "flash",
@kind == :info && "bg-emerald-50 text-emerald-800 ring-emerald-500 fill-cyan-900", @kind == :info && "flash-info",
@kind == :error && "bg-rose-50 text-rose-900 shadow-md ring-rose-500 fill-rose-900" @kind == :error && "flash-error"
]} ]}
{@rest} {@rest}
> >
<p :if={@title} class="flex items-center gap-1.5 text-sm font-semibold leading-6"> <p :if={@title} class="flash-title">
<.icon :if={@kind == :info} name="hero-information-circle-mini" class="h-4 w-4" /> <.icon :if={@kind == :info} name="hero-information-circle-mini" class="h-4 w-4" />
<.icon :if={@kind == :error} name="hero-exclamation-circle-mini" class="h-4 w-4" /> <.icon :if={@kind == :error} name="hero-exclamation-circle-mini" class="h-4 w-4" />
<%= @title %> <%= @title %>
</p> </p>
<p class="mt-2 text-sm leading-5"><%= msg %></p> <p class="mt-2 text-sm leading-5"><%= msg %></p>
<button type="button" class="group absolute top-1 right-1 p-2" aria-label={gettext("close")}> <button type="button" class="flash-close-button" aria-label={gettext("close")}>
<.icon name="hero-x-mark-solid" class="h-5 w-5 opacity-40 group-hover:opacity-70" /> <.icon name="hero-x-mark-solid" class="flash-close-button-icon" />
</button> </button>
</div> </div>
""" """
@ -202,9 +198,9 @@ defmodule ComfycampWeb.CoreComponents do
def simple_form(assigns) do def simple_form(assigns) do
~H""" ~H"""
<.form :let={f} for={@for} as={@as} {@rest}> <.form :let={f} for={@for} as={@as} {@rest}>
<div class="mt-10 space-y-8 bg-white"> <div class="simple-form">
<%= render_slot(@inner_block, f) %> <%= render_slot(@inner_block, f) %>
<div :for={action <- @actions} class="mt-2 flex items-center justify-between gap-6"> <div :for={action <- @actions} class="simple-form-action">
<%= render_slot(action, f) %> <%= render_slot(action, f) %>
</div> </div>
</div> </div>
@ -231,8 +227,7 @@ defmodule ComfycampWeb.CoreComponents do
<button <button
type={@type} type={@type}
class={[ class={[
"phx-submit-loading:opacity-75 rounded-lg bg-zinc-900 hover:bg-zinc-700 py-2 px-3", "button",
"text-sm font-semibold leading-6 text-white active:text-white/80",
@class @class
]} ]}
{@rest} {@rest}
@ -310,7 +305,7 @@ defmodule ComfycampWeb.CoreComponents do
~H""" ~H"""
<div phx-feedback-for={@name}> <div phx-feedback-for={@name}>
<label class="flex items-center gap-4 text-sm leading-6 text-zinc-600"> <label class="checkbox-label">
<input type="hidden" name={@name} value="false" /> <input type="hidden" name={@name} value="false" />
<input <input
type="checkbox" type="checkbox"
@ -318,7 +313,7 @@ defmodule ComfycampWeb.CoreComponents do
name={@name} name={@name}
value="true" value="true"
checked={@checked} checked={@checked}
class="rounded border-zinc-300 text-zinc-900 focus:ring-0" class="checkbox-input"
{@rest} {@rest}
/> />
<%= @label %> <%= @label %>
@ -335,7 +330,7 @@ defmodule ComfycampWeb.CoreComponents do
<select <select
id={@id} id={@id}
name={@name} name={@name}
class="mt-2 block w-full rounded-md border border-gray-300 bg-white shadow-sm focus:border-zinc-400 focus:ring-0 sm:text-sm" class="select"
multiple={@multiple} multiple={@multiple}
{@rest} {@rest}
> >
@ -355,10 +350,9 @@ defmodule ComfycampWeb.CoreComponents do
id={@id} id={@id}
name={@name} name={@name}
class={[ class={[
"mt-2 block w-full rounded-lg text-zinc-900 focus:ring-0 sm:text-sm sm:leading-6", "textarea",
"min-h-[6rem] phx-no-feedback:border-zinc-300 phx-no-feedback:focus:border-zinc-400", @errors == [] && "",
@errors == [] && "border-zinc-300 focus:border-zinc-400", @errors != [] && ""
@errors != [] && "border-rose-400 focus:border-rose-400"
]} ]}
{@rest} {@rest}
><%= Phoenix.HTML.Form.normalize_value("textarea", @value) %></textarea> ><%= Phoenix.HTML.Form.normalize_value("textarea", @value) %></textarea>
@ -378,10 +372,9 @@ defmodule ComfycampWeb.CoreComponents do
id={@id} id={@id}
value={Phoenix.HTML.Form.normalize_value(@type, @value)} value={Phoenix.HTML.Form.normalize_value(@type, @value)}
class={[ class={[
"mt-2 block w-full rounded-lg text-zinc-900 focus:ring-0 sm:text-sm sm:leading-6", "input",
"phx-no-feedback:border-zinc-300 phx-no-feedback:focus:border-zinc-400", @errors == [] && "",
@errors == [] && "border-zinc-300 focus:border-zinc-400", @errors != [] && ""
@errors != [] && "border-rose-400 focus:border-rose-400"
]} ]}
{@rest} {@rest}
/> />
@ -398,7 +391,7 @@ defmodule ComfycampWeb.CoreComponents do
def label(assigns) do def label(assigns) do
~H""" ~H"""
<label for={@for} class="block text-sm font-semibold leading-6 text-zinc-800"> <label for={@for} class="label">
<%= render_slot(@inner_block) %> <%= render_slot(@inner_block) %>
</label> </label>
""" """
@ -411,7 +404,7 @@ defmodule ComfycampWeb.CoreComponents do
def error(assigns) do def error(assigns) do
~H""" ~H"""
<p class="mt-3 flex gap-3 text-sm leading-6 text-rose-600 phx-no-feedback:hidden"> <p class="error">
<.icon name="hero-exclamation-circle-mini" class="mt-0.5 h-5 w-5 flex-none" /> <.icon name="hero-exclamation-circle-mini" class="mt-0.5 h-5 w-5 flex-none" />
<%= render_slot(@inner_block) %> <%= render_slot(@inner_block) %>
</p> </p>
@ -475,12 +468,12 @@ defmodule ComfycampWeb.CoreComponents do
end end
~H""" ~H"""
<div class="overflow-y-auto px-4 sm:overflow-visible sm:px-0"> <div class="table-container">
<table class="w-[40rem] mt-11 sm:w-full"> <table class="table">
<thead class="text-sm text-left leading-6 text-zinc-500"> <thead class="thead">
<tr> <tr>
<th :for={col <- @col} class="p-0 pb-4 pr-6 font-normal"><%= col[:label] %></th> <th :for={col <- @col} class="th"><%= col[:label] %></th>
<th :if={@action != []} class="relative p-0 pb-4"> <th :if={@action != []} class="th-actions">
<span class="sr-only"><%= gettext("Actions") %></span> <span class="sr-only"><%= gettext("Actions") %></span>
</th> </th>
</tr> </tr>
@ -488,13 +481,13 @@ defmodule ComfycampWeb.CoreComponents do
<tbody <tbody
id={@id} id={@id}
phx-update={match?(%Phoenix.LiveView.LiveStream{}, @rows) && "stream"} phx-update={match?(%Phoenix.LiveView.LiveStream{}, @rows) && "stream"}
class="relative divide-y divide-zinc-100 border-t border-zinc-200 text-sm leading-6 text-zinc-700" class="tbody"
> >
<tr :for={row <- @rows} id={@row_id && @row_id.(row)} class="group hover:bg-zinc-50"> <tr :for={row <- @rows} id={@row_id && @row_id.(row)} class="">
<td <td
:for={{col, i} <- Enum.with_index(@col)} :for={{col, i} <- Enum.with_index(@col)}
phx-click={@row_click && @row_click.(row)} phx-click={@row_click && @row_click.(row)}
class={["relative p-0", @row_click && "hover:cursor-pointer"]} class={["td", @row_click && "hover:cursor-pointer"]}
> >
<div class="block py-4 pr-6"> <div class="block py-4 pr-6">
<span class="absolute -inset-y-px right-0 -left-4 group-hover:bg-zinc-50 sm:rounded-l-xl" /> <span class="absolute -inset-y-px right-0 -left-4 group-hover:bg-zinc-50 sm:rounded-l-xl" />
@ -537,11 +530,11 @@ defmodule ComfycampWeb.CoreComponents do
def list(assigns) do def list(assigns) do
~H""" ~H"""
<div class="mt-14"> <div class="list">
<dl class="-my-4 divide-y divide-zinc-100"> <dl class="list-description">
<div :for={item <- @item} class="flex gap-4 py-4 text-sm leading-6 sm:gap-8"> <div :for={item <- @item} class="list-item">
<dt class="w-1/4 flex-none text-zinc-500"><%= item.title %></dt> <dt class="list-item-title"><%= item.title %></dt>
<dd class="text-zinc-700"><%= render_slot(item) %></dd> <dd class="list-item-description"><%= render_slot(item) %></dd>
</div> </div>
</dl> </dl>
</div> </div>
@ -563,7 +556,7 @@ defmodule ComfycampWeb.CoreComponents do
<div class="mt-16"> <div class="mt-16">
<.link <.link
navigate={@navigate} navigate={@navigate}
class="text-sm font-semibold leading-6 text-zinc-900 hover:text-zinc-700" class="back-nav-link"
> >
<.icon name="hero-arrow-left-solid" class="h-3 w-3" /> <.icon name="hero-arrow-left-solid" class="h-3 w-3" />
<%= render_slot(@inner_block) %> <%= render_slot(@inner_block) %>
@ -604,10 +597,7 @@ defmodule ComfycampWeb.CoreComponents do
def show(js \\ %JS{}, selector) do def show(js \\ %JS{}, selector) do
JS.show(js, JS.show(js,
to: selector, to: selector,
transition: transition: "show"
{"transition-all transform ease-out duration-300",
"opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95",
"opacity-100 translate-y-0 sm:scale-100"}
) )
end end
@ -615,10 +605,7 @@ defmodule ComfycampWeb.CoreComponents do
JS.hide(js, JS.hide(js,
to: selector, to: selector,
time: 200, time: 200,
transition: transition: "hide"
{"transition-all transform ease-in duration-200",
"opacity-100 translate-y-0 sm:scale-100",
"opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"}
) )
end end
@ -627,7 +614,7 @@ defmodule ComfycampWeb.CoreComponents do
|> JS.show(to: "##{id}") |> JS.show(to: "##{id}")
|> JS.show( |> JS.show(
to: "##{id}-bg", to: "##{id}-bg",
transition: {"transition-all transform ease-out duration-300", "opacity-0", "opacity-100"} transition: "show-modal"
) )
|> show("##{id}-container") |> show("##{id}-container")
|> JS.add_class("overflow-hidden", to: "body") |> JS.add_class("overflow-hidden", to: "body")
@ -638,7 +625,7 @@ defmodule ComfycampWeb.CoreComponents do
js js
|> JS.hide( |> JS.hide(
to: "##{id}-bg", to: "##{id}-bg",
transition: {"transition-all transform ease-in duration-200", "opacity-100", "opacity-0"} transition: "hide-modal"
) )
|> hide("##{id}-container") |> hide("##{id}-container")
|> JS.hide(to: "##{id}", transition: {"block", "block", "hidden"}) |> JS.hide(to: "##{id}", transition: {"block", "block", "hidden"})

View file

@ -1,20 +1,20 @@
<header class="px-4 sm:px-6 lg:px-8"> <header>
<div class="mx-auto max-w-2xl flex items-center gap-8 border-b border-zinc-100 py-3 text-sm"> <div class="limiter">
<a href="/">Главная</a> <a href="/">Главная</a>
<a href="/services/">Сервисы</a> <a href="/services/">Сервисы</a>
<a href="/cinema/">Кинотеатр</a> <a href="/cinema/">Кинотеатр</a>
</div> </div>
</header> </header>
<main class="px-4 py-20 sm:px-6 lg:px-8"> <main>
<div class="mx-auto max-w-2xl"> <div class="limiter">
<.flash_group flash={@flash} /> <.flash_group flash={@flash} />
<%= @inner_content %> <%= @inner_content %>
</div> </div>
</main> </main>
<footer class="px-4 py-20 sm:px-6 lg:px-8"> <footer>
<div class="mx-auto max-w-2xl"> <div class="limiter">
<div class="list"> <div class="list">
<a href="http://[201:80ed:6eeb:aea4:cdc0:c836:2831:f2dd]"> <a href="http://[201:80ed:6eeb:aea4:cdc0:c836:2831:f2dd]">
<.icon name="hero-globe-alt" /> Yggdrasil <.icon name="hero-globe-alt" /> Yggdrasil

View file

@ -23,7 +23,7 @@
href={"http://[201:80ed:6eeb:aea4:cdc0:c836:2831:f2dd]" <> @conn.request_path} href={"http://[201:80ed:6eeb:aea4:cdc0:c836:2831:f2dd]" <> @conn.request_path}
/> />
</head> </head>
<body class="bg-white antialiased"> <body>
<%= @inner_content %> <%= @inner_content %>
</body> </body>
</html> </html>

10
mix.exs
View file

@ -42,7 +42,6 @@ defmodule Comfycamp.MixProject do
{:floki, ">= 0.30.0", only: :test}, {:floki, ">= 0.30.0", only: :test},
{:phoenix_live_dashboard, "~> 0.8.3"}, {:phoenix_live_dashboard, "~> 0.8.3"},
{:esbuild, "~> 0.8", runtime: Mix.env() == :dev}, {:esbuild, "~> 0.8", runtime: Mix.env() == :dev},
{:tailwind, "~> 0.2", runtime: Mix.env() == :dev},
{:heroicons, {:heroicons,
github: "tailwindlabs/heroicons", github: "tailwindlabs/heroicons",
tag: "v2.1.1", tag: "v2.1.1",
@ -73,13 +72,8 @@ defmodule Comfycamp.MixProject do
"ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"], "ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
"ecto.reset": ["ecto.drop", "ecto.setup"], "ecto.reset": ["ecto.drop", "ecto.setup"],
test: ["ecto.create --quiet", "ecto.migrate --quiet", "test"], test: ["ecto.create --quiet", "ecto.migrate --quiet", "test"],
"assets.setup": ["tailwind.install --if-missing", "esbuild.install --if-missing"], "assets.setup": ["esbuild.install --if-missing"],
"assets.build": ["tailwind comfycamp", "esbuild comfycamp"], "assets.build": ["esbuild comfycamp"]
"assets.deploy": [
"tailwind comfycamp --minify",
"esbuild comfycamp --minify",
"phx.digest"
]
] ]
end end
end end

View file

@ -31,7 +31,6 @@
"plug_crypto": {:hex, :plug_crypto, "2.1.0", "f44309c2b06d249c27c8d3f65cfe08158ade08418cf540fd4f72d4d6863abb7b", [:mix], [], "hexpm", "131216a4b030b8f8ce0f26038bc4421ae60e4bb95c5cf5395e1421437824c4fa"}, "plug_crypto": {:hex, :plug_crypto, "2.1.0", "f44309c2b06d249c27c8d3f65cfe08158ade08418cf540fd4f72d4d6863abb7b", [:mix], [], "hexpm", "131216a4b030b8f8ce0f26038bc4421ae60e4bb95c5cf5395e1421437824c4fa"},
"postgrex": {:hex, :postgrex, "0.18.0", "f34664101eaca11ff24481ed4c378492fed2ff416cd9b06c399e90f321867d7e", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "a042989ba1bc1cca7383ebb9e461398e3f89f868c92ce6671feb7ef132a252d1"}, "postgrex": {:hex, :postgrex, "0.18.0", "f34664101eaca11ff24481ed4c378492fed2ff416cd9b06c399e90f321867d7e", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "a042989ba1bc1cca7383ebb9e461398e3f89f868c92ce6671feb7ef132a252d1"},
"swoosh": {:hex, :swoosh, "1.16.7", "9dd0c172b4519a023f58e94d3ea79480b469dd4c0cd5369fabfbfd2e39bf5545", [:mix], [{:bandit, ">= 1.0.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mua, "~> 0.1.0", [hex: :mua, repo: "hexpm", optional: true]}, {:multipart, "~> 0.4", [hex: :multipart, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: true]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:req, "~> 0.4 or ~> 1.0", [hex: :req, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "21073982816cff3410e90c0d80ebfd5a0bf4839c7b39db20bc69a6df123bbf35"}, "swoosh": {:hex, :swoosh, "1.16.7", "9dd0c172b4519a023f58e94d3ea79480b469dd4c0cd5369fabfbfd2e39bf5545", [:mix], [{:bandit, ">= 1.0.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mua, "~> 0.1.0", [hex: :mua, repo: "hexpm", optional: true]}, {:multipart, "~> 0.4", [hex: :multipart, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: true]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:req, "~> 0.4 or ~> 1.0", [hex: :req, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "21073982816cff3410e90c0d80ebfd5a0bf4839c7b39db20bc69a6df123bbf35"},
"tailwind": {:hex, :tailwind, "0.2.2", "9e27288b568ede1d88517e8c61259bc214a12d7eed271e102db4c93fcca9b2cd", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "ccfb5025179ea307f7f899d1bb3905cd0ac9f687ed77feebc8f67bdca78565c4"},
"telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"}, "telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"},
"telemetry_metrics": {:hex, :telemetry_metrics, "1.0.0", "29f5f84991ca98b8eb02fc208b2e6de7c95f8bb2294ef244a176675adc7775df", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "f23713b3847286a534e005126d4c959ebcca68ae9582118ce436b521d1d47d5d"}, "telemetry_metrics": {:hex, :telemetry_metrics, "1.0.0", "29f5f84991ca98b8eb02fc208b2e6de7c95f8bb2294ef244a176675adc7775df", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "f23713b3847286a534e005126d4c959ebcca68ae9582118ce436b521d1d47d5d"},
"telemetry_poller": {:hex, :telemetry_poller, "1.1.0", "58fa7c216257291caaf8d05678c8d01bd45f4bdbc1286838a28c4bb62ef32999", [:rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "9eb9d9cbfd81cbd7cdd24682f8711b6e2b691289a0de6826e58452f28c103c8f"}, "telemetry_poller": {:hex, :telemetry_poller, "1.1.0", "58fa7c216257291caaf8d05678c8d01bd45f4bdbc1286838a28c4bb62ef32999", [:rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "9eb9d9cbfd81cbd7cdd24682f8711b6e2b691289a0de6826e58452f28c103c8f"},