initial bootstrap/navbar setup akin to bones73k implementation
This commit is contained in:
parent
dfe805b811
commit
0a83f8f317
32 changed files with 6856 additions and 7865 deletions
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -32,3 +32,10 @@ npm-debug.log
|
|||
# we ignore priv/static. You may want to comment
|
||||
# this depending on your deployment strategy.
|
||||
/priv/static/
|
||||
|
||||
|
||||
# for vscode elixir_ls extension files
|
||||
/.elixir_ls
|
||||
|
||||
# dev
|
||||
TODO.md
|
||||
|
|
35
assets/css/_bs-colors.scss
Normal file
35
assets/css/_bs-colors.scss
Normal file
|
@ -0,0 +1,35 @@
|
|||
// Colors
|
||||
// $primary: #662c91;
|
||||
// $secondary: #ee6c4d;
|
||||
// $success: #3f784c;
|
||||
// $info: #3f84e5;
|
||||
// $warning: #ffec51;
|
||||
$light: $gray-200;
|
||||
$dark: $gray-800;
|
||||
|
||||
// Create your own map
|
||||
$custom-colors: (
|
||||
"primary": $primary,
|
||||
"secondary": $secondary,
|
||||
"success": $success,
|
||||
"info": $info,
|
||||
"warning": $warning,
|
||||
"danger": $danger,
|
||||
"light": $light,
|
||||
"dark": $dark,
|
||||
"gray": $gray-500,
|
||||
);
|
||||
|
||||
// $custom-colors: (
|
||||
// "custom-color": #900
|
||||
// );
|
||||
|
||||
// Merge the maps
|
||||
$theme-colors: map-merge($theme-colors, $custom-colors);
|
||||
|
||||
// misc
|
||||
$navbar-dark-color: rgba($white, 0.75);
|
||||
$navbar-dark-hover-color: rgba($white, 0.9);
|
||||
$navbar-dark-active-color: $white;
|
||||
$navbar-dark-disabled-color: rgba($white, 0.45);
|
||||
$navbar-dark-toggler-border-color: rgba($white, 0.3);
|
21
assets/css/_bs-custom.scss
Normal file
21
assets/css/_bs-custom.scss
Normal file
|
@ -0,0 +1,21 @@
|
|||
/* Bootstrap custom variable overrides */
|
||||
|
||||
// Typography
|
||||
//
|
||||
// Font, line-height, and color for body text, headings, and more.
|
||||
|
||||
// stylelint-disable value-keyword-case
|
||||
$font-family-sans-serif: Lato, system-ui, -apple-system, "Segoe UI", Roboto,
|
||||
"Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif,
|
||||
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" !important;
|
||||
$font-family-secondary: Righteous, system-ui, -apple-system, "Segoe UI", Roboto,
|
||||
"Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif,
|
||||
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" !important;
|
||||
$font-family-monospace: "Fira Mono", SFMono-Regular, Menlo, Monaco, Consolas,
|
||||
"Liberation Mono", "Courier New", monospace !important;
|
||||
$font-family-code: "Fira Code", "Fira Mono", SFMono-Regular, Menlo, Monaco,
|
||||
Consolas, "Liberation Mono", "Courier New", monospace !important;
|
||||
|
||||
// Features
|
||||
$enable-shadows: true;
|
||||
$enable-negative-margins: true;
|
50
assets/css/_bs-load.scss
Normal file
50
assets/css/_bs-load.scss
Normal file
|
@ -0,0 +1,50 @@
|
|||
/* Bootstrap custom variable overrides */
|
||||
@import "bs-custom";
|
||||
|
||||
// Required || Configuration
|
||||
@import "../node_modules/bootstrap/scss/functions";
|
||||
@import "../node_modules/bootstrap/scss/variables";
|
||||
|
||||
/* Bootstrap custom variable overrides */
|
||||
@import "bs-colors";
|
||||
|
||||
// Required || Configuration -- CONTINUED
|
||||
@import "../node_modules/bootstrap/scss/mixins";
|
||||
@import "../node_modules/bootstrap/scss/utilities";
|
||||
|
||||
// Optional || Layout & components
|
||||
@import "../node_modules/bootstrap/scss/root";
|
||||
@import "../node_modules/bootstrap/scss/reboot";
|
||||
@import "../node_modules/bootstrap/scss/type";
|
||||
@import "../node_modules/bootstrap/scss/images";
|
||||
@import "../node_modules/bootstrap/scss/containers";
|
||||
@import "../node_modules/bootstrap/scss/grid";
|
||||
// @import "../node_modules/bootstrap/scss/tables";
|
||||
@import "../node_modules/bootstrap/scss/forms";
|
||||
@import "../node_modules/bootstrap/scss/buttons";
|
||||
@import "../node_modules/bootstrap/scss/transitions";
|
||||
// @import "../node_modules/bootstrap/scss/dropdown";
|
||||
// @import "../node_modules/bootstrap/scss/button-group";
|
||||
@import "../node_modules/bootstrap/scss/nav";
|
||||
@import "../node_modules/bootstrap/scss/navbar";
|
||||
@import "../node_modules/bootstrap/scss/card";
|
||||
// @import "../node_modules/bootstrap/scss/accordion";
|
||||
// @import "../node_modules/bootstrap/scss/breadcrumb";
|
||||
// @import "../node_modules/bootstrap/scss/pagination";
|
||||
// @import "../node_modules/bootstrap/scss/badge";
|
||||
// @import "../node_modules/bootstrap/scss/alert";
|
||||
// @import "../node_modules/bootstrap/scss/progress";
|
||||
// @import "../node_modules/bootstrap/scss/list-group";
|
||||
// @import "../node_modules/bootstrap/scss/close";
|
||||
// @import "../node_modules/bootstrap/scss/toasts";
|
||||
// @import "../node_modules/bootstrap/scss/modal";
|
||||
// @import "../node_modules/bootstrap/scss/tooltip";
|
||||
// @import "../node_modules/bootstrap/scss/popover";
|
||||
// @import "../node_modules/bootstrap/scss/carousel";
|
||||
// @import "../node_modules/bootstrap/scss/spinners";
|
||||
|
||||
// Helpers
|
||||
@import "../node_modules/bootstrap/scss/helpers";
|
||||
|
||||
// Utilities
|
||||
@import "../node_modules/bootstrap/scss/utilities/api";
|
26
assets/css/_fonts.scss
Normal file
26
assets/css/_fonts.scss
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* Fontsource Lato */
|
||||
// @import "../node_modules/@fontsource/lato/100.css"; /* thin | normal */
|
||||
// @import "../node_modules/@fontsource/lato/100-italic.css"; /* thin | italic */
|
||||
@import "../node_modules/@fontsource/lato/300.css"; /* light | normal */
|
||||
// @import "../node_modules/@fontsource/lato/300-italic.css"; /* light | italic */
|
||||
@import "../node_modules/@fontsource/lato/400.css"; /* normal | normal */
|
||||
// @import "../node_modules/@fontsource/lato/400-italic.css"; /* normal | italic */
|
||||
@import "../node_modules/@fontsource/lato/700.css"; /* bold | normal */
|
||||
// @import "../node_modules/@fontsource/lato/700-italic.css"; /* bold | italic */
|
||||
// @import "../node_modules/@fontsource/lato/900.css"; /* black | normal */
|
||||
// @import "../node_modules/@fontsource/lato/900-italic.css"; /* black | italic */
|
||||
|
||||
/* Fontsource Righteous */
|
||||
@import "../node_modules/@fontsource/righteous/400.css"; /* normal | normal */
|
||||
|
||||
/* Fontsource Fira Mono */
|
||||
@import "../node_modules/@fontsource/fira-mono/400.css"; /* normal | normal */
|
||||
// @import "../node_modules/@fontsource/fira-mono/500.css"; /* heavier normal? */
|
||||
@import "../node_modules/@fontsource/fira-mono/700.css"; /* bold | normal */
|
||||
|
||||
/* Fontsource Fira Code */
|
||||
@import "../node_modules/@fontsource/fira-code/300.css"; /* light | normal */
|
||||
@import "../node_modules/@fontsource/fira-code/400.css"; /* normal | normal */
|
||||
// @import "../node_modules/@fontsource/fira-code/500.css"; /* heavier normal? */
|
||||
// @import "../node_modules/@fontsource/fira-code/600.css"; /* heavier normal? */
|
||||
@import "../node_modules/@fontsource/fira-code/700.css"; /* bold | normal */
|
56
assets/css/_nav-burger.scss
Normal file
56
assets/css/_nav-burger.scss
Normal file
|
@ -0,0 +1,56 @@
|
|||
/* Hamburger settings overrides */
|
||||
$hamburger-padding-x: 0.95rem !default;
|
||||
$hamburger-padding-y: 0.625rem !default;
|
||||
$hamburger-layer-width: 1.5rem !default;
|
||||
$hamburger-layer-height: 2px !default;
|
||||
$hamburger-layer-spacing: 6px !default;
|
||||
// * skipping default color, using color from bootstrap instead, below
|
||||
// $hamburger-layer-color: rgba(0, 0, 0, 0.55) !default;
|
||||
$hamburger-layer-border-radius: 0.25rem !default;
|
||||
$hamburger-hover-opacity: 0.7 !default;
|
||||
// * skipping default color, using color from bootstrap instead, below
|
||||
// $hamburger-active-layer-color: $hamburger-layer-color !default;
|
||||
$hamburger-active-hover-opacity: $hamburger-hover-opacity !default;
|
||||
|
||||
/* import hamburgers sass */
|
||||
@import "../node_modules/hamburgers/_sass/hamburgers/hamburgers.scss";
|
||||
|
||||
/* correct colors to match bootstrap defaults */
|
||||
.navbar-light {
|
||||
.hamburger {
|
||||
&.navbar-toggler {
|
||||
border: 1px $navbar-light-toggler-border-color solid !important;
|
||||
.hamburger-inner {
|
||||
&,
|
||||
&::before,
|
||||
&::after {
|
||||
background-color: $navbar-light-color;
|
||||
}
|
||||
}
|
||||
&.is-active {
|
||||
.hamburger-inner::after {
|
||||
background-color: $navbar-light-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.navbar-dark {
|
||||
.hamburger {
|
||||
&.navbar-toggler {
|
||||
border: 1px $navbar-dark-toggler-border-color solid !important;
|
||||
.hamburger-inner {
|
||||
&,
|
||||
&::before,
|
||||
&::after {
|
||||
background-color: $navbar-dark-color;
|
||||
}
|
||||
}
|
||||
&.is-active {
|
||||
.hamburger-inner::after {
|
||||
background-color: $navbar-dark-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
43
assets/css/_phx-liveview.scss
Normal file
43
assets/css/_phx-liveview.scss
Normal file
|
@ -0,0 +1,43 @@
|
|||
/* LiveView specific classes for your customizations */
|
||||
|
||||
/* hides the feedback field help if liveview indicates field not touched yet */
|
||||
.phx-no-feedback.invalid-feedback,
|
||||
.phx-no-feedback .invalid-feedback,
|
||||
.phx-orphaned-feedback.phx-no-feedback .invalid-feedback {
|
||||
display: none;
|
||||
}
|
||||
.phx-orphaned-feedback .invalid-feedback {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
/* sets default bootstrap form-control styles if field not touched yet */
|
||||
.phx-no-feedback .form-control.is-valid,
|
||||
.phx-no-feedback .form-control.is-invalid {
|
||||
border: $input-border-width solid $input-border-color;
|
||||
background-image: none;
|
||||
|
||||
&:focus {
|
||||
color: $input-focus-color;
|
||||
background-color: $input-focus-bg;
|
||||
border-color: $input-focus-border-color;
|
||||
outline: 0;
|
||||
@if $enable-shadows {
|
||||
@include box-shadow($input-box-shadow, $input-focus-box-shadow);
|
||||
} @else {
|
||||
// Avoid using mixin so we can pass custom focus shadow properly
|
||||
box-shadow: $input-focus-box-shadow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.phx-click-loading {
|
||||
opacity: 0.5;
|
||||
transition: opacity 1s ease-out;
|
||||
}
|
||||
|
||||
.phx-disconnected {
|
||||
cursor: wait;
|
||||
}
|
||||
.phx-disconnected * {
|
||||
pointer-events: none;
|
||||
}
|
21
assets/css/_svg-icons.scss
Normal file
21
assets/css/_svg-icons.scss
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
SVG ICON SYSTEM
|
||||
per https://blog.prototypr.io/align-svg-icons-to-text-and-say-goodbye-to-font-icons-d44b3d7b26b4
|
||||
*/
|
||||
.icon {
|
||||
display: inline-flex;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.icon svg,
|
||||
.icon img {
|
||||
height: 1em;
|
||||
width: 1em;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
.icon.baseline svg,
|
||||
.icon img {
|
||||
top: 0.125em;
|
||||
position: relative;
|
||||
}
|
|
@ -1,90 +1,63 @@
|
|||
/* This file is for your main application css. */
|
||||
@import "./phoenix.css";
|
||||
/* Fonts */
|
||||
@import "fonts";
|
||||
|
||||
/* LiveView specific classes for your customizations */
|
||||
.phx-no-feedback.invalid-feedback,
|
||||
.phx-no-feedback .invalid-feedback {
|
||||
display: none;
|
||||
/* Load Bootstrap v5 and customizations */
|
||||
@import "bs-load";
|
||||
|
||||
/*SVG ICON SYSTEM*/
|
||||
@import "svg-icons";
|
||||
|
||||
/* LiveView specific CSS */
|
||||
@import "phx-liveview";
|
||||
|
||||
/* Navbar toggler icon override */
|
||||
@import "nav-burger";
|
||||
|
||||
/* extra */
|
||||
.was-validated .no-valid-style .form-check-input:valid,
|
||||
.form-check-input.is-valid {
|
||||
border-color: inherit !important;
|
||||
}
|
||||
.was-validated .no-valid-style .form-check-input:valid ~ .form-check-label,
|
||||
.no-valid-style .form-check-input.is-valid ~ .form-check-label {
|
||||
color: inherit !important;
|
||||
}
|
||||
.table-nonfluid {
|
||||
width: auto !important;
|
||||
}
|
||||
.cursor-pointer {
|
||||
cursor: pointer !important;
|
||||
}
|
||||
|
||||
.phx-click-loading {
|
||||
opacity: 0.5;
|
||||
transition: opacity 1s ease-out;
|
||||
/*
|
||||
icons in input fields
|
||||
*/
|
||||
/* enable absolute positioning */
|
||||
.inner-addon {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.phx-disconnected{
|
||||
cursor: wait;
|
||||
}
|
||||
.phx-disconnected *{
|
||||
/* style icon */
|
||||
.inner-addon > .icon {
|
||||
position: absolute;
|
||||
padding: 0.5625rem 0.5rem;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.phx-modal {
|
||||
opacity: 1!important;
|
||||
position: fixed;
|
||||
z-index: 1;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
background-color: rgb(0,0,0);
|
||||
background-color: rgba(0,0,0,0.4);
|
||||
/* align icon */
|
||||
.inner-addon > .icon.is-left {
|
||||
left: 0px;
|
||||
}
|
||||
.inner-addon > .icon.is-right {
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
.phx-modal-content {
|
||||
background-color: #fefefe;
|
||||
margin: 15% auto;
|
||||
padding: 20px;
|
||||
border: 1px solid #888;
|
||||
width: 80%;
|
||||
/* add padding */
|
||||
.left-addon input,
|
||||
.left-addon select {
|
||||
padding-left: 2rem;
|
||||
}
|
||||
|
||||
.phx-modal-close {
|
||||
color: #aaa;
|
||||
float: right;
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.phx-modal-close:hover,
|
||||
.phx-modal-close:focus {
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
/* Alerts and form errors */
|
||||
.alert {
|
||||
padding: 15px;
|
||||
margin-bottom: 20px;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.alert-info {
|
||||
color: #31708f;
|
||||
background-color: #d9edf7;
|
||||
border-color: #bce8f1;
|
||||
}
|
||||
.alert-warning {
|
||||
color: #8a6d3b;
|
||||
background-color: #fcf8e3;
|
||||
border-color: #faebcc;
|
||||
}
|
||||
.alert-danger {
|
||||
color: #a94442;
|
||||
background-color: #f2dede;
|
||||
border-color: #ebccd1;
|
||||
}
|
||||
.alert p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.alert:empty {
|
||||
display: none;
|
||||
}
|
||||
.invalid-feedback {
|
||||
color: #a94442;
|
||||
display: block;
|
||||
margin: -1rem 0 2rem;
|
||||
.right-addon input,
|
||||
.right-addon select {
|
||||
padding-right: 2rem;
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
12
assets/js/_hamburger-helper.js
Normal file
12
assets/js/_hamburger-helper.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
const togglerBtn = document.getElementById("navbarSupportedContentToggler");
|
||||
const navbarContent = document.getElementById("navbarSupportedContent");
|
||||
|
||||
navbarContent.addEventListener("show.bs.collapse", () => {
|
||||
console.log("opening navbar content");
|
||||
togglerBtn.classList.toggle("is-active");
|
||||
});
|
||||
|
||||
navbarContent.addEventListener("hide.bs.collapse", () => {
|
||||
console.log("closing navbar content");
|
||||
togglerBtn.classList.toggle("is-active");
|
||||
});
|
|
@ -1,7 +1,12 @@
|
|||
// We need to import the CSS so that webpack will load it.
|
||||
// The MiniCssExtractPlugin is used to separate it out into
|
||||
// its own CSS file.
|
||||
import "../css/app.scss"
|
||||
import "../css/app.scss";
|
||||
|
||||
// Import icons for sprite-loader
|
||||
// navbar brand icon
|
||||
import "../node_modules/@mdi/svg/svg/desktop-classic.svg"; // brand
|
||||
// other:///
|
||||
|
||||
// webpack automatically bundles all modules in your
|
||||
// entry points. Those entry points can be configured
|
||||
|
@ -12,25 +17,34 @@ import "../css/app.scss"
|
|||
// import {Socket} from "phoenix"
|
||||
// import socket from "./socket"
|
||||
//
|
||||
import "phoenix_html"
|
||||
import {Socket} from "phoenix"
|
||||
import topbar from "topbar"
|
||||
import {LiveSocket} from "phoenix_live_view"
|
||||
import "phoenix_html";
|
||||
import { Socket } from "phoenix";
|
||||
import topbar from "topbar";
|
||||
import { LiveSocket } from "phoenix_live_view";
|
||||
|
||||
let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
|
||||
let liveSocket = new LiveSocket("/live", Socket, {params: {_csrf_token: csrfToken}})
|
||||
// // Bootstrap v5 js imports
|
||||
import "bootstrap/js/dist/collapse";
|
||||
// import "bootstrap/js/dist/dropdown";
|
||||
// Bootstrap helpers
|
||||
import "./_hamburger-helper";
|
||||
|
||||
let csrfToken = document
|
||||
.querySelector("meta[name='csrf-token']")
|
||||
.getAttribute("content");
|
||||
let liveSocket = new LiveSocket("/live", Socket, {
|
||||
params: { _csrf_token: csrfToken },
|
||||
});
|
||||
|
||||
// Show progress bar on live navigation and form submits
|
||||
topbar.config({barColors: {0: "#29d"}, shadowColor: "rgba(0, 0, 0, .3)"})
|
||||
window.addEventListener("phx:page-loading-start", info => topbar.show())
|
||||
window.addEventListener("phx:page-loading-stop", info => topbar.hide())
|
||||
topbar.config({ barColors: { 0: "#29d" }, shadowColor: "rgba(0, 0, 0, .3)" });
|
||||
window.addEventListener("phx:page-loading-start", (info) => topbar.show());
|
||||
window.addEventListener("phx:page-loading-stop", (info) => topbar.hide());
|
||||
|
||||
// connect if there are any LiveViews on the page
|
||||
liveSocket.connect()
|
||||
liveSocket.connect();
|
||||
|
||||
// expose liveSocket on window for web console debug logs and latency simulation:
|
||||
// >> liveSocket.enableDebug()
|
||||
// >> liveSocket.enableLatencySim(1000) // enabled for duration of browser session
|
||||
// >> liveSocket.disableLatencySim()
|
||||
window.liveSocket = liveSocket
|
||||
|
||||
window.liveSocket = liveSocket;
|
||||
|
|
13736
assets/package-lock.json
generated
13736
assets/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -3,28 +3,43 @@
|
|||
"description": " ",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"deploy": "webpack --mode production",
|
||||
"deploy": "NODE_ENV=production webpack --mode production",
|
||||
"watch": "webpack --mode development --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fontsource/fira-code": "^4.x",
|
||||
"@fontsource/fira-mono": "^4.x",
|
||||
"@fontsource/lato": "^4.x",
|
||||
"@fontsource/righteous": "^4.x",
|
||||
"@mdi/svg": "^5.9.55",
|
||||
"@popperjs/core": "^2.8.4",
|
||||
"bootstrap": "^5.0.0-beta3",
|
||||
"bootstrap-icons": "^1.4.0",
|
||||
"hamburgers": "^1.1.3",
|
||||
"phoenix": "file:../deps/phoenix",
|
||||
"phoenix_html": "file:../deps/phoenix_html",
|
||||
"phoenix_live_view": "file:../deps/phoenix_live_view",
|
||||
"topbar": "^0.1.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.0.0",
|
||||
"@babel/preset-env": "^7.0.0",
|
||||
"babel-loader": "^8.0.0",
|
||||
"copy-webpack-plugin": "^5.1.1",
|
||||
"css-loader": "^3.4.2",
|
||||
"hard-source-webpack-plugin": "^0.13.1",
|
||||
"mini-css-extract-plugin": "^0.9.0",
|
||||
"node-sass": "^4.13.1",
|
||||
"optimize-css-assets-webpack-plugin": "^5.0.1",
|
||||
"sass-loader": "^8.0.2",
|
||||
"terser-webpack-plugin": "^2.3.2",
|
||||
"webpack": "^4.41.5",
|
||||
"webpack-cli": "^3.3.2"
|
||||
"@babel/core": "^7.x",
|
||||
"@babel/preset-env": "^7.x",
|
||||
"autoprefixer": "^10.2.4",
|
||||
"babel-loader": "^8.x",
|
||||
"copy-webpack-plugin": "^8.x",
|
||||
"css-loader": "^5.x",
|
||||
"css-minimizer-webpack-plugin": "^1.x",
|
||||
"file-loader": "^6.2.0",
|
||||
"glob-all": "^3.2.1",
|
||||
"mini-css-extract-plugin": "^1.x",
|
||||
"postcss": "^8.2.6",
|
||||
"postcss-loader": "^5.0.0",
|
||||
"postcss-scss": "^3.0.4",
|
||||
"purgecss-webpack-plugin": "^4.0.2",
|
||||
"sass": "^1.x",
|
||||
"sass-loader": "^11.x",
|
||||
"svg-sprite-loader": "^6.x",
|
||||
"webpack": "^5.x",
|
||||
"webpack-cli": "^4.x"
|
||||
}
|
||||
}
|
||||
|
|
4
assets/postcss.config.js
Normal file
4
assets/postcss.config.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
module.exports = {
|
||||
parser: require("postcss-scss"),
|
||||
plugins: [require("autoprefixer")],
|
||||
};
|
|
@ -1,53 +1,105 @@
|
|||
const path = require('path');
|
||||
const glob = require('glob');
|
||||
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
const TerserPlugin = require('terser-webpack-plugin');
|
||||
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
||||
const path = require("path");
|
||||
const glob = require("glob-all");
|
||||
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
||||
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
|
||||
const CopyWebpackPlugin = require("copy-webpack-plugin");
|
||||
const SpriteLoaderPlugin = require("svg-sprite-loader/plugin");
|
||||
const PurgecssPlugin = require("purgecss-webpack-plugin");
|
||||
|
||||
module.exports = (env, options) => {
|
||||
const devMode = options.mode !== 'production';
|
||||
const devMode = options.mode !== "production";
|
||||
|
||||
return {
|
||||
optimization: {
|
||||
minimizer: [
|
||||
new TerserPlugin({ cache: true, parallel: true, sourceMap: devMode }),
|
||||
new OptimizeCSSAssetsPlugin({})
|
||||
]
|
||||
},
|
||||
entry: {
|
||||
'app': glob.sync('./vendor/**/*.js').concat(['./js/app.js'])
|
||||
app: glob.sync("./vendor/**/*.js").concat(["./js/app.js"]),
|
||||
},
|
||||
output: {
|
||||
filename: '[name].js',
|
||||
path: path.resolve(__dirname, '../priv/static/js'),
|
||||
publicPath: '/js/'
|
||||
path: path.resolve(__dirname, "../priv/static/js"),
|
||||
filename: "[name].js",
|
||||
publicPath: "/js/",
|
||||
},
|
||||
devtool: devMode ? 'eval-cheap-module-source-map' : undefined,
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.js$/,
|
||||
exclude: /node_modules/,
|
||||
use: {
|
||||
loader: 'babel-loader'
|
||||
}
|
||||
loader: "babel-loader",
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.[s]?css$/,
|
||||
use: [
|
||||
MiniCssExtractPlugin.loader,
|
||||
'css-loader',
|
||||
'sass-loader',
|
||||
"css-loader",
|
||||
"sass-loader",
|
||||
"postcss-loader",
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.(woff(2)?|ttf|eot)(\?v=\d+\.\d+\.\d+)?$/,
|
||||
use: [
|
||||
{
|
||||
loader: "file-loader",
|
||||
options: {
|
||||
esModule: false,
|
||||
name: "[name].[ext]",
|
||||
outputPath: "../fonts",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.svg$/,
|
||||
loader: "svg-sprite-loader",
|
||||
options: {
|
||||
extract: true,
|
||||
spriteFilename: "icons.svg",
|
||||
publicPath: "../images/",
|
||||
symbolId: (filePath) => {
|
||||
if (filePath.includes("bootstrap-icons")) {
|
||||
return `bi-${path.basename(filePath).slice(0, -4)}`;
|
||||
} else if (filePath.includes("@mdi")) {
|
||||
return `mdi-${path.basename(filePath).slice(0, -4)}`;
|
||||
} else if (filePath.includes("heroicons")) {
|
||||
if (filePath.includes("outline")) {
|
||||
return `hio-${path.basename(filePath).slice(0, -4)}`;
|
||||
} else {
|
||||
return `his-${path.basename(filePath).slice(0, -4)}`;
|
||||
}
|
||||
]
|
||||
} else {
|
||||
return `${path.basename(filePath).slice(0, -4)}`;
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new MiniCssExtractPlugin({ filename: '../css/app.css' }),
|
||||
new CopyWebpackPlugin([{ from: 'static/', to: '../' }])
|
||||
new MiniCssExtractPlugin({ filename: "../css/app.css" }),
|
||||
new SpriteLoaderPlugin({ plainSprite: true }),
|
||||
new CopyWebpackPlugin({
|
||||
patterns: [{ from: "static/", to: "../" }],
|
||||
}),
|
||||
].concat(
|
||||
devMode
|
||||
? []
|
||||
: [
|
||||
new PurgecssPlugin({
|
||||
paths: glob.sync([
|
||||
"../**/*.html.leex",
|
||||
"../**/*.html.eex",
|
||||
"../**/views/**/*.ex",
|
||||
"../**/live/**/*.ex",
|
||||
"./js/**/*.js",
|
||||
]),
|
||||
safelist: [/phx/, /topbar/],
|
||||
}),
|
||||
]
|
||||
.concat(devMode ? [new HardSourceWebpackPlugin()] : [])
|
||||
}
|
||||
),
|
||||
optimization: {
|
||||
minimizer: ["...", new CssMinimizerPlugin()],
|
||||
},
|
||||
devtool: devMode ? "source-map" : undefined,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -7,6 +7,11 @@
|
|||
# General application configuration
|
||||
use Mix.Config
|
||||
|
||||
config :elixir, :time_zone_database, Tzdata.TimeZoneDatabase
|
||||
|
||||
# Custom application global variables
|
||||
config :home73k, :app_global_vars, time_zone: "America/New_York"
|
||||
|
||||
# Configures the endpoint
|
||||
config :home73k, Home73kWeb.Endpoint,
|
||||
url: [host: "localhost"],
|
||||
|
|
|
@ -16,7 +16,8 @@ config :home73k, Home73kWeb.Endpoint,
|
|||
"node_modules/webpack/bin/webpack.js",
|
||||
"--mode",
|
||||
"development",
|
||||
"--watch-stdin",
|
||||
"--watch",
|
||||
"--watch-options-stdin",
|
||||
cd: Path.expand("../assets", __DIR__)
|
||||
]
|
||||
]
|
||||
|
|
|
@ -6,4 +6,9 @@ defmodule Home73k do
|
|||
Contexts are also responsible for managing your data, regardless
|
||||
if it comes from the database, an external API or others.
|
||||
"""
|
||||
|
||||
@app_vars Application.get_env(:bones73k, :app_global_vars, time_zone: "America/New_York")
|
||||
@app_time_zone @app_vars[:time_zone]
|
||||
|
||||
def app_time_zone, do: @app_time_zone
|
||||
end
|
||||
|
|
|
@ -31,7 +31,8 @@ defmodule Home73kWeb do
|
|||
quote do
|
||||
use Phoenix.View,
|
||||
root: "lib/home73k_web/templates",
|
||||
namespace: Home73kWeb
|
||||
namespace: Home73kWeb,
|
||||
pattern: "**/*"
|
||||
|
||||
# Import convenience functions from controllers
|
||||
import Phoenix.Controller,
|
||||
|
@ -48,6 +49,7 @@ defmodule Home73kWeb do
|
|||
layout: {Home73kWeb.LayoutView, "live.html"}
|
||||
|
||||
unquote(view_helpers())
|
||||
import Home73kWeb.LiveHelpers
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -56,6 +58,7 @@ defmodule Home73kWeb do
|
|||
use Phoenix.LiveComponent
|
||||
|
||||
unquote(view_helpers())
|
||||
import Home73kWeb.LiveHelpers
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -87,6 +90,9 @@ defmodule Home73kWeb do
|
|||
# Import basic rendering functionality (render, render_layout, etc)
|
||||
import Phoenix.View
|
||||
|
||||
# Import SVG Icon helper
|
||||
import Home73kWeb.IconHelpers
|
||||
|
||||
import Home73kWeb.ErrorHelpers
|
||||
import Home73kWeb.Gettext
|
||||
alias Home73kWeb.Router.Helpers, as: Routes
|
||||
|
|
|
@ -23,7 +23,7 @@ defmodule Home73kWeb.Endpoint do
|
|||
plug Plug.Static,
|
||||
at: "/",
|
||||
from: :home73k,
|
||||
gzip: false,
|
||||
gzip: true,
|
||||
only: ~w(css fonts images js favicon.ico robots.txt)
|
||||
|
||||
# Code reloading can be explicitly enabled under the
|
||||
|
|
13
lib/home73k_web/live/live_helpers.ex
Normal file
13
lib/home73k_web/live/live_helpers.ex
Normal file
|
@ -0,0 +1,13 @@
|
|||
defmodule Home73kWeb.LiveHelpers do
|
||||
@doc """
|
||||
Performs the {:noreply, socket} for a given socket.
|
||||
This helps make the noreply pipeable
|
||||
"""
|
||||
def live_noreply(socket), do: {:noreply, socket}
|
||||
|
||||
@doc """
|
||||
Performs the {:ok, socket} for a given socket.
|
||||
This helps make the ok reply pipeable
|
||||
"""
|
||||
def live_okreply(socket), do: {:ok, socket}
|
||||
end
|
|
@ -3,7 +3,7 @@ defmodule Home73kWeb.PageLive do
|
|||
|
||||
@impl true
|
||||
def mount(_params, _session, socket) do
|
||||
{:ok, assign(socket, query: "", results: %{})}
|
||||
{:ok, assign(socket, query: "", results: %{}, page_title: "~")}
|
||||
end
|
||||
|
||||
@impl true
|
||||
|
|
61
lib/home73k_web/templates/layout/_navbar.html.eex
Normal file
61
lib/home73k_web/templates/layout/_navbar.html.eex
Normal file
|
@ -0,0 +1,61 @@
|
|||
<nav class="navbar navbar-expand-lg navbar-light bg-light mb-4">
|
||||
<div class="container">
|
||||
|
||||
<h1 class="fs-4 my-0 py-0 lh-base">
|
||||
<%= link to: Routes.page_path(@conn, :index), class: "navbar-brand fs-4" do %>
|
||||
<%= icon_div @conn, "mdi-desktop-classic", [class: "icon baseline me-1 fs-3"] %>
|
||||
<span class="fw-light" style="font-family: Righteous;">\\AdamPion73k</span>
|
||||
<% end %>
|
||||
</h1>
|
||||
|
||||
<button class="hamburger hamburger--squeeze collapsed navbar-toggler" id="navbarSupportedContentToggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="hamburger-box d-flex">
|
||||
<span class="hamburger-inner"></span>
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||
|
||||
<%# nav LEFT items %>
|
||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||
|
||||
<%# ACTIVE page link example %>
|
||||
<%# <li class="nav-item">
|
||||
<a class="nav-link active" aria-current="page" href="#">Home</a>
|
||||
</li> %>
|
||||
|
||||
<%# DISABLED page link example %>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
|
||||
</li>
|
||||
|
||||
<%# <li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownExample" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</a>
|
||||
<ul class="dropdown-menu" aria-labelledby="navbarDropdownExample">
|
||||
<li><a class="dropdown-item" href="#">Action</a></li>
|
||||
<li><a class="dropdown-item" href="#">Another action</a></li>
|
||||
<li><hr class="dropdown-divider"></li>
|
||||
<li><a class="dropdown-item" href="#">Something else here</a></li>
|
||||
</ul>
|
||||
</li> %>
|
||||
|
||||
</ul>
|
||||
|
||||
<%# nav RIGHT items %>
|
||||
<ul class="navbar-nav">
|
||||
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" aria-current="page" href="#">Resume</a>
|
||||
</li>
|
||||
|
||||
<%= link nav_link_opts(@conn, to: Routes.page_path(@conn, :index), class: "btn btn-outline-dark d-none d-lg-block") do %>
|
||||
<%#= icon_div @conn, "bi-door-open", [class: "icon baseline"] %>
|
||||
Log in
|
||||
<% end %>
|
||||
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
|
@ -1,5 +1,19 @@
|
|||
<main role="main" class="container">
|
||||
<p class="alert alert-info" role="alert"><%= get_flash(@conn, :info) %></p>
|
||||
<p class="alert alert-danger" role="alert"><%= get_flash(@conn, :error) %></p>
|
||||
|
||||
<%# phoenix flash alerts: %>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-12 col-lg-10 col-xxl-8 ">
|
||||
<%= for {kind, class} <- alert_kinds() do %>
|
||||
<%= if flash_content = get_flash(@conn, kind) do %>
|
||||
<div class="alert <%= class %> alert-dismissible fade show" role="alert">
|
||||
<%= flash_content %>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= @inner_content %>
|
||||
|
||||
</main>
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
<main role="main" class="container">
|
||||
<p class="alert alert-info" role="alert"
|
||||
phx-click="lv:clear-flash"
|
||||
phx-value-key="info"><%= live_flash(@flash, :info) %></p>
|
||||
|
||||
<p class="alert alert-danger" role="alert"
|
||||
phx-click="lv:clear-flash"
|
||||
phx-value-key="error"><%= live_flash(@flash, :error) %></p>
|
||||
<%# liveview flash alerts: %>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-12 col-lg-10 col-xxl-8 ">
|
||||
<%= for {kind, class} <- alert_kinds() do %>
|
||||
<%= if flash_content = live_flash(@flash, kind) do %>
|
||||
<div class="alert <%= class %> alert-dismissible fade show" role="alert" id="lv-alert-<%= kind %>" phx-hook="AlertRemover" data-key="<%= kind %>">
|
||||
<%= flash_content %>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= @inner_content %>
|
||||
|
||||
</main>
|
||||
|
|
29
lib/home73k_web/templates/layout/navbar/_user_menu.html.eex
Normal file
29
lib/home73k_web/templates/layout/navbar/_user_menu.html.eex
Normal file
|
@ -0,0 +1,29 @@
|
|||
<li class="nav-item dropdown">
|
||||
|
||||
<a href="#" class="nav-link dropdown-toggle" id="navbarDropdownUserMenu" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<%= icon_div @conn, "bi-person-circle", [class: "icon baseline me-1"] %>
|
||||
Hello
|
||||
</a>
|
||||
|
||||
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdownUserMenu">
|
||||
|
||||
<li><hr class="dropdown-divider"></li>
|
||||
|
||||
<li>
|
||||
<%= link nav_link_opts(@conn, to: Routes.page_path(@conn, :index), class: "dropdown-item") do %>
|
||||
<%= icon_div @conn, "bi-people", [class: "icon baseline me-1"] %>
|
||||
Users
|
||||
<% end %>
|
||||
</li>
|
||||
<li><hr class="dropdown-divider"></li>
|
||||
|
||||
<li>
|
||||
<%= link nav_link_opts(@conn, to: Routes.page_path(@conn, :index), class: "dropdown-item") do %>
|
||||
<%= icon_div @conn, "bi-sliders", [class: "icon baseline me-1"] %>
|
||||
Settings
|
||||
<% end %>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</li>
|
|
@ -5,26 +5,19 @@
|
|||
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<%= csrf_meta_tag() %>
|
||||
<%= live_title_tag assigns[:page_title] || "Home73k", suffix: " · Phoenix Framework" %>
|
||||
<%= live_title_tag assigns[:page_title] || "", prefix: assigns[:page_title] && "73k.us \\ " || "73k.us" %>
|
||||
<meta name="author" content="Adam Piontek"/>
|
||||
<link rel="me" href="mailto:adam@73k.us"/>
|
||||
<link rel="me" href="sms:+16462341697"/>
|
||||
<link rel="authorization_endpoint" href="https://indieauth.com/auth"/>
|
||||
<link phx-track-static rel="stylesheet" href="<%= Routes.static_path(@conn, "/css/app.css") %>"/>
|
||||
<script defer phx-track-static type="text/javascript" src="<%= Routes.static_path(@conn, "/js/app.js") %>"></script>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<section class="container">
|
||||
<nav role="navigation">
|
||||
<ul>
|
||||
<li><a href="https://hexdocs.pm/phoenix/overview.html">Get Started</a></li>
|
||||
<%= if function_exported?(Routes, :live_dashboard_path, 2) do %>
|
||||
<li><%= link "LiveDashboard", to: Routes.live_dashboard_path(@conn, :home) %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</nav>
|
||||
<a href="https://phoenixframework.org/" class="phx-logo">
|
||||
<img src="<%= Routes.static_path(@conn, "/images/phoenix.png") %>" alt="Phoenix Framework Logo"/>
|
||||
</a>
|
||||
</section>
|
||||
</header>
|
||||
|
||||
<%= render "_navbar.html", assigns %>
|
||||
|
||||
<%= @inner_content %>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
38
lib/home73k_web/views/icon_helpers.ex
Normal file
38
lib/home73k_web/views/icon_helpers.ex
Normal file
|
@ -0,0 +1,38 @@
|
|||
defmodule Home73kWeb.IconHelpers do
|
||||
@moduledoc """
|
||||
Generate SVG sprite use tags for SVG icons
|
||||
"""
|
||||
|
||||
use Phoenix.HTML
|
||||
alias Home73kWeb.Router.Helpers, as: Routes
|
||||
|
||||
def icon_div(conn, name, div_opts \\ [], svg_opts \\ []) do
|
||||
content_tag(:div, tag_opts(name, div_opts)) do
|
||||
icon_svg(conn, name, svg_opts)
|
||||
end
|
||||
end
|
||||
|
||||
def icon_svg(conn, name, opts \\ []) do
|
||||
opts = aria_hidden?(opts)
|
||||
|
||||
content_tag(:svg, tag_opts(name, opts)) do
|
||||
~E"""
|
||||
<%= if title = Keyword.get(opts, :aria_label), do: content_tag(:title, title) %>
|
||||
<%= tag(:use, "xlink:href": Routes.static_path(conn, "/images/icons.svg##{name}")) %>
|
||||
"""
|
||||
end
|
||||
end
|
||||
|
||||
defp tag_opts(name, opts) do
|
||||
Keyword.update(opts, :class, name, fn c -> "#{c} #{name}" end)
|
||||
end
|
||||
|
||||
defp aria_hidden?(opts) do
|
||||
case Keyword.get(opts, :aria_hidden) do
|
||||
"false" -> Keyword.drop(opts, [:aria_hidden])
|
||||
false -> Keyword.drop(opts, [:aria_hidden])
|
||||
"true" -> opts
|
||||
_ -> Keyword.put(opts, :aria_hidden, "true")
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,3 +1,21 @@
|
|||
defmodule Home73kWeb.LayoutView do
|
||||
use Home73kWeb, :view
|
||||
|
||||
def nav_link_opts(conn, opts) do
|
||||
case Keyword.get(opts, :to) == Phoenix.Controller.current_path(conn) do
|
||||
false -> opts
|
||||
true -> Keyword.update(opts, :class, "active", fn c -> "#{c} active" end)
|
||||
end
|
||||
end
|
||||
|
||||
def alert_kinds do
|
||||
[
|
||||
success: "alert-success",
|
||||
info: "alert-info",
|
||||
error: "alert-danger",
|
||||
warning: "alert-warning",
|
||||
primary: "alert-primary",
|
||||
secondary: "alert-secondary"
|
||||
]
|
||||
end
|
||||
end
|
||||
|
|
8
mix.exs
8
mix.exs
|
@ -43,7 +43,13 @@ defmodule Home73k.MixProject do
|
|||
{:telemetry_poller, "~> 0.4"},
|
||||
{:gettext, "~> 0.11"},
|
||||
{:jason, "~> 1.0"},
|
||||
{:plug_cowboy, "~> 2.0"}
|
||||
{:plug_cowboy, "~> 2.0"},
|
||||
{:tzdata, "~> 1.1"},
|
||||
|
||||
# Additional packages
|
||||
|
||||
{:credo, "~> 1.5", only: [:dev, :test], runtime: false},
|
||||
{:sobelow, "~> 0.8", only: :dev}
|
||||
]
|
||||
end
|
||||
|
||||
|
|
12
mix.lock
12
mix.lock
|
@ -1,13 +1,21 @@
|
|||
%{
|
||||
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"},
|
||||
"certifi": {:hex, :certifi, "2.6.1", "dbab8e5e155a0763eea978c913ca280a6b544bfa115633fa20249c3d396d9493", [:rebar3], [], "hexpm", "524c97b4991b3849dd5c17a631223896272c6b0af446778ba4675a1dff53bb7e"},
|
||||
"cowboy": {:hex, :cowboy, "2.8.0", "f3dc62e35797ecd9ac1b50db74611193c29815401e53bac9a5c0577bd7bc667d", [:rebar3], [{:cowlib, "~> 2.9.1", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "4643e4fba74ac96d4d152c75803de6fad0b3fa5df354c71afdd6cbeeb15fac8a"},
|
||||
"cowboy_telemetry": {:hex, :cowboy_telemetry, "0.3.1", "ebd1a1d7aff97f27c66654e78ece187abdc646992714164380d8a041eda16754", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3a6efd3366130eab84ca372cbd4a7d3c3a97bdfcfb4911233b035d117063f0af"},
|
||||
"cowlib": {:hex, :cowlib, "2.9.1", "61a6c7c50cf07fdd24b2f45b89500bb93b6686579b069a89f88cb211e1125c78", [:rebar3], [], "hexpm", "e4175dc240a70d996156160891e1c62238ede1729e45740bdd38064dad476170"},
|
||||
"credo": {:hex, :credo, "1.5.5", "e8f422026f553bc3bebb81c8e8bf1932f498ca03339856c7fec63d3faac8424b", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "dd8623ab7091956a855dc9f3062486add9c52d310dfd62748779c4315d8247de"},
|
||||
"file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"},
|
||||
"floki": {:hex, :floki, "0.30.0", "22ebbe681a5d3777cdd830ca091b1b806d33c3449c26312eadca7f7be685c0c8", [:mix], [{:html_entities, "~> 0.5.0", [hex: :html_entities, repo: "hexpm", optional: false]}], "hexpm", "a9e128a4ca9bb71f11affa315b6768a9ad326d5996ff1e92acf1d7a01a10076a"},
|
||||
"gettext": {:hex, :gettext, "0.18.2", "7df3ea191bb56c0309c00a783334b288d08a879f53a7014341284635850a6e55", [:mix], [], "hexpm", "f9f537b13d4fdd30f3039d33cb80144c3aa1f8d9698e47d7bcbcc8df93b1f5c5"},
|
||||
"hackney": {:hex, :hackney, "1.17.4", "99da4674592504d3fb0cfef0db84c3ba02b4508bae2dff8c0108baa0d6e0977c", [:rebar3], [{:certifi, "~>2.6.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "de16ff4996556c8548d512f4dbe22dd58a587bf3332e7fd362430a7ef3986b16"},
|
||||
"html_entities": {:hex, :html_entities, "0.5.2", "9e47e70598da7de2a9ff6af8758399251db6dbb7eebe2b013f2bbd2515895c3c", [:mix], [], "hexpm", "c53ba390403485615623b9531e97696f076ed415e8d8058b1dbaa28181f4fdcc"},
|
||||
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},
|
||||
"jason": {:hex, :jason, "1.2.2", "ba43e3f2709fd1aa1dce90aaabfd039d000469c05c56f0b8e31978e03fa39052", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "18a228f5f0058ee183f29f9eae0805c6e59d61c3b006760668d8d18ff0d12179"},
|
||||
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
|
||||
"mime": {:hex, :mime, "1.5.0", "203ef35ef3389aae6d361918bf3f952fa17a09e8e43b5aa592b93eba05d0fb8d", [:mix], [], "hexpm", "55a94c0f552249fc1a3dd9cd2d3ab9de9d3c89b559c2bd01121f824834f24746"},
|
||||
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
|
||||
"parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"},
|
||||
"phoenix": {:hex, :phoenix, "1.5.8", "71cfa7a9bb9a37af4df98939790642f210e35f696b935ca6d9d9c55a884621a4", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.13", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.1.2 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "35ded0a32f4836168c7ab6c33b88822eccd201bcd9492125a9bea4c54332d955"},
|
||||
"phoenix_html": {:hex, :phoenix_html, "2.14.3", "51f720d0d543e4e157ff06b65de38e13303d5778a7919bcc696599e5934271b8", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "efd697a7fff35a13eeeb6b43db884705cba353a1a41d127d118fda5f90c8e80f"},
|
||||
"phoenix_live_dashboard": {:hex, :phoenix_live_dashboard, "0.4.0", "87990e68b60213d7487e65814046f9a2bed4a67886c943270125913499b3e5c3", [:mix], [{:ecto_psql_extras, "~> 0.4.1 or ~> 0.5", [hex: :ecto_psql_extras, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.14.1 or ~> 2.15", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.15.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.4.0 or ~> 0.5.0 or ~> 0.6.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "8d52149e58188e9e4497cc0d8900ab94d9b66f96998ec38c47c7a4f8f4f50e57"},
|
||||
|
@ -18,7 +26,11 @@
|
|||
"plug_cowboy": {:hex, :plug_cowboy, "2.4.1", "779ba386c0915027f22e14a48919a9545714f849505fa15af2631a0d298abf0f", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d72113b6dff7b37a7d9b2a5b68892808e3a9a752f2bf7e503240945385b70507"},
|
||||
"plug_crypto": {:hex, :plug_crypto, "1.2.2", "05654514ac717ff3a1843204b424477d9e60c143406aa94daf2274fdd280794d", [:mix], [], "hexpm", "87631c7ad914a5a445f0a3809f99b079113ae4ed4b867348dd9eec288cecb6db"},
|
||||
"ranch": {:hex, :ranch, "1.7.1", "6b1fab51b49196860b733a49c07604465a47bdb78aa10c1c16a3d199f7f8c881", [:rebar3], [], "hexpm", "451d8527787df716d99dc36162fca05934915db0b6141bbdac2ea8d3c7afc7d7"},
|
||||
"sobelow": {:hex, :sobelow, "0.11.1", "23438964486f8112b41e743bbfd402da3e5b296fdc9eacab29914b79c48916dd", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "9897363a7eff96f4809304a90aad819e2ad5e5d24db547af502885146746a53c"},
|
||||
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"},
|
||||
"telemetry": {:hex, :telemetry, "0.4.2", "2808c992455e08d6177322f14d3bdb6b625fbcfd233a73505870d8738a2f4599", [:rebar3], [], "hexpm", "2d1419bd9dda6a206d7b5852179511722e2b18812310d304620c7bd92a13fcef"},
|
||||
"telemetry_metrics": {:hex, :telemetry_metrics, "0.6.0", "da9d49ee7e6bb1c259d36ce6539cd45ae14d81247a2b0c90edf55e2b50507f7b", [:mix], [{:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "5cfe67ad464b243835512aa44321cee91faed6ea868d7fb761d7016e02915c3d"},
|
||||
"telemetry_poller": {:hex, :telemetry_poller, "0.5.1", "21071cc2e536810bac5628b935521ff3e28f0303e770951158c73eaaa01e962a", [:rebar3], [{:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4cab72069210bc6e7a080cec9afffad1b33370149ed5d379b81c7c5f0c663fd4"},
|
||||
"tzdata": {:hex, :tzdata, "1.1.0", "72f5babaa9390d0f131465c8702fa76da0919e37ba32baa90d93c583301a8359", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "18f453739b48d3dc5bcf0e8906d2dc112bb40baafe2c707596d89f3c8dd14034"},
|
||||
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue