no message

This commit is contained in:
2025-10-18 14:46:52 +08:00
commit 7a84025b05
387 changed files with 75711 additions and 0 deletions

3
assets/css/tailwind.css Normal file
View File

@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

BIN
assets/img/dashboard.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

1
assets/img/github.svg Normal file
View File

@@ -0,0 +1 @@
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg>

After

Width:  |  Height:  |  Size: 775 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

1
assets/img/twitter.svg Normal file
View File

@@ -0,0 +1 @@
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M23.954 4.569c-.885.389-1.83.654-2.825.775 1.014-.611 1.794-1.574 2.163-2.723-.951.555-2.005.959-3.127 1.184-.896-.959-2.173-1.559-3.591-1.559-2.717 0-4.92 2.203-4.92 4.917 0 .39.045.765.127 1.124C7.691 8.094 4.066 6.13 1.64 3.161c-.427.722-.666 1.561-.666 2.475 0 1.71.87 3.213 2.188 4.096-.807-.026-1.566-.248-2.228-.616v.061c0 2.385 1.693 4.374 3.946 4.827-.413.111-.849.171-1.296.171-.314 0-.615-.03-.916-.086.631 1.953 2.445 3.377 4.604 3.417-1.68 1.319-3.809 2.105-6.102 2.105-.39 0-.779-.023-1.17-.067 2.189 1.394 4.768 2.209 7.557 2.209 9.054 0 13.999-7.496 13.999-13.986 0-.209 0-.42-.015-.63.961-.689 1.8-1.56 2.46-2.548l-.047-.02z"/></svg>

After

Width:  |  Height:  |  Size: 704 B

8
assets/js/alp.js Normal file

File diff suppressed because one or more lines are too long

34
assets/js/charts-bars.js Normal file
View File

@@ -0,0 +1,34 @@
/**
* For usage, visit Chart.js docs https://www.chartjs.org/docs/latest/
*/
const barConfig = {
type: 'bar',
data: {
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
datasets: [
{
label: 'Shoes',
backgroundColor: '#0694a2',
// borderColor: window.chartColors.red,
borderWidth: 1,
data: [-3, 14, 52, 74, 33, 90, 70],
},
{
label: 'Bags',
backgroundColor: '#7e3af2',
// borderColor: window.chartColors.blue,
borderWidth: 1,
data: [66, 33, 43, 12, 54, 62, 84],
},
],
},
options: {
responsive: true,
legend: {
display: false,
},
},
}
const barsCtx = document.getElementById('bars')
window.myBar = new Chart(barsCtx, barConfig)

71
assets/js/charts-lines.js Normal file
View File

@@ -0,0 +1,71 @@
/**
* For usage, visit Chart.js docs https://www.chartjs.org/docs/latest/
*/
const lineConfig = {
type: 'line',
data: {
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
datasets: [
{
label: 'Organic',
/**
* These colors come from Tailwind CSS palette
* https://tailwindcss.com/docs/customizing-colors/#default-color-palette
*/
backgroundColor: '#0694a2',
borderColor: '#0694a2',
data: [43, 48, 40, 54, 67, 73, 70],
fill: false,
},
{
label: 'Paid',
fill: false,
/**
* These colors come from Tailwind CSS palette
* https://tailwindcss.com/docs/customizing-colors/#default-color-palette
*/
backgroundColor: '#7e3af2',
borderColor: '#7e3af2',
data: [24, 50, 64, 74, 52, 51, 65],
},
],
},
options: {
responsive: true,
/**
* Default legends are ugly and impossible to style.
* See examples in charts.html to add your own legends
* */
legend: {
display: false,
},
tooltips: {
mode: 'index',
intersect: false,
},
hover: {
mode: 'nearest',
intersect: true,
},
scales: {
x: {
display: true,
scaleLabel: {
display: true,
labelString: 'Month',
},
},
y: {
display: true,
scaleLabel: {
display: true,
labelString: 'Value',
},
},
},
},
}
// change this to the id of your chart element in HMTL
const lineCtx = document.getElementById('line')
window.myLine = new Chart(lineCtx, lineConfig)

35
assets/js/charts-pie.js Normal file
View File

@@ -0,0 +1,35 @@
/**
* For usage, visit Chart.js docs https://www.chartjs.org/docs/latest/
*/
const pieConfig = {
type: 'doughnut',
data: {
datasets: [
{
data: [33, 33, 33],
/**
* These colors come from Tailwind CSS palette
* https://tailwindcss.com/docs/customizing-colors/#default-color-palette
*/
backgroundColor: ['#0694a2', '#1c64f2', '#7e3af2'],
label: 'Dataset 1',
},
],
labels: ['Shoes', 'Shirts', 'Bags'],
},
options: {
responsive: true,
cutoutPercentage: 80,
/**
* Default legends are ugly and impossible to style.
* See examples in charts.html to add your own legends
* */
legend: {
display: false,
},
},
}
// change this to the id of your chart element in HMTL
const pieCtx = document.getElementById('pie')
window.myPie = new Chart(pieCtx, pieConfig)

51
assets/js/focus-trap.js Normal file
View File

@@ -0,0 +1,51 @@
/**
* Limit focus to focusable elements inside `element`
* @param {HTMLElement} element - DOM element to focus trap inside
* @return {Function} cleanup function
*/
function focusTrap(element) {
const focusableElements = getFocusableElements(element)
const firstFocusableEl = focusableElements[0]
const lastFocusableEl = focusableElements[focusableElements.length - 1]
// Wait for the case the element was not yet rendered
setTimeout(() => firstFocusableEl.focus(), 50)
/**
* Get all focusable elements inside `element`
* @param {HTMLElement} element - DOM element to focus trap inside
* @return {HTMLElement[]} List of focusable elements
*/
function getFocusableElements(element = document) {
return [
...element.querySelectorAll(
'a, button, details, input, select, textarea, [tabindex]:not([tabindex="-1"])'
),
].filter((e) => !e.hasAttribute('disabled'))
}
function handleKeyDown(e) {
const TAB = 9
const isTab = e.key.toLowerCase() === 'tab' || e.keyCode === TAB
if (!isTab) return
if (e.shiftKey) {
if (document.activeElement === firstFocusableEl) {
lastFocusableEl.focus()
e.preventDefault()
}
} else {
if (document.activeElement === lastFocusableEl) {
firstFocusableEl.focus()
e.preventDefault()
}
}
}
element.addEventListener('keydown', handleKeyDown)
return function cleanup() {
element.removeEventListener('keydown', handleKeyDown)
}
}

62
assets/js/init-alpine.js Normal file
View File

@@ -0,0 +1,62 @@
function data() {
function getThemeFromLocalStorage() {
// if user already changed the theme, use it
if (window.localStorage.getItem('dark')) {
return JSON.parse(window.localStorage.getItem('dark'))
}
// else return their preferences
return (
!!window.matchMedia &&
window.matchMedia('(prefers-color-scheme: dark)').matches
)
}
function setThemeToLocalStorage(value) {
window.localStorage.setItem('dark', value)
}
return {
dark: getThemeFromLocalStorage(),
toggleTheme() {
this.dark = !this.dark
setThemeToLocalStorage(this.dark)
},
isSideMenuOpen: false,
toggleSideMenu() {
this.isSideMenuOpen = !this.isSideMenuOpen
},
closeSideMenu() {
this.isSideMenuOpen = false
},
isNotificationsMenuOpen: false,
toggleNotificationsMenu() {
this.isNotificationsMenuOpen = !this.isNotificationsMenuOpen
},
closeNotificationsMenu() {
this.isNotificationsMenuOpen = false
},
isProfileMenuOpen: false,
toggleProfileMenu() {
this.isProfileMenuOpen = !this.isProfileMenuOpen
},
closeProfileMenu() {
this.isProfileMenuOpen = false
},
isPagesMenuOpen: false,
togglePagesMenu() {
this.isPagesMenuOpen = !this.isPagesMenuOpen
},
// Modal
isModalOpen: false,
trapCleanup: null,
openModal() {
this.isModalOpen = true
this.trapCleanup = focusTrap(document.querySelector('#modal'))
},
closeModal() {
this.isModalOpen = false
this.trapCleanup()
},
}
}