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:
parent
c80f439840
commit
c6de8dce34
11 changed files with 481 additions and 182 deletions
|
@ -1,5 +1,48 @@
|
|||
@import "tailwindcss/base";
|
||||
@import "tailwindcss/components";
|
||||
@import "tailwindcss/utilities";
|
||||
@import "./core_components.css";
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
|
363
assets/css/core_components.css
Normal file
363
assets/css/core_components.css
Normal 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;
|
||||
}
|
|
@ -21,6 +21,7 @@ import "phoenix_html"
|
|||
import {Socket} from "phoenix"
|
||||
import {LiveSocket} from "phoenix_live_view"
|
||||
import topbar from "../vendor/topbar"
|
||||
import "../css/app.css"
|
||||
|
||||
let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
|
||||
let liveSocket = new LiveSocket("/live", Socket, {
|
||||
|
|
|
@ -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})
|
||||
})
|
||||
]
|
||||
}
|
|
@ -41,18 +41,6 @@ config :esbuild,
|
|||
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
|
||||
config :logger, :console,
|
||||
format: "$time $metadata[$level] $message\n",
|
||||
|
|
|
@ -25,8 +25,7 @@ config :comfycamp, ComfycampWeb.Endpoint,
|
|||
debug_errors: true,
|
||||
secret_key_base: "6TPjZ6GJcs5FerDbAdr2pHRL5JASsi04nah6WbeQfbPmnuHz0lAUu4e60HNBkKVv",
|
||||
watchers: [
|
||||
esbuild: {Esbuild, :install_and_run, [:comfycamp, ~w(--sourcemap=inline --watch)]},
|
||||
tailwind: {Tailwind, :install_and_run, [:comfycamp, ~w(--watch)]}
|
||||
esbuild: {Esbuild, :install_and_run, [:comfycamp, ~w(--sourcemap=inline --watch)]}
|
||||
]
|
||||
|
||||
# ## SSL Support
|
||||
|
|
|
@ -48,34 +48,32 @@ defmodule ComfycampWeb.CoreComponents do
|
|||
phx-mounted={@show && show_modal(@id)}
|
||||
phx-remove={hide_modal(@id)}
|
||||
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
|
||||
class="fixed inset-0 overflow-y-auto"
|
||||
class="modal-body"
|
||||
aria-labelledby={"#{@id}-title"}
|
||||
aria-describedby={"#{@id}-description"}
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
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
|
||||
id={"#{@id}-container"}
|
||||
phx-window-keydown={JS.exec("data-cancel", to: "##{@id}")}
|
||||
phx-key="escape"
|
||||
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
|
||||
phx-click={JS.exec("data-cancel", to: "##{@id}")}
|
||||
type="button"
|
||||
class="-m-3 flex-none p-3 opacity-20 hover:opacity-40"
|
||||
class="modal-close-button"
|
||||
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>
|
||||
</div>
|
||||
<div id={"#{@id}-content"}>
|
||||
|
@ -84,8 +82,6 @@ defmodule ComfycampWeb.CoreComponents do
|
|||
</.focus_wrap>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
|
@ -115,20 +111,20 @@ defmodule ComfycampWeb.CoreComponents do
|
|||
phx-click={JS.push("lv:clear-flash", value: %{key: @kind}) |> hide("##{@id}")}
|
||||
role="alert"
|
||||
class={[
|
||||
"fixed top-2 right-2 mr-2 w-80 sm:w-96 z-50 rounded-lg p-3 ring-1",
|
||||
@kind == :info && "bg-emerald-50 text-emerald-800 ring-emerald-500 fill-cyan-900",
|
||||
@kind == :error && "bg-rose-50 text-rose-900 shadow-md ring-rose-500 fill-rose-900"
|
||||
"flash",
|
||||
@kind == :info && "flash-info",
|
||||
@kind == :error && "flash-error"
|
||||
]}
|
||||
{@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 == :error} name="hero-exclamation-circle-mini" class="h-4 w-4" />
|
||||
<%= @title %>
|
||||
</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")}>
|
||||
<.icon name="hero-x-mark-solid" class="h-5 w-5 opacity-40 group-hover:opacity-70" />
|
||||
<button type="button" class="flash-close-button" aria-label={gettext("close")}>
|
||||
<.icon name="hero-x-mark-solid" class="flash-close-button-icon" />
|
||||
</button>
|
||||
</div>
|
||||
"""
|
||||
|
@ -202,9 +198,9 @@ defmodule ComfycampWeb.CoreComponents do
|
|||
def simple_form(assigns) do
|
||||
~H"""
|
||||
<.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) %>
|
||||
<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) %>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -231,8 +227,7 @@ defmodule ComfycampWeb.CoreComponents do
|
|||
<button
|
||||
type={@type}
|
||||
class={[
|
||||
"phx-submit-loading:opacity-75 rounded-lg bg-zinc-900 hover:bg-zinc-700 py-2 px-3",
|
||||
"text-sm font-semibold leading-6 text-white active:text-white/80",
|
||||
"button",
|
||||
@class
|
||||
]}
|
||||
{@rest}
|
||||
|
@ -310,7 +305,7 @@ defmodule ComfycampWeb.CoreComponents do
|
|||
|
||||
~H"""
|
||||
<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="checkbox"
|
||||
|
@ -318,7 +313,7 @@ defmodule ComfycampWeb.CoreComponents do
|
|||
name={@name}
|
||||
value="true"
|
||||
checked={@checked}
|
||||
class="rounded border-zinc-300 text-zinc-900 focus:ring-0"
|
||||
class="checkbox-input"
|
||||
{@rest}
|
||||
/>
|
||||
<%= @label %>
|
||||
|
@ -335,7 +330,7 @@ defmodule ComfycampWeb.CoreComponents do
|
|||
<select
|
||||
id={@id}
|
||||
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}
|
||||
{@rest}
|
||||
>
|
||||
|
@ -355,10 +350,9 @@ defmodule ComfycampWeb.CoreComponents do
|
|||
id={@id}
|
||||
name={@name}
|
||||
class={[
|
||||
"mt-2 block w-full rounded-lg text-zinc-900 focus:ring-0 sm:text-sm sm:leading-6",
|
||||
"min-h-[6rem] phx-no-feedback:border-zinc-300 phx-no-feedback:focus:border-zinc-400",
|
||||
@errors == [] && "border-zinc-300 focus:border-zinc-400",
|
||||
@errors != [] && "border-rose-400 focus:border-rose-400"
|
||||
"textarea",
|
||||
@errors == [] && "",
|
||||
@errors != [] && ""
|
||||
]}
|
||||
{@rest}
|
||||
><%= Phoenix.HTML.Form.normalize_value("textarea", @value) %></textarea>
|
||||
|
@ -378,10 +372,9 @@ defmodule ComfycampWeb.CoreComponents do
|
|||
id={@id}
|
||||
value={Phoenix.HTML.Form.normalize_value(@type, @value)}
|
||||
class={[
|
||||
"mt-2 block w-full rounded-lg text-zinc-900 focus:ring-0 sm:text-sm sm:leading-6",
|
||||
"phx-no-feedback:border-zinc-300 phx-no-feedback:focus:border-zinc-400",
|
||||
@errors == [] && "border-zinc-300 focus:border-zinc-400",
|
||||
@errors != [] && "border-rose-400 focus:border-rose-400"
|
||||
"input",
|
||||
@errors == [] && "",
|
||||
@errors != [] && ""
|
||||
]}
|
||||
{@rest}
|
||||
/>
|
||||
|
@ -398,7 +391,7 @@ defmodule ComfycampWeb.CoreComponents do
|
|||
|
||||
def label(assigns) do
|
||||
~H"""
|
||||
<label for={@for} class="block text-sm font-semibold leading-6 text-zinc-800">
|
||||
<label for={@for} class="label">
|
||||
<%= render_slot(@inner_block) %>
|
||||
</label>
|
||||
"""
|
||||
|
@ -411,7 +404,7 @@ defmodule ComfycampWeb.CoreComponents do
|
|||
|
||||
def error(assigns) do
|
||||
~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" />
|
||||
<%= render_slot(@inner_block) %>
|
||||
</p>
|
||||
|
@ -475,12 +468,12 @@ defmodule ComfycampWeb.CoreComponents do
|
|||
end
|
||||
|
||||
~H"""
|
||||
<div class="overflow-y-auto px-4 sm:overflow-visible sm:px-0">
|
||||
<table class="w-[40rem] mt-11 sm:w-full">
|
||||
<thead class="text-sm text-left leading-6 text-zinc-500">
|
||||
<div class="table-container">
|
||||
<table class="table">
|
||||
<thead class="thead">
|
||||
<tr>
|
||||
<th :for={col <- @col} class="p-0 pb-4 pr-6 font-normal"><%= col[:label] %></th>
|
||||
<th :if={@action != []} class="relative p-0 pb-4">
|
||||
<th :for={col <- @col} class="th"><%= col[:label] %></th>
|
||||
<th :if={@action != []} class="th-actions">
|
||||
<span class="sr-only"><%= gettext("Actions") %></span>
|
||||
</th>
|
||||
</tr>
|
||||
|
@ -488,13 +481,13 @@ defmodule ComfycampWeb.CoreComponents do
|
|||
<tbody
|
||||
id={@id}
|
||||
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
|
||||
:for={{col, i} <- Enum.with_index(@col)}
|
||||
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">
|
||||
<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
|
||||
~H"""
|
||||
<div class="mt-14">
|
||||
<dl class="-my-4 divide-y divide-zinc-100">
|
||||
<div :for={item <- @item} class="flex gap-4 py-4 text-sm leading-6 sm:gap-8">
|
||||
<dt class="w-1/4 flex-none text-zinc-500"><%= item.title %></dt>
|
||||
<dd class="text-zinc-700"><%= render_slot(item) %></dd>
|
||||
<div class="list">
|
||||
<dl class="list-description">
|
||||
<div :for={item <- @item} class="list-item">
|
||||
<dt class="list-item-title"><%= item.title %></dt>
|
||||
<dd class="list-item-description"><%= render_slot(item) %></dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
|
@ -563,7 +556,7 @@ defmodule ComfycampWeb.CoreComponents do
|
|||
<div class="mt-16">
|
||||
<.link
|
||||
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" />
|
||||
<%= render_slot(@inner_block) %>
|
||||
|
@ -604,10 +597,7 @@ defmodule ComfycampWeb.CoreComponents do
|
|||
def show(js \\ %JS{}, selector) do
|
||||
JS.show(js,
|
||||
to: selector,
|
||||
transition:
|
||||
{"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"}
|
||||
transition: "show"
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -615,10 +605,7 @@ defmodule ComfycampWeb.CoreComponents do
|
|||
JS.hide(js,
|
||||
to: selector,
|
||||
time: 200,
|
||||
transition:
|
||||
{"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"}
|
||||
transition: "hide"
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -627,7 +614,7 @@ defmodule ComfycampWeb.CoreComponents do
|
|||
|> JS.show(to: "##{id}")
|
||||
|> JS.show(
|
||||
to: "##{id}-bg",
|
||||
transition: {"transition-all transform ease-out duration-300", "opacity-0", "opacity-100"}
|
||||
transition: "show-modal"
|
||||
)
|
||||
|> show("##{id}-container")
|
||||
|> JS.add_class("overflow-hidden", to: "body")
|
||||
|
@ -638,7 +625,7 @@ defmodule ComfycampWeb.CoreComponents do
|
|||
js
|
||||
|> JS.hide(
|
||||
to: "##{id}-bg",
|
||||
transition: {"transition-all transform ease-in duration-200", "opacity-100", "opacity-0"}
|
||||
transition: "hide-modal"
|
||||
)
|
||||
|> hide("##{id}-container")
|
||||
|> JS.hide(to: "##{id}", transition: {"block", "block", "hidden"})
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
<header class="px-4 sm:px-6 lg:px-8">
|
||||
<div class="mx-auto max-w-2xl flex items-center gap-8 border-b border-zinc-100 py-3 text-sm">
|
||||
<header>
|
||||
<div class="limiter">
|
||||
<a href="/">Главная</a>
|
||||
<a href="/services/">Сервисы</a>
|
||||
<a href="/cinema/">Кинотеатр</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="px-4 py-20 sm:px-6 lg:px-8">
|
||||
<div class="mx-auto max-w-2xl">
|
||||
<main>
|
||||
<div class="limiter">
|
||||
<.flash_group flash={@flash} />
|
||||
<%= @inner_content %>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="px-4 py-20 sm:px-6 lg:px-8">
|
||||
<div class="mx-auto max-w-2xl">
|
||||
<footer>
|
||||
<div class="limiter">
|
||||
<div class="list">
|
||||
<a href="http://[201:80ed:6eeb:aea4:cdc0:c836:2831:f2dd]">
|
||||
<.icon name="hero-globe-alt" /> Yggdrasil
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
href={"http://[201:80ed:6eeb:aea4:cdc0:c836:2831:f2dd]" <> @conn.request_path}
|
||||
/>
|
||||
</head>
|
||||
<body class="bg-white antialiased">
|
||||
<body>
|
||||
<%= @inner_content %>
|
||||
</body>
|
||||
</html>
|
||||
|
|
10
mix.exs
10
mix.exs
|
@ -42,7 +42,6 @@ defmodule Comfycamp.MixProject do
|
|||
{:floki, ">= 0.30.0", only: :test},
|
||||
{:phoenix_live_dashboard, "~> 0.8.3"},
|
||||
{:esbuild, "~> 0.8", runtime: Mix.env() == :dev},
|
||||
{:tailwind, "~> 0.2", runtime: Mix.env() == :dev},
|
||||
{:heroicons,
|
||||
github: "tailwindlabs/heroicons",
|
||||
tag: "v2.1.1",
|
||||
|
@ -73,13 +72,8 @@ defmodule Comfycamp.MixProject do
|
|||
"ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
|
||||
"ecto.reset": ["ecto.drop", "ecto.setup"],
|
||||
test: ["ecto.create --quiet", "ecto.migrate --quiet", "test"],
|
||||
"assets.setup": ["tailwind.install --if-missing", "esbuild.install --if-missing"],
|
||||
"assets.build": ["tailwind comfycamp", "esbuild comfycamp"],
|
||||
"assets.deploy": [
|
||||
"tailwind comfycamp --minify",
|
||||
"esbuild comfycamp --minify",
|
||||
"phx.digest"
|
||||
]
|
||||
"assets.setup": ["esbuild.install --if-missing"],
|
||||
"assets.build": ["esbuild comfycamp"]
|
||||
]
|
||||
end
|
||||
end
|
||||
|
|
1
mix.lock
1
mix.lock
|
@ -31,7 +31,6 @@
|
|||
"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"},
|
||||
"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_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"},
|
||||
|
|
Loading…
Reference in a new issue