Compare commits

...

10 Commits

Author SHA1 Message Date
c00e336009 feat: add cities and weather_arts tables
Some checks are pending
CI / scan_ruby (push) Waiting to run
CI / scan_js (push) Waiting to run
CI / lint (push) Waiting to run
CI / test (push) Waiting to run
- Create cities table with fields for name, country, latitude, and longitude
- Add featured boolean field to cities table
- Create weather_arts table with fields for weather_date, weather_condition, description, and prompt

These changes enhance the database schema by introducing new tables that will support
future features related to city and weather data management.
2025-01-17 18:08:41 +08:00
6dccace0c8 chore: add QWeather API key to credentials
- Include QWeather API key in the credentials file

This change adds the necessary API key for the QWeather service, enabling
future integration of weather data into the application. The key is stored
in the encrypted credentials file to maintain security.
2025-01-17 18:07:57 +08:00
42e0da1aa0 feat: add city and weather art models
- Create City model with attributes: name, country, latitude, longitude, and featured.
- Create WeatherArt model with attributes: weather_date, weather_condition, description, and prompt.
- Add migration files for creating cities and weather arts tables.
- Include fixture files for cities and weather arts for testing.
- Add basic test files for both models.

These changes introduce new models and database tables to support
city and weather art data, enabling future features related to
weather information and city management.
2025-01-17 18:05:42 +08:00
81843f0c08 chore: remove unused jQuery and Bootstrap dependencies
- 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
50 changed files with 481 additions and 2991 deletions

View File

@ -70,8 +70,6 @@ group :test do
gem "rails-controller-testing"
end
gem "cssbundling-rails", "~> 1.4"
gem "jsbundling-rails", "~> 1.3"
group :production do

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)
@ -441,7 +439,6 @@ DEPENDENCIES
bootsnap
brakeman
capybara
cssbundling-rails (~> 1.4)
debug
faker (~> 3.5)
guard (~> 2.19)

View File

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

View File

@ -18,7 +18,7 @@
}
h1 {
@apply text-[3em] tracking-[-2px] mb-[30px] text-center;
@apply text-[3em] tracking-[-2px] mb-8 mt-8 text-center;
}
h2 {

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

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

View File

@ -1,12 +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 "flowbite/dist/flowbite.turbo"
import "./controllers"

View File

@ -3,4 +3,11 @@
// import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading"
// eagerLoadControllersFrom("controllers", application)
import { application } from "./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';
}

2
app/models/city.rb Normal file
View File

@ -0,0 +1,2 @@
class City < ApplicationRecord
end

View File

@ -0,0 +1,2 @@
class WeatherArt < ApplicationRecord
end

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,39 +1,10 @@
<footer class="mt-12 pt-5 border-t border-gray-200 text-gray-600">
<div class="container mx-auto px-4">
<div class="flex flex-col md:flex-row md:justify-between items-center">
<!-- 左侧文本 -->
<small class="text-sm mb-4 md:mb-0">
The
<a href="https://www.railstutorial.org"
class="text-gray-600 hover:text-gray-900">
Ruby on Rails Tutorial
</a>
by
<a href="https://www.michaelhartl.com"
class="text-gray-600 hover:text-gray-900">
Michael Hartl
</a>
</small>
<!-- 右侧导航 -->
<nav>
<ul class="flex flex-wrap justify-center space-x-4">
<li>
<%= link_to "About", about_url,
class: "text-gray-600 hover:text-gray-900" %>
</li>
<li>
<%= link_to "Contact", contact_url,
class: "text-gray-600 hover:text-gray-900" %>
</li>
<li>
<a href="https://news.railstutorial.org"
class="text-gray-600 hover:text-gray-900">
News
</a>
</li>
</ul>
</nav>
</div>
</div>
<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,6 +1,13 @@
<div class="navbar bg-base-100 glass">
<!-- 固定在顶部容器 -->
<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 "sample app", root_url, id: "logo", class: "btn btn-ghost text-xl" %>
<%= link_to "Today AI Weather", root_url, id: "logo", class: "btn btn-ghost text-xl" %>
</div>
<div class="navbar-end">
<div class="hidden lg:flex">
@ -9,18 +16,20 @@
<li><%= link_to "Help", help_url %></li>
<% if logged_in? %>
<li><%= link_to "Users", users_path %></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<li>
<details>
<summary>
Account <b class="caret"></b>
</a>
<ul class="dropdown-menu">
</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>
<li class="divider"></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>
@ -67,5 +76,11 @@
<% end %>
</ul>
</details>
<%= render "layouts/theme_swap" %>
</div>
</div>
</div>
<!--</div>-->
</div>
<!-- 添加一个占位 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,17 +5,14 @@
<title><%= full_title(yield(:title)) %></title>
<%= render 'layouts/rails_default' %>
<%= render 'layouts/shim' %>
<%= stylesheet_link_tag "tailwind", "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 pt-16">
<% 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? %>

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>
<% end %>
<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>
<%= f.submit "Log in", class: "btn btn-primary" %>
<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 %>
<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

@ -1,16 +1,15 @@
<% provide(:title, "Home") %>
<div class="center jumbotron">
<h1>Welcome to the Sample App</h1>
<h2>
This is the home page for the
<a href="https://www.railstutorial.org">Ruby on Rails Tutorial</a>
Sample application.
</h2>
<%= link_to "Sing up now!", signup_path, class:"btn btn-lg btn-primary" %>
<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
Today Ai Weather application.
</p>
<%= link_to "Sing up now!", signup_path, class:"btn btn-lg btn-primary" %>
</div>
</div>
</div>
<%= link_to image_tag("rails.svg", alt:"Rails logo", width: "200"),
"https://rubyonrails.org/" %>
<%#= 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' %>
<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>
<%= f.label :email %>
<%= f.email_field :email, class: 'form-control' %>
<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 :password %>
<%= f.password_field :password, class: 'form-control' %>
<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>
<%= f.label :password_confirmation, "Confirmation" %>
<%= f.password_field :password_confirmation, class: 'form-control' %>
<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>
<%= f.submit yield(:button_text), class: "btn btn-primary" %>
<% end %>
<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 %>
<% if current_user.admin? && !current_user?(user) %>
| <%= link_to "delete", user,
data: {
turbo_method: :delete,
confirm: "You sure?"
} %>
<% end %>
</li>
<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 user,
data: {
turbo_method: :delete,
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 %>
<% 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">
<%= render 'form' %>
<div class="gravatar_edit">
<%= gravatar_for @user %>
<a href="https://gravatar.com/emails" target="_blank">change</a>
<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>
</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>
</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 %>
<!-- 用户列表 -->
<div class="grid gap-4 max-w-3xl mx-auto">
<%= render @users %>
</div>
<!-- 分页 -->
<div class="flex justify-center mb-6 mt-6">
<div class="join">
<%= paginate @users %>
</div>
</div>
<ul class="users">
<%= 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>

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>
</div>

View File

@ -1,12 +1,25 @@
<%provide(:title, @user.name) %>
<% provide(:title, @user.name) %>
<div class="row">
<aside class="col-md-4">
<section class="user_info">
<h1>
<%= gravatar_for @user %>
<%= @user.name %>
</h1>
<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>
</div>

View File

@ -1 +1 @@
YKfU5l6Ov/BSQ2f9dFDaYg6oB6vTubpbZ9SIp9d8XyHwu2aadiIM0HB/Z1OmKVcfm5kZY3pk9PmGNzSiZga7553+d7LzfRAY4fU0s2UWhn/2uXXAgjj3i0O9AaL7EesvpW9DSFZQb+JtmCQLEY+aTQTtO1YF34IpvyqAMtz75r5moKFQM0WzB48fv0bk0AI3ZhH9THWNvompAEKAE8ZTmNvhwyntt0AtB4cwyyBDybi6DRn4hYlxLzFcZRelAhR4GhfCbH8htd8n79eYZR2dp7bHP/svz3mFMUbhhRmIDiwqCyOovf/UAj7xF40MOVe2RBkycwE/UOpEc7/+YZFfE9y5ezoFQ3LlvnLIClsh2Ye4VXjvwEaGa5YNGqQiGrdk5w4zzVa1s0Kybq3q70b7+o5Wj1VIB2Gmoeo4FmxRubBtnxntMiic2lMAbdTRGniGmmSo9I2K+/KFYqtmIguTIdqsUcDgBockafmZrsKO0iDTmBnzef+Ws8u9K5P4lA==--1qH7QuK1ah68Kh2a--Qd/IItnduATpr/gMHFmHiA==
/ttF+x55j6ZTSjsUldgbvhtqOQx2RIhMFFvooE6Bi+RP+JlXziCUubpJHGfbscjEgukeif4rrmBWJ1aiL3nf9pPmEnvbt5HsmucpLZE9NEoLZW/lNQktVdQCB+dSiX9pwfGxI75R/63rz05cuFtXh0TpnNGhriHZwX/mSbNZQ70p+WK304EtXoqGNWD8TBuLTbRbY3Jjdx0a3AM1UIszD0r9Au775opGCqw0uWciVkAcIWeLFBH+hld71ZTalrei661OKr6qwFwcnPtXlTwPv2GCAZj5sod0vYFksjwztbHgWbYpk0ZoexxGeVjKXgR977XpqTusfkxhc1RlftIlW59sngS9uStfUjLOgEIiO6Luxrq/9mCXxETk1vSYEfUmzj6wNg5QJcI/BwmSxoxKkXrwqXpU0TzRnUQoCWOCvhO4U+KAKcueV7JjjY39GU9vj7hiY1AsYUnZCdd4orxAazUibOpGlxtVjSCc4OUU25VdHbayai18Om7J6QdSRc48SBYau4HYr1cI7okfxnsQtad1YtVUufPG0PvLR9sbk9AyDQu0a0vtP8kXCSUGMS5FeQ==--dcyGnovSBlvMYvIb--S4VD+flhOEWm93yUMSe44Q==

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

@ -9,7 +9,7 @@ Rails.application.routes.draw do
# get "static_pages/contact"
root "static_pages#home"
get "/demo", to: "static_pages#demo"
get "/help", to: "static_pages#help"

View File

@ -6,26 +6,48 @@ module.exports = {
'./app/helpers/**/*.rb',
'./app/javascript/**/*.js',
'./app/views/**/*.{erb,haml,html,slim}',
'./node_modules/flowbite/**/*.js'
],
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('flowbite/plugin')
// 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: "light", // name of one of the included themes for dark mode
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

View File

@ -0,0 +1,13 @@
class CreateCities < ActiveRecord::Migration[8.0]
def change
create_table :cities do |t|
t.string :name
t.string :country
t.decimal :latitude
t.decimal :longitude
t.boolean :featured
t.timestamps
end
end
end

View File

@ -0,0 +1,12 @@
class CreateWeatherArts < ActiveRecord::Migration[8.0]
def change
create_table :weather_arts do |t|
t.date :weather_date
t.string :weather_condition
t.text :description
t.string :prompt
t.timestamps
end
end
end

21
db/schema.rb generated
View File

@ -10,7 +10,17 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[8.0].define(version: 2025_01_07_093124) do
ActiveRecord::Schema[8.0].define(version: 2025_01_17_095400) do
create_table "cities", force: :cascade do |t|
t.string "name"
t.string "country"
t.decimal "latitude"
t.decimal "longitude"
t.boolean "featured"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "users", force: :cascade do |t|
t.string "name"
t.string "email"
@ -26,4 +36,13 @@ ActiveRecord::Schema[8.0].define(version: 2025_01_07_093124) do
t.datetime "reset_send_at"
t.index ["email"], name: "index_users_on_email", unique: true
end
create_table "weather_arts", force: :cascade do |t|
t.date "weather_date"
t.string "weather_condition"
t.text "description"
t.string "prompt"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end

2479
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -6,9 +6,6 @@
"@hotwired/turbo-rails": "^8.0.12",
"@popperjs/core": "^2.11.8",
"autoprefixer": "^10.4.20",
"bootstrap": "3",
"bootstrap-icons": "^1.11.3",
"flowbite": "^2.5.2",
"jquery": "^3.7.1",
"nodemon": "^3.1.9",
"postcss": "^8.4.49",
@ -16,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\"",

15
test/fixtures/cities.yml vendored Normal file
View File

@ -0,0 +1,15 @@
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
one:
name: MyString
country: MyString
latitude: 9.99
longitude: 9.99
featured: false
two:
name: MyString
country: MyString
latitude: 9.99
longitude: 9.99
featured: false

13
test/fixtures/weather_arts.yml vendored Normal file
View File

@ -0,0 +1,13 @@
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
one:
weather_date: 2025-01-17
weather_condition: MyString
description: MyText
prompt: MyString
two:
weather_date: 2025-01-17
weather_condition: MyString
description: MyText
prompt: MyString

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

7
test/models/city_test.rb Normal file
View File

@ -0,0 +1,7 @@
require "test_helper"
class CityTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end

View File

@ -0,0 +1,7 @@
require "test_helper"
class WeatherArtTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end

122
yarn.lock
View File

@ -255,7 +255,7 @@
"@parcel/watcher-win32-ia32" "2.5.0"
"@parcel/watcher-win32-x64" "2.5.0"
"@popperjs/core@^2.11.8", "@popperjs/core@^2.9.3":
"@popperjs/core@^2.11.8":
version "2.11.8"
resolved "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz"
integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==
@ -265,26 +265,6 @@
resolved "https://registry.npmjs.org/@rails/actioncable/-/actioncable-7.2.201.tgz"
integrity sha512-wsTdWoZ5EfG5k3t7ORdyQF0ZmDEgN4aVPCanHAiNEwCROqibSZMXXmCbH7IDJUVri4FOeAVwwbPINI7HVHPKBw==
"@rollup/plugin-node-resolve@^15.2.3":
version "15.3.1"
resolved "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.1.tgz"
integrity sha512-tgg6b91pAybXHJQMAAwW9VuWBO6Thi+q7BCNARLwSqlmsHz0XYURtGvh/AuwSADXSI4h/2uHbs7s4FzlZDGSGA==
dependencies:
"@rollup/pluginutils" "^5.0.1"
"@types/resolve" "1.20.2"
deepmerge "^4.2.2"
is-module "^1.0.0"
resolve "^1.22.1"
"@rollup/pluginutils@^5.0.1":
version "5.1.4"
resolved "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz"
integrity sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==
dependencies:
"@types/estree" "^1.0.0"
estree-walker "^2.0.2"
picomatch "^4.0.2"
"@sindresorhus/merge-streams@^2.1.0":
version "2.3.0"
resolved "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz"
@ -300,16 +280,6 @@
lodash.merge "^4.6.2"
postcss-selector-parser "6.0.10"
"@types/estree@^1.0.0":
version "1.0.6"
resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz"
integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==
"@types/resolve@1.20.2":
version "1.20.2"
resolved "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz"
integrity sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==
ansi-regex@^5.0.1:
version "5.0.1"
resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz"
@ -352,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.npmjs.org/bootstrap/-/bootstrap-3.4.1.tgz"
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"
@ -480,11 +440,6 @@ debug@^4:
dependencies:
ms "^2.1.3"
deepmerge@^4.2.2:
version "4.3.1"
resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz"
integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==
dependency-graph@^0.11.0:
version "0.11.0"
resolved "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz"
@ -541,11 +496,6 @@ escalade@^3.1.1, escalade@^3.2.0:
resolved "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz"
integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==
estree-walker@^2.0.2:
version "2.0.2"
resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz"
integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
fast-glob@^3.3.2:
version "3.3.2"
resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz"
@ -576,23 +526,6 @@ fill-range@^7.1.1:
dependencies:
to-regex-range "^5.0.1"
flowbite-datepicker@^1.3.0:
version "1.3.2"
resolved "https://registry.npmjs.org/flowbite-datepicker/-/flowbite-datepicker-1.3.2.tgz"
integrity sha512-6Nfm0MCVX3mpaR7YSCjmEO2GO8CDt6CX8ZpQnGdeu03WUCWtEPQ/uy0PUiNtIJjJZWnX0Cm3H55MOhbD1g+E/g==
dependencies:
"@rollup/plugin-node-resolve" "^15.2.3"
flowbite "^2.0.0"
flowbite@^2.0.0, flowbite@^2.5.2:
version "2.5.2"
resolved "https://registry.npmjs.org/flowbite/-/flowbite-2.5.2.tgz"
integrity sha512-kwFD3n8/YW4EG8GlY3Od9IoKND97kitO+/ejISHSqpn3vw2i5K/+ZI8Jm2V+KC4fGdnfi0XZ+TzYqQb4Q1LshA==
dependencies:
"@popperjs/core" "^2.9.3"
flowbite-datepicker "^1.3.0"
mini-svg-data-uri "^1.4.3"
fraction.js@^4.3.7:
version "4.3.7"
resolved "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz"
@ -612,11 +545,6 @@ fsevents@~2.3.2:
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
function-bind@^1.1.2:
version "1.1.2"
resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz"
integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
get-caller-file@^2.0.5:
version "2.0.5"
resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz"
@ -656,13 +584,6 @@ has-flag@^3.0.0:
resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz"
integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==
hasown@^2.0.2:
version "2.0.2"
resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz"
integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==
dependencies:
function-bind "^1.1.2"
ignore-by-default@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz"
@ -685,13 +606,6 @@ is-binary-path@~2.1.0:
dependencies:
binary-extensions "^2.0.0"
is-core-module@^2.16.0:
version "2.16.1"
resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz"
integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==
dependencies:
hasown "^2.0.2"
is-extglob@^2.1.1:
version "2.1.1"
resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz"
@ -709,11 +623,6 @@ is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1:
dependencies:
is-extglob "^2.1.1"
is-module@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz"
integrity sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==
is-number@^7.0.0:
version "7.0.0"
resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz"
@ -766,11 +675,6 @@ micromatch@^4.0.4, micromatch@^4.0.5:
braces "^3.0.3"
picomatch "^2.3.1"
mini-svg-data-uri@^1.4.3:
version "1.4.4"
resolved "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz"
integrity sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==
minimatch@^3.1.2:
version "3.1.2"
resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz"
@ -824,11 +728,6 @@ normalize-range@^0.1.2:
resolved "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz"
integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==
path-parse@^1.0.7:
version "1.0.7"
resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz"
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
path-type@^5.0.0:
version "5.0.0"
resolved "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz"
@ -844,11 +743,6 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1:
resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
picomatch@^4.0.2:
version "4.0.2"
resolved "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz"
integrity sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==
pify@^2.3.0:
version "2.3.0"
resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz"
@ -956,15 +850,6 @@ require-directory@^2.1.1:
resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz"
integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
resolve@^1.22.1:
version "1.22.10"
resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz"
integrity sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==
dependencies:
is-core-module "^2.16.0"
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
reusify@^1.0.4:
version "1.0.4"
resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz"
@ -1033,11 +918,6 @@ supports-color@^5.5.0:
dependencies:
has-flag "^3.0.0"
supports-preserve-symlinks-flag@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz"
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
thenby@^1.3.4:
version "1.3.4"
resolved "https://registry.npmjs.org/thenby/-/thenby-1.3.4.tgz"