Compare commits

...

9 Commits

Author SHA1 Message Date
81843f0c08 chore: remove unused jQuery and Bootstrap dependencies
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
- Deleted the `add_jquery.js` file as jQuery is no longer needed.
- Removed references to Bootstrap from the Gemfile and package.json.
- Updated the application layout to reflect the removal of Bootstrap styles.
- Adjusted the paginator HTML to use a class that aligns with the new styling.

These changes streamline the asset pipeline by eliminating unused libraries,
which can improve load times and reduce potential security vulnerabilities.
The application now relies on alternative styling and JavaScript solutions.
2025-01-17 17:08:07 +08:00
0335ef4ed6 refactor: replace list items with buttons in pagination
- Changed pagination elements from <li> to <button> for better accessibility.
- Updated the paginator structure to use a <div> instead of <ul>.
- Ensured that all pagination links are now buttons, improving the user experience.

These changes enhance the semantic structure of the pagination, making it more intuitive and accessible for users, especially those using assistive technologies.
2025-01-17 15:22:13 +08:00
8c598ce3dc chore: remove flowbite dependency
- Remove Flowbite import from application.js
- Update tailwind.config.js to exclude Flowbite
- Delete package-lock.json to reflect the removal of Flowbite

This commit cleans up the project by removing the Flowbite library, which was previously included but is no longer needed. This helps streamline the codebase and may improve performance.
2025-01-17 15:06:51 +08:00
87e0c2eec6 feat: add theme switching and toast notifications
- Implement theme switching functionality with a new ThemeController
- Add ToastController for displaying notifications
- Update various views for improved layout and styling
- Introduce animations for toast notifications

These changes enhance the user experience by allowing users to switch between light and dark themes and receive feedback through toast notifications. The UI has been improved for better accessibility and aesthetics.
2025-01-17 15:02:25 +08:00
42d8d5ce1d feat: enhance layout responsiveness and style
- Update footer layout to improve styling and center alignment
- Change header theme control from 'synthwave' to 'light'
- Enhance home page layout with hero and background styles
- Refactor user sign-up form with better styling and structure
- Add copyright notice and responsive design to the footer

These changes focus on enhancing the overall user experience with a
more modern layout and improved responsiveness across devices. The
footer now includes copyright information and a cleaner design, while
the sign-up form has additional styling to improve usability.
2025-01-17 00:01:13 +08:00
99c5e8afe9 feat: remove unnecessary theme from tailwind config
- Update `tailwind.config.js` to use only `light` and `dark` themes.
- This change improves code maintainability and reduces unnecessary complexity.
- No other components or functionalities are affected by this change.
2025-01-16 21:04:00 +08:00
9ce9feafb7 feat: update layouts and styles
- Update the footer layout to include copyright information and navigation links
- Improve the header layout with a responsive theme switcher
- Configure Tailwind CSS to use light and dark themes

This change enhances the project's user interface and user experience by providing a more visually appealing and responsive design. It includes updates to the footer and header layouts, making it easier for users to navigate the site. Additionally, it configures Tailwind CSS to use light and dark themes, allowing users to customize their experience to suit their preferences.
2025-01-16 21:02:13 +08:00
5456e8ff91 feat: update header layout and add daisyUI
- Refactor header layout from a fixed to a responsive design using
  a navbar component.
- Integrate daisyUI for improved styling and utility classes.
- Ensure that all existing links and dropdown functionalities are
  preserved.
- Modify tailwind.config.js to include daisyUI plugin with
  appropriate theme settings.
- Update package.json to include daisyUI as a dev dependency.

This commit enhances the visual layout and user experience of the
header by making it responsive while streamlining component usage
with daisyUI, which also provides additional UI features.
This change ensures better usability across devices.
2025-01-16 21:02:06 +08:00
cafe820a64 feat: add tailwindcss integration and demo page
- Add tailwindcss-rails gem to Gemfile
- Create application.tailwind.css for Tailwind styles
- Update Procfile.dev for Tailwind CSS watch command
- Add demo action and view for showcasing features
- Update application layout to use Tailwind CSS classes
- Refactor footer and header for improved styling

This commit introduces Tailwind CSS for styling the application, enhancing the UI with utility-first CSS. A new demo page is also added to showcase the application features.
2025-01-16 18:17:08 +08:00
46 changed files with 649 additions and 1834 deletions

View File

@ -70,10 +70,10 @@ group :test do
gem "rails-controller-testing"
end
gem "cssbundling-rails", "~> 1.4"
gem "jsbundling-rails", "~> 1.3"
group :production do
gem "pg", "~> 1.5"
end
gem "tailwindcss-rails", "~> 3.2"

View File

@ -102,8 +102,6 @@ GEM
concurrent-ruby (1.3.4)
connection_pool (2.4.1)
crass (1.0.6)
cssbundling-rails (1.4.1)
railties (>= 6.0.0)
date (3.4.1)
debug (1.10.0)
irb (~> 1.10)
@ -385,6 +383,14 @@ GEM
stimulus-rails (1.3.4)
railties (>= 6.0.0)
stringio (3.1.2)
tailwindcss-rails (3.2.0)
railties (>= 7.0.0)
tailwindcss-ruby
tailwindcss-ruby (3.4.17-aarch64-linux)
tailwindcss-ruby (3.4.17-arm-linux)
tailwindcss-ruby (3.4.17-arm64-darwin)
tailwindcss-ruby (3.4.17-x86_64-darwin)
tailwindcss-ruby (3.4.17-x86_64-linux)
thor (1.3.2)
thruster (0.1.10)
thruster (0.1.10-aarch64-linux)
@ -433,7 +439,6 @@ DEPENDENCIES
bootsnap
brakeman
capybara
cssbundling-rails (~> 1.4)
debug
faker (~> 3.5)
guard (~> 2.19)
@ -455,6 +460,7 @@ DEPENDENCIES
solid_queue
sqlite3 (>= 2.1)
stimulus-rails
tailwindcss-rails (~> 3.2)
thruster
turbo-rails
tzinfo-data

View File

@ -1,3 +1,3 @@
web: env RUBY_DEBUG_OPEN=true bin/rails server
css: yarn watch:css
js: yarn build --watch
css: bin/rails tailwindcss:watch

View File

@ -1,2 +1,3 @@
//= link_tree ../images
// = link_tree ../builds
//= link_tree ../builds

View File

@ -0,0 +1 @@
<svg height='100px' width='100px' fill="#000000" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="0 0 64 64" style="enable-background:new 0 0 64 64;" xml:space="preserve"><g><path d="M15,29c-3.309,0-6,2.691-6,6c0,2.206,1.794,4,4,4s4-1.794,4-4h-2c0,1.103-0.897,2-2,2s-2-0.897-2-2c0-2.206,1.794-4,4-4 c3.309,0,6,2.691,6,6c0,4.411-3.589,8-8,8C7.486,45,3,40.514,3,35c0-4.057,1.984-7.869,5.308-10.195l10.9-7.63 C21.583,15.513,23,12.79,23,9.891C23,4.989,19.011,1,14.109,1C12.395,1,11,2.395,11,4.109v16.371l-3.839,2.687 C3.303,25.867,1,30.291,1,35c0,5.934,4.334,10.863,10,11.819V58c0,1.654-1.346,3-3,3s-3-1.346-3-3c0-0.551,0.449-1,1-1s1,0.449,1,1 v1h2v-1c0-1.654-1.346-3-3-3s-3,1.346-3,3c0,2.757,2.243,5,5,5s5-2.243,5-5V47c5.514,0,10-4.486,10-10C23,32.589,19.411,29,15,29z M13,4.109C13,3.498,13.498,3,14.109,3C17.909,3,21,6.091,21,9.891c0,2.247-1.099,4.357-2.939,5.646L13,19.079V4.109z"></path><path d="M31,45.22l10,2v-8.04l-12-2.4V49h-2c-2.206,0-4,1.794-4,4s1.794,4,4,4s4-1.794,4-4V45.22z M31,39.22l8,1.6v3.96l-8-1.6 V39.22z M29,53c0,1.103-0.897,2-2,2s-2-0.897-2-2s0.897-2,2-2h2V53z"></path><path d="M51,18.895V29h-2c-2.206,0-4,1.794-4,4s1.794,4,4,4s4-1.794,4-4v-5.895l8,0.8V31h-2c-2.206,0-4,1.794-4,4s1.794,4,4,4 s4-1.794,4-4V20.095L51,18.895z M51,33c0,1.103-0.897,2-2,2s-2-0.897-2-2s0.897-2,2-2h2V33z M61,35c0,1.103-0.897,2-2,2 s-2-0.897-2-2s0.897-2,2-2h2V35z M53,25.095v-3.99l8,0.8v3.99L53,25.095z"></path><path d="M43,9h2v12h2V5c0-2.206-1.794-4-4-4s-4,1.794-4,4S40.794,9,43,9z M43,3c1.103,0,2,0.897,2,2v2h-2c-1.103,0-2-0.897-2-2 S41.897,3,43,3z"></path><path d="M29,23c2.206,0,4-1.794,4-4V3h-2v12h-2c-2.206,0-4,1.794-4,4S26.794,23,29,23z M29,17h2v2c0,1.103-0.897,2-2,2 s-2-0.897-2-2S27.897,17,29,17z"></path><path d="M36.792,61.086l0.813,1.828c8.887-3.949,15.894-11.447,19.224-20.572l-1.879-0.686 C51.804,50.275,45.186,57.357,36.792,61.086z"></path><path d="M56.434,16.628c-1.505-3.76-3.624-7.221-6.298-10.286l-1.507,1.314c2.526,2.896,4.527,6.165,5.949,9.715L56.434,16.628z"></path><path d="M53.532,39.309l-1.902-0.617c-3.047,9.39-11.047,16.797-20.879,19.332l0.499,1.937 C41.737,57.256,50.275,49.343,53.532,39.309z"></path><path d="M51.841,16.554c-0.713-1.432-1.547-2.823-2.481-4.134l-1.629,1.16c0.873,1.226,1.653,2.526,2.32,3.866L51.841,16.554z"></path><path d="M34.081,34.615l1.846,0.771C36.639,33.677,37,31.866,37,30c0-2.683-0.761-5.29-2.201-7.539l-1.685,1.078 C34.348,25.466,35,27.7,35,30C35,31.6,34.69,33.152,34.081,34.615z"></path><path d="M41,30c0,2.291-0.424,4.522-1.261,6.631l1.859,0.737C42.528,35.023,43,32.544,43,30c0-6.212-2.815-11.967-7.723-15.79 l-1.229,1.578C38.466,19.229,41,24.409,41,30z"></path></g></svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -1,3 +0,0 @@
@import 'bootstrap/dist/css/bootstrap';
@import 'bootstrap-icons/font/bootstrap-icons';
@import './custom';

View File

@ -0,0 +1,31 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
/*
@layer components {
.btn-primary {
@apply py-2 px-4 bg-blue-200;
}
}
*/
@layer base {
h1, h2, h3, h4, h5, h6 {
@apply leading-none;
}
h1 {
@apply text-[3em] tracking-[-2px] mb-8 mt-8 text-center;
}
h2 {
@apply text-[1.2em] tracking-[-1px] mb-[30px] text-center font-normal text-gray-400;
}
p {
@apply text-[1.1em] leading-[1.7];
}
}

View File

@ -1,201 +0,0 @@
/* color */
$light-gray: #777;
$gray-lighter: #D3D3D3;
/* universal */
body {
padding-top: 60px;
}
section {
overflow: auto;
}
textarea {
resize: vertical;
}
.center {
text-align: center;
h1 {
margin-bottom: 10px;
}
}
/* typography */
h1, h2, h3, h4, h5, h6 {
line-height: 1;
}
h1 {
font-size: 3em;
letter-spacing: -2px;
margin-bottom: 30px;
text-align: center;
}
h2 {
font-size: 1.2em;
letter-spacing: -1px;
margin-bottom: 30px;
text-align: center;
font-weight: normal;
color: $light-gray;
}
p {
font-size: 1.1em;
line-height: 1.7em;
}
/* header */
#logo {
float: left;
margin-right: 10px;
font-size: 1.7em;
color: #fff;
text-transform: uppercase;
letter-spacing: -1px;
padding-top: 9px;
font-weight: bold;
&:hover {
color: $light-gray;
text-decoration: none;
}
}
//img {
// display: none;
//}
/* footer */
footer {
margin-top: 45px;
padding-top: 5px;
border-top: 1px solid #eaeaea;
color: $light-gray;
a {
color: #555;
&hover {
color: #222;
}
}
small {
float: left;
}
ul {
float: right;
list-style: none;
li {
float: left;
margin-left: 15px;
}
}
}
/* mixins, variables, etc. */
$gray-medium-light: #eaeaea;
@mixin box_sizing {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
/* miscellaneous */
.debug_dump {
clear: both;
float: left;
width: 100%;
margin-top: 45px;
@include box-sizing;
}
/* sidebar */
aside {
section.user_info {
margin-top: 20px;
}
section {
padding: 10px 0;
margin-top: 20px;
&:first-child {
border: 0;
padding-top: 0;
}
span{
display: block;
margin-bottom: 3px;
line-height: 1;
}
h1 {
font-size: 1.4em;
text-align: left;
letter-spacing: -1px;
margin-bottom: 3px;
margin-top: 0;
}
}
}
.gravatar {
float: left;
margin-right: 10px;
}
.gravatar_edit {
margin-top: 15px;
}
/* forms */
input, textarea, select, .uneditable-input {
border: 1px solid #bbb;
width: 100%;
margin-bottom: 15px;
@include box_sizing;
}
input {
height: auto !important;
}
/* forms */
#error_explanation {
color: red;
ul {
color: red;
margin: 0 0 30px 0;
}
}
.field_with_errors {
//@extend .has-error;
.form-control {
//color: $state-danger-text;
}
}
.checkbox {
margin-top: -10px;
margin-bottom: 10px;
span {
margin-left: 20px;
font-weight: normal;
}
}
#session_remember_me {
width: auto;
margin-left: 0;
}
/* Users index */
.users {
list-style: none;
margin: 0;
li {
overflow: auto;
padding: 10px 0;
border-bottom: 1px solid $gray-lighter;
}
}

View File

@ -10,4 +10,7 @@ class StaticPagesController < ApplicationController
def contact
end
def demo
end
end

View File

@ -1,3 +0,0 @@
import jquery from 'jquery'
window.jQuery = jquery
window.$ = jquery

View File

@ -1,10 +1,4 @@
// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
import "@hotwired/turbo-rails"
import './add_jquery'
import "jquery/dist/jquery"
import "bootstrap/dist/js/bootstrap"
import "./controllers"

View File

@ -4,3 +4,10 @@
// eagerLoadControllersFrom("controllers", application)
import { application } from "./application"
import ThemeController from "./theme_controller"
import ToastController from "./toast_controller"
import HelloController from "./hello_controller"
application.register("hello", HelloController)
application.register("theme", ThemeController)
application.register("toast", ToastController)

View File

@ -0,0 +1,24 @@
import { Controller } from "@hotwired/stimulus"
// Connects to data-controller="theme"
export default class extends Controller {
static targets = ["toggle"]
connect() {
this.initTheme()
}
initTheme() {
const savedTheme = localStorage.getItem('theme')
if(savedTheme) {
document.documentElement.setAttribute('data-theme', savedTheme)
this.toggleTarget.checked = savedTheme === 'dark'
}
}
toggle(event) {
const newTheme = event.target.checked ? 'dark' : 'light'
document.documentElement.setAttribute('data-theme', newTheme)
localStorage.setItem('theme', newTheme)
}
}

View File

@ -0,0 +1,14 @@
import { Controller } from "@hotwired/stimulus"
// Connects to data-controller="toast"
export default class extends Controller {
connect() {
// 3秒后自动隐藏
setTimeout(() => {
this.element.classList.add('animate-fade-out')
setTimeout(() => {
this.element.remove()
}, 500)
}, 3000)
}
}

View File

@ -0,0 +1,22 @@
// 获取切换按钮
const themeToggle = document.querySelector('.theme-controller');
// 监听变化
themeToggle.addEventListener('change', (e) => {
// 切换 HTML data-theme 属性
if(e.target.checked) {
document.documentElement.setAttribute('data-theme', 'dark');
} else {
document.documentElement.setAttribute('data-theme', 'light');
}
// 保存主题设置到 localStorage
localStorage.setItem('theme', e.target.checked ? 'dark' : 'light');
});
// 页面加载时检查之前的主题设置
const savedTheme = localStorage.getItem('theme');
if(savedTheme) {
document.documentElement.setAttribute('data-theme', savedTheme);
themeToggle.checked = savedTheme === 'dark';
}

View File

@ -1,3 +1,3 @@
<li>
<button class="join-item btn">
<%= link_to_unless current_page.first?, raw(t 'views.pagination.first'), url, remote: remote %>
</li>
</button>

View File

@ -1,3 +1,3 @@
<li class='disabled'>
<button class="join-item btn btn-disabled">
<%= content_tag :a, raw(t 'views.pagination.truncate') %>
</li>
</button>

View File

@ -1,3 +1,3 @@
<li>
<button class="join-item btn">
<%= link_to_unless current_page.last?, raw(t 'views.pagination.last'), url, { remote: remote } %>
</li>
</button>

View File

@ -1,3 +1,3 @@
<li>
<button class="join-item btn">
<%= link_to_unless current_page.last?, raw(t 'views.pagination.next'), url, rel: 'next', remote: remote %>
</li>
</button>

View File

@ -1,9 +1,9 @@
<% if page.current? %>
<li class='active'>
<button class='join-item btn btn-active'>
<%= content_tag :a, page, data: { remote: remote }, rel: page.rel %>
</li>
</button>
<% else %>
<li>
<button class="join-item btn">
<%= link_to page, url, remote: remote, rel: page.rel %>
</li>
</button>
<% end %>

View File

@ -1,5 +1,5 @@
<%= paginator.render do -%>
<ul class="pagination">
<div class="join pagination">
<%= first_page_tag unless current_page.first? %>
<%= prev_page_tag unless current_page.first? %>
<% each_page do |page| -%>
@ -11,5 +11,5 @@
<% end -%>
<%= next_page_tag unless current_page.last? %>
<%= last_page_tag unless current_page.last? %>
</ul>
</div>
<% end -%>

View File

@ -1,3 +1,3 @@
<li>
<button class="join-item btn">
<%= link_to_unless current_page.first?, raw(t 'views.pagination.previous'), url, rel: 'prev', remote: remote %>
</li>
</button>

View File

@ -1,13 +1,10 @@
<footer class="footer">
<small>
The <a href="https://www.railstutorial.org">Ruby on Rails Tutorial</a>
by <a href="https://www.michaelhartl.com">Michael Hartl</a>
</small>
<nav>
<ul>
<li><%= link_to "About", about_url %></li>
<li><%= link_to "Contact", contact_url %></li>
<li><a href="https://news.railstutorial.org">News</a></li>
</ul>
<footer class="footer footer-center bg-base-200 text-base-content rounded p-10 mt-8">
<nav class="grid grid-flow-col gap-4">
<%= link_to "About", about_url, class: "link link-hover" %>
<%= link_to "Contact", contact_url, class: "link link-hover" %>
<a href="https://news.railstutorial.org" class="text-gray-600 hover:text-gray-900">News</a>
</nav>
<aside>
<p>Copyright © <%= Date.current.year %> - All right reserved by ACME Industries Ltd</p>
</aside>
</footer>

View File

@ -1,20 +1,59 @@
<header class="navbar navbar-fixed-top navbar-inverse">
<div class="container">
<%= link_to "sample app", root_url, id: "logo" %>
<nav>
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed"
data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1"
aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<!-- 固定在顶部容器 -->
<div class="fixed top-0 left-0 right-0 z-50">
<!-- 响应式内边距 -->
<!--<div class="container mx-auto px-3 sm:px-6 lg:px-1 py-4">-->
<!-- 顶部菜单栏 -->
<div class="navbar
backdrop-filter backdrop-blur-lg bg-opacity-30 border-b border-gray-200 border-transparent
shadow-md min-h-0 h-12 px-8 lg:px-12">
<div class="navbar-start">
<%= link_to "Today AI Weather", root_url, id: "logo", class: "btn btn-ghost text-xl" %>
</div>
<ul class="nav navbar-nav navbar-right collapse navbar-collapse"
id="bs-example-navbar-collapse-1">
<div class="navbar-end">
<div class="hidden lg:flex">
<ul class="menu menu-horizontal px-1">
<li><%= link_to "Home", root_url %></li>
<li><%= link_to "Help", help_url %></li>
<% if logged_in? %>
<li><%= link_to "Users", users_path %></li>
<li>
<details>
<summary>
Account <b class="caret"></b>
</summary>
<ul class="bg-base-100 rounded-t-none p-2">
<li><%= link_to "Profile", current_user %></li>
<li><%= link_to "Settings", edit_user_path(current_user) %></li>
<div class="divider"></div>
<li>
<%= link_to "Log out", logout_path, data: { turbo_method: :delete } %>
</li>
</ul>
</details>
</li>
<% else %>
<li><%= link_to "Log in", login_path %></li>
<% end %>
</ul>
</div>
<details class="dropdown dropdown-end">
<summary tabindex="0" role="button" class="btn btn-ghost lg:hidden">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M4 6h16M4 12h8m-8 6h16" />
</svg>
</summary>
<ul
tabindex="0"
class="menu menu-sm dropdown-content bg-base-100 rounded-box z-[1] mt-3 w-52 p-2 shadow">
<li><%= link_to "Home", root_url %></li>
<li><%= link_to "Help", help_url %></li>
<% if logged_in? %>
@ -36,7 +75,12 @@
<li><%= link_to "Log in", login_path %></li>
<% end %>
</ul>
</nav>
</details>
<%= render "layouts/theme_swap" %>
</div>
</div>
<!--</div>-->
</div>
</header>
<!-- 添加一个占位 div防止内容被覆盖 -->
<div aria-hidden="true" class="border-none h-12"></div>

View File

@ -0,0 +1,37 @@
<!-- 放在布局文件的 body 标签末尾 -->
<div class="toast toast-end">
<% flash.each do |message_type, message| %>
<% alert_class = case message_type
when "success" then "alert alert-success"
when "danger", "error" then "alert alert-error"
when "warning" then "alert alert-warning"
when "info" then "alert alert-info"
else "alert"
end
%>
<div data-controller="toast" class="<%= alert_class %> animate-slide-in-right">
<div>
<% case message_type %>
<% when "success" %>
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<% when "error", "danger" %>
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<% when "warning" %>
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
</svg>
<% else %>
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<% end %>
<span><%= message %></span>
</div>
</div>
<% end %>
</div>

View File

@ -0,0 +1,29 @@
<div data-controller="theme">
<label class="swap swap-rotate">
<!-- this hidden checkbox controls the state -->
<input
type="checkbox"
class="theme-controller"
data-theme-target="toggle"
data-action="change->theme#toggle"
/>
<!-- sun icon -->
<svg
class="swap-off h-6 w-6 fill-current"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24">
<path
d="M5.64,17l-.71.71a1,1,0,0,0,0,1.41,1,1,0,0,0,1.41,0l.71-.71A1,1,0,0,0,5.64,17ZM5,12a1,1,0,0,0-1-1H3a1,1,0,0,0,0,2H4A1,1,0,0,0,5,12Zm7-7a1,1,0,0,0,1-1V3a1,1,0,0,0-2,0V4A1,1,0,0,0,12,5ZM5.64,7.05a1,1,0,0,0,.7.29,1,1,0,0,0,.71-.29,1,1,0,0,0,0-1.41l-.71-.71A1,1,0,0,0,4.93,6.34Zm12,.29a1,1,0,0,0,.7-.29l.71-.71a1,1,0,1,0-1.41-1.41L17,5.64a1,1,0,0,0,0,1.41A1,1,0,0,0,17.66,7.34ZM21,11H20a1,1,0,0,0,0,2h1a1,1,0,0,0,0-2Zm-9,8a1,1,0,0,0-1,1v1a1,1,0,0,0,2,0V20A1,1,0,0,0,12,19ZM18.36,17A1,1,0,0,0,17,18.36l.71.71a1,1,0,0,0,1.41,0,1,1,0,0,0,0-1.41ZM12,6.5A5.5,5.5,0,1,0,17.5,12,5.51,5.51,0,0,0,12,6.5Zm0,9A3.5,3.5,0,1,1,15.5,12,3.5,3.5,0,0,1,12,15.5Z" />
</svg>
<!-- moon icon -->
<svg
class="swap-on h-6 w-6 fill-current"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24">
<path
d="M21.64,13a1,1,0,0,0-1.05-.14,8.05,8.05,0,0,1-3.37.73A8.15,8.15,0,0,1,9.08,5.49a8.59,8.59,0,0,1,.25-2A1,1,0,0,0,8,2.36,10.14,10.14,0,1,0,22,14.05,1,1,0,0,0,21.64,13Zm-9.5,6.69A8.14,8.14,0,0,1,7.08,5.22v.27A10.15,10.15,0,0,0,17.22,15.63a9.79,9.79,0,0,0,2.1-.22A8.11,8.11,0,0,1,12.14,19.73Z" />
</svg>
</label>
</div>

View File

@ -5,23 +5,50 @@
<title><%= full_title(yield(:title)) %></title>
<%= render 'layouts/rails_default' %>
<%= render 'layouts/shim' %>
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
<%= stylesheet_link_tag "tailwind", "inter-font", "data-turbo-track": "reload" %>
<%= javascript_include_tag "application", "data-turbo-track": "reload", type: "module" %>
</head>
<body>
<%= render 'layouts/header' %>
<div class="container">
<% flash.each do |message_type, message| %>
<%= content_tag(:div, message, class: "alert alert-#{message_type}") %>
<!-- <div class="alert alert-<%#= message_type %>"><%#= message %></div>-->
<% end %>
<div class="">
<%= render 'layouts/message' %>
<%= yield %>
<%= render 'layouts/footer' %>
<%#= debug(params) if Rails.env.development? %>
<%= debug(params.to_yaml) if Rails.env.development? %>
<%= debug(session) if Rails.env.development? %>
<%= debug(Time.now) if Rails.env.development? %>
<%#= debug(params.to_yaml) if Rails.env.development? %>
<%#= debug(session) if Rails.env.development? %>
<%#= debug(Time.now) if Rails.env.development? %>
<% if Rails.env.development? %>
<div class="container mx-auto px-4 mb-8 pt-4">
<div class="max-w-4xl mx-auto border-2 border-gray-300 rounded-lg p-6 bg-gray-100">
<!-- Params -->
<div class="mb-6">
<h3 class="text-gray-700 font-bold mb-2">Params:</h3>
<pre class="bg-white p-4 rounded shadow overflow-x-auto text-sm text-gray-600 border border-gray-200">
<%= params.to_yaml %>
</pre>
</div>
<!-- Session -->
<div class="mb-6">
<h3 class="text-gray-700 font-bold mb-2">Session:</h3>
<pre class="bg-white p-4 rounded shadow overflow-x-auto text-sm text-gray-600 border border-gray-200">
<%= session %>
</pre>
</div>
<!-- Time -->
<div>
<h3 class="text-gray-700 font-bold mb-2">Current Time:</h3>
<pre class="bg-white p-4 rounded shadow overflow-x-auto text-sm text-gray-600 border border-gray-200">
<%= Time.now %>
</pre>
</div>
</div>
</div>
<% end %>
</div>
</body>
</html>

View File

@ -1,24 +1,45 @@
<% provide(:title, "Log in") %>
<h1>Log in</h1>
<div class ="row">
<div class="col-md-6 col-md-offset-3">
<%= form_with(url: login_path, scope: :session, local: true) do |f| %>
<%= f.label :email %>
<%= f.email_field :email, class: 'form-control' %>
<div class ="container mx-auto px-4">
<h1 class="text-3xl font-bold text-center my-8">Log in</h1>
<%= f.label :password %>
<%= link_to "(forgot password)", new_password_reset_path %>
<%= f.password_field :password, class: 'form-control' %>
<div class="max-w-md mx-auto">
<%= form_with(url: login_path, scope: :session, local: true, class: "space-y-4") do |f| %>
<div class="form-control">
<%= f.label :email, class: "label" do %>
<span class="label-text">Email</span>
<% end %>
<%= f.email_field :email, class: "input input-bordered w-full" %>
</div>
<%= f.label :remember_me, class: "checkbox inline" do %>
<%= f.check_box :remember_me %>
<span>Remember me on this computer</span>
<div class="form-control">
<div class="flex justify-between items-center">
<%= f.label :password, class: "label" do %>
<span class="label-text">Password</span>
<% end %>
<%= link_to "(forgot password)", new_password_reset_path,
class: "text-sm text-primary hover:text-primary-focus" %>
</div>
<%= f.password_field :password, class: "input input-bordered w-full" %>
</div>
<div class="form-control">
<label class="label cursor-pointer">
<%= f.check_box :remember_me, class: "checkbox checkbox-primary" %>
<span class="label-text ml-2">Remember me on this computer</span>
</label>
</div>
<div class="form-control mt-6">
<%= f.submit "Log in", class: "btn btn-primary w-full" %>
</div>
<% end %>
<%= f.submit "Log in", class: "btn btn-primary" %>
<% end %>
<p>New user? <%= link_to "Sign up now!", signup_path %></p>
<div class="text-center mt-6">
<p>New user?
<%= link_to "Sign up now!", signup_path,
class: "text-primary hover:text-primary-focus" %>
</p>
</div>
</div>
</div>

View File

@ -0,0 +1,10 @@
<div class="flex justify-center">
<div class="mx-4 order-last">
<%= image_tag("music.svg", alt:"music", width: "100") %>
</div>
<div class="mx-4 self-center">
<h1>Welcome to NorthBy</h1>
<h2>A premium in sight and sound</h2>
<button>Learn More</button>
</div>
</div>

View File

@ -1,16 +1,15 @@
<% provide(:title, "Home") %>
<div class="center jumbotron">
<h1>Welcome to the Sample App</h1>
<h2>
<div class="hero bg-base-200 min-h-screen">
<div class="hero-content text-center">
<div class="max-w-md">
<h1 class="text-5xl font-bold">Welcome to the Today Ai Weather</h1>
<p class="py-6">
This is the home page for the
<a href="https://www.railstutorial.org">Ruby on Rails Tutorial</a>
Sample application.
</h2>
Today Ai Weather application.
</p>
<%= link_to "Sing up now!", signup_path, class:"btn btn-lg btn-primary" %>
</div>
<%= link_to image_tag("rails.svg", alt:"Rails logo", width: "200"),
"https://rubyonrails.org/" %>
</div>
</div>
<%#= link_to image_tag("kitten.jpg", alt:"Kitten", width:"200") %>

View File

@ -1,18 +1,36 @@
<%= form_with(model: @user, local: true) do |f| %>
<%= form_with(model: @user, local: true, class: "space-y-4") do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
<%= f.label :email %>
<%= f.email_field :email, class: 'form-control' %>
<%= f.label :password %>
<%= f.password_field :password, class: 'form-control' %>
<%= f.label :password_confirmation, "Confirmation" %>
<%= f.password_field :password_confirmation, class: 'form-control' %>
<%= f.submit yield(:button_text), class: "btn btn-primary" %>
<div class="form-control">
<%= f.label :name, class: "label" do %>
<span class="label-text">Name</span>
<% end %>
<%= f.text_field :name, class: "input input-bordered w-full" %>
</div>
<div class="form-control">
<%= f.label :email, class: "label" do %>
<span class="label-text">Email</span>
<% end %>
<%= f.email_field :email, class: "input input-bordered w-full" %>
</div>
<div class="form-control">
<%= f.label :password, class: "label" do %>
<span class="label-text">Password</span>
<% end %>
<%= f.password_field :password, class: "input input-bordered w-full" %>
</div>
<div class="form-control">
<%= f.label :password_confirmation, class: "label" do %>
<span class="label-text">Confirmation</span>
<% end %>
<%= f.password_field :password_confirmation, class: "input input-bordered w-full" %>
</div>
<div class="form-control mt-6">
<%= f.submit yield(:button_text), class: "btn btn-primary mb-6" %>
</div>
<% end %>

View File

@ -1,11 +1,24 @@
<li>
<%= gravatar_for user, size: 50 %>
<%= link_to user.name, user %>
<div class="card card-compact bg-base-100 shadow-lg hover:shadow-xl transition-shadow">
<div class="card-body flex-row items-center justify-between">
<!-- 用户基本信息 -->
<div class="flex items-center gap-4">
<%= gravatar_for user, size: 50, class: "rounded-full" %>
<%= link_to user.name, user,
class: "link link-hover text-lg font-medium" %>
</div>
<!-- 管理员操作按钮 -->
<% if current_user.admin? && !current_user?(user) %>
| <%= link_to "delete", user,
<%= link_to user,
data: {
turbo_method: :delete,
confirm: "You sure?"
} %>
turbo_confirm: "Are you sure you want to delete this user?"
},
class: "btn btn-ghost btn-sm text-error hover:bg-error hover:text-white" do %>
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>
<% end %>
</li>
<% end %>
</div>
</div>

View File

@ -1,13 +1,34 @@
<% provide(:title, "Edit user") %>
<% provide(:button_text, 'Save changes') %>
<h1>Update your profile</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<div class="container mx-auto px-4 py-8">
<div class="max-w-md mx-auto">
<!-- 标题 -->
<h1 class="text-2xl font-bold text-center mb-8">Update your profile</h1>
<!-- 表单区域 -->
<div class="card bg-base-100 shadow-lg">
<div class="card-body">
<%= render 'form' %>
<div class="gravatar_edit">
<%= gravatar_for @user %>
<a href="https://gravatar.com/emails" target="_blank">change</a>
</div>
</div>
<!-- 头像编辑区 -->
<div class="card bg-base-100 shadow-lg mb-8">
<div class="card-body items-center text-center">
<%= gravatar_for @user, size: 100, class: "rounded-full ring ring-primary ring-offset-2" %>
<%= link_to "https://gravatar.com/emails",
target: "_blank",
rel: "noopener noreferrer",
class: "btn btn-outline btn-sm gap-2 mt-4" do %>
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" />
</svg>
Change Avatar
<% end %>
</div>
</div>
</div>
</div>

View File

@ -1,17 +1,18 @@
<% provide(:title, 'All users') %>
<h1>All users</h1>
<div class="container mx-auto px-4 py-8">
<h1 class="text-3xl font-bold text-center mb-8">All Users</h1>
<%= paginate @users %>
<ul class="users">
<!-- 用户列表 -->
<div class="grid gap-4 max-w-3xl mx-auto">
<%= render @users %>
<%# auto loop by rails, like after %>
<%# @users.each do |user| %>
<!-- <li>-->
<%#= gravatar_for user, size: 50 %>
<%#= link_to user.name, user %>
<!-- </li>-->
<%# end %>
</ul>
</div>
<!-- 分页 -->
<div class="flex justify-center mb-6 mt-6">
<div class="join">
<%= paginate @users %>
</div>
</div>
</div>

View File

@ -1,9 +1,9 @@
<% provide(:title, 'Sign up') %>
<% provide(:button_text, 'Create my account') %>
<h1>Sign up</h1>
<div class="container mx-auto px-4">
<h1 class="text-3xl font-bold text-center my-8">Sign up</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<div class="max-w-md mx-auto">
<%= render 'form' %>
</div>
</div>

View File

@ -1,12 +1,25 @@
<% provide(:title, @user.name) %>
<div class="row">
<aside class="col-md-4">
<section class="user_info">
<h1>
<%= gravatar_for @user %>
<div class="container mx-auto px-4 py-8">
<aside class="max-w-2xl mx-auto">
<section class="card bg-base-100 shadow-xl">
<div class="card-body">
<!-- 头像和用户名布局 -->
<h1 class="flex flex-col sm:flex-row items-center gap-6">
<!-- 头像添加装饰效果 -->
<div class="relative">
<%= gravatar_for @user, size: 120, class: "rounded-full ring-2 ring-primary ring-offset-2 hover:ring-4 transition-all duration-300" %>
<div class="absolute inset-0 rounded-full bg-primary/10 animate-pulse"></div>
</div>
<!-- 用户名样式 -->
<div class="text-center sm:text-left">
<span class="text-2xl font-bold bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent">
<%= @user.name %>
</span>
</div>
</h1>
</div>
</section>
</aside>
</div>

View File

@ -1,6 +1,6 @@
#!/usr/bin/env sh
if gem list --no-installed --exact --silent foreman; then
if ! gem list foreman -i --silent; then
echo "Installing foreman..."
gem install foreman
fi
@ -8,4 +8,9 @@ fi
# Default to port 3000 if not specified
export PORT="${PORT:-3000}"
exec foreman start -f Procfile.dev --env /dev/null "$@"
# Let the debug gem allow remote connections,
# but avoid loading until `debugger` is called
export RUBY_DEBUG_OPEN="true"
export RUBY_DEBUG_LAZY="true"
exec foreman start -f Procfile.dev "$@"

View File

@ -5,4 +5,3 @@ pin "application"
# pin "@hotwired/stimulus", to: "stimulus.min.js"
# pin "@hotwired/stimulus-loading", to: "stimulus-loading.js"
pin_all_from "app/javascript/controllers", under: "controllers"
# pin "bootstrap", to: "bootstrap.min.js"

View File

@ -5,7 +5,7 @@ Rails.application.config.assets.version = "1.0"
# Add additional assets to the asset load path.
# Rails.application.config.assets.paths << Emoji.images_path
Rails.application.config.assets.paths << Rails.root.join("node_modules/bootstrap/dist/js")
Rails.application.config.assets.paths << Rails.root.join("node_modules/bootstrap-icons/font")
Rails.application.config.assets.paths << Rails.root.join("node_modules/bootstrap/dist/js")
Rails.application.config.assets.precompile << "bootstrap.min.js"
# Rails.application.config.assets.paths << Rails.root.join("node_modules/bootstrap/dist/js")
# Rails.application.config.assets.paths << Rails.root.join("node_modules/bootstrap-icons/font")
# Rails.application.config.assets.paths << Rails.root.join("node_modules/bootstrap/dist/js")
# Rails.application.config.assets.precompile << "bootstrap.min.js"

View File

@ -1,6 +1,6 @@
Rails.application.routes.draw do
get "password_resets/new"
get "password_resets/edit"
# get "password_resets/new"
# get "password_resets/edit"
# get "sessions/new"
# get "users/new"
# get "static_pages/home"
@ -10,6 +10,8 @@ Rails.application.routes.draw do
root "static_pages#home"
get "/demo", to: "static_pages#demo"
get "/help", to: "static_pages#help"
get "/about", to: "static_pages#about"
get "/contact", to: "static_pages#contact"
@ -19,6 +21,8 @@ Rails.application.routes.draw do
post "/login", to: "sessions#create"
delete "/logout", to: "sessions#destroy"
get "pages/home"
resources :users
resources :account_activations, only: [ :edit ]
resources :password_resets, only: [ :new, :create, :edit, :update ]

58
config/tailwind.config.js Normal file
View File

@ -0,0 +1,58 @@
const defaultTheme = require('tailwindcss/defaultTheme')
module.exports = {
content: [
'./public/*.html',
'./app/helpers/**/*.rb',
'./app/javascript/**/*.js',
'./app/views/**/*.{erb,haml,html,slim}',
],
theme: {
extend: {
fontFamily: {
sans: ['Inter var', ...defaultTheme.fontFamily.sans],
},
keyframes: {
'slide-in-right': {
'0%': {
transform: 'translateX(100%)',
opacity: '0'
},
'100%': {
transform: 'translateX(0)',
opacity: '1'
},
},
'fade-out': {
'0%': {
opacity: '1'
},
'100%': {
opacity: '0'
},
}
},
animation: {
'slide-in-right': 'slide-in-right 0.5s ease-out',
'fade-out': 'fade-out 0.5s ease-out'
},
},
},
plugins: [
require('@tailwindcss/typography'),
require('daisyui'),
// require('@tailwindcss/forms'),
// require('@tailwindcss/typography'),
// require('@tailwindcss/container-queries'),
],
daisyui: {
themes: false, // false: only light + dark | true: all themes | array: specific themes like this ["light", "dark", "cupcake"]
darkTheme: "dark", // name of one of the included themes for dark mode
base: true, // applies background color and foreground color for root element by default
styled: true, // include daisyUI colors and design decisions for all components
utils: true, // adds responsive and modifier utility classes
prefix: "", // prefix for daisyUI classnames (components, modifiers and responsive class names. Not colors)
logs: true, // Shows info about daisyUI version and used config in the console when building your CSS
themeRoot: ":root", // The element that receives theme color CSS variables
},
}

1449
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -6,8 +6,6 @@
"@hotwired/turbo-rails": "^8.0.12",
"@popperjs/core": "^2.11.8",
"autoprefixer": "^10.4.20",
"bootstrap": "3",
"bootstrap-icons": "^1.11.3",
"jquery": "^3.7.1",
"nodemon": "^3.1.9",
"postcss": "^8.4.49",
@ -15,7 +13,6 @@
"sass": "^1.83.0"
},
"scripts": {
"build:css:compile": "sass ./app/assets/stylesheets/application.bootstrap.scss:./app/assets/builds/application.css --no-source-map --load-path=node_modules",
"build:css:prefix": "postcss ./app/assets/builds/application.css --use=autoprefixer --output=./app/assets/builds/application.css",
"build:css": "yarn build:css:compile && yarn build:css:prefix",
"watch:css": "nodemon --watch ./app/assets/stylesheets/ --ext scss --exec \"yarn build:css\"",
@ -25,6 +22,8 @@
"defaults"
],
"devDependencies": {
"@tailwindcss/typography": "^0.5.16",
"daisyui": "^4.12.23",
"esbuild": "^0.24.2"
}
}

View File

@ -7,7 +7,7 @@ class SiteLayoutTest < ActionDispatch::IntegrationTest
test "layout links" do
get root_path
assert_template "static_pages/home"
assert_select "a[href=?]", root_url, count: 2
assert_select "a[href=?]", root_url, count: 3
assert_select "a[href=?]", about_url
assert_select "a[href=?]", help_url
assert_select "a[href=?]", contact_url

View File

@ -10,7 +10,7 @@ class UsersIndexTest < ActionDispatch::IntegrationTest
log_in_as(@admin)
get users_path
assert_template "users/index"
assert_select "ul.pagination"
assert_select "div.pagination"
first_page_of_users = User.where(activated: true).page(1)
# first_page_of_users.first.toggle!(:activated)
@ -18,7 +18,7 @@ class UsersIndexTest < ActionDispatch::IntegrationTest
assert user.activated?
assert_select "a[href=?]", user_path(user), text: user.name
unless user == @admin
assert_select "a[href=?]", user_path(user), text: "delete"
assert_select "a[href=?][data-turbo-method='delete']", user_path(user)
end
end

View File

@ -129,7 +129,7 @@
"@hotwired/stimulus@^3.2.2":
version "3.2.2"
resolved "https://registry.yarnpkg.com/@hotwired/stimulus/-/stimulus-3.2.2.tgz#071aab59c600fed95b97939e605ff261a4251608"
resolved "https://registry.npmjs.org/@hotwired/stimulus/-/stimulus-3.2.2.tgz"
integrity sha512-eGeIqNOQpXoPAIP7tC1+1Yc1yl1xnwYqg+3mzqxyrbE5pg5YFBZcA6YoTiByJB6DKAEsiWtl6tjTJS4IYtbB7A==
"@hotwired/turbo-rails@^8.0.12":
@ -270,6 +270,16 @@
resolved "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz"
integrity sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==
"@tailwindcss/typography@^0.5.16":
version "0.5.16"
resolved "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.16.tgz"
integrity sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA==
dependencies:
lodash.castarray "^4.4.0"
lodash.isplainobject "^4.0.6"
lodash.merge "^4.6.2"
postcss-selector-parser "6.0.10"
ansi-regex@^5.0.1:
version "5.0.1"
resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz"
@ -312,16 +322,6 @@ binary-extensions@^2.0.0:
resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz"
integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==
bootstrap-icons@^1.11.3:
version "1.11.3"
resolved "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.11.3.tgz"
integrity sha512-+3lpHrCw/it2/7lBL15VR0HEumaBss0+f/Lb6ZvHISn1mlK83jjFpooTLsMWbIjJMDjDjOExMsTxnXSIT4k4ww==
bootstrap@3:
version "3.4.1"
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-3.4.1.tgz#c3a347d419e289ad11f4033e3c4132b87c081d72"
integrity sha512-yN5oZVmRCwe5aKwzRj6736nSmKDX7pLYwsXiCj/EYmo16hODaBiT4En5btW/jhBF/seV+XMx3aYwukYC3A49DA==
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz"
@ -347,6 +347,11 @@ browserslist@^4.23.3:
node-releases "^2.0.19"
update-browserslist-db "^1.1.1"
camelcase-css@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5"
integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==
caniuse-lite@^1.0.30001646, caniuse-lite@^1.0.30001688:
version "1.0.30001690"
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz"
@ -400,6 +405,34 @@ concat-map@0.0.1:
resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
css-selector-tokenizer@^0.8:
version "0.8.0"
resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.8.0.tgz#88267ef6238e64f2215ea2764b3e2cf498b845dd"
integrity sha512-Jd6Ig3/pe62/qe5SBPTN8h8LeUg/pT4lLgtavPf7updwwHpvFzxvOQBHYj2LZDMjUnBzgvIUSjRcf6oT5HzHFg==
dependencies:
cssesc "^3.0.0"
fastparse "^1.1.2"
cssesc@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz"
integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
culori@^3:
version "3.3.0"
resolved "https://registry.yarnpkg.com/culori/-/culori-3.3.0.tgz#e33530adbd124d53bd6550394397e695eaaed739"
integrity sha512-pHJg+jbuFsCjz9iclQBqyL3B2HLCBF71BwVNujUYEvCeQMvV97R59MNK3R2+jgJ3a1fcZgI9B3vYgz8lzr/BFQ==
daisyui@^4.12.23:
version "4.12.23"
resolved "https://registry.yarnpkg.com/daisyui/-/daisyui-4.12.23.tgz#3fc370ed4c226c9c811d223da1ba6a56ac16d777"
integrity sha512-EM38duvxutJ5PD65lO/AFMpcw+9qEy6XAZrTpzp7WyaPeO/l+F/Qiq0ECHHmFNcFXh5aVoALY4MGrrxtCiaQCQ==
dependencies:
css-selector-tokenizer "^0.8"
culori "^3"
picocolors "^1"
postcss-js "^4"
debug@^4:
version "4.4.0"
resolved "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz"
@ -474,6 +507,11 @@ fast-glob@^3.3.2:
merge2 "^1.3.0"
micromatch "^4.0.4"
fastparse@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9"
integrity sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==
fastq@^1.6.0:
version "1.18.0"
resolved "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz"
@ -609,6 +647,21 @@ lilconfig@^3.1.1:
resolved "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz"
integrity sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==
lodash.castarray@^4.4.0:
version "4.4.0"
resolved "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz"
integrity sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==
lodash.isplainobject@^4.0.6:
version "4.0.6"
resolved "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz"
integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==
lodash.merge@^4.6.2:
version "4.6.2"
resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz"
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
merge2@^1.3.0:
version "1.4.1"
resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz"
@ -680,7 +733,7 @@ path-type@^5.0.0:
resolved "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz"
integrity sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==
picocolors@^1.0.0, picocolors@^1.0.1, picocolors@^1.1.0, picocolors@^1.1.1:
picocolors@^1, picocolors@^1.0.0, picocolors@^1.0.1, picocolors@^1.1.0, picocolors@^1.1.1:
version "1.1.1"
resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz"
integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
@ -713,6 +766,13 @@ postcss-cli@^11.0.0:
slash "^5.0.0"
yargs "^17.0.0"
postcss-js@^4:
version "4.0.1"
resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-4.0.1.tgz#61598186f3703bab052f1c4f7d805f3991bee9d2"
integrity sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==
dependencies:
camelcase-css "^2.0.1"
postcss-load-config@^5.0.0:
version "5.1.0"
resolved "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-5.1.0.tgz"
@ -729,6 +789,14 @@ postcss-reporter@^7.0.0:
picocolors "^1.0.0"
thenby "^1.3.4"
postcss-selector-parser@6.0.10:
version "6.0.10"
resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz"
integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==
dependencies:
cssesc "^3.0.0"
util-deprecate "^1.0.2"
postcss-value-parser@^4.2.0:
version "4.2.0"
resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz"
@ -890,6 +958,11 @@ update-browserslist-db@^1.1.1:
escalade "^3.2.0"
picocolors "^1.1.0"
util-deprecate@^1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz"