-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.php
More file actions
116 lines (99 loc) · 4.66 KB
/
index.php
File metadata and controls
116 lines (99 loc) · 4.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
<?php
require_once 'core/config.php';
require_once 'core/detector.php';
require_once 'core/explorer.php';
require_once 'core/helper.php';
$location = getScanPath();
$folders = getFolders($location['abs']);
if (isset($_GET['phpinfo']) && $_GET['phpinfo'] == '1') {
phpinfo();
exit;
}
?>
<script>
function setupTheme() {
return {
searchQuery: '',
visibleCount: 0,
filterType: 'ALL',
dark: localStorage.theme === 'dark' ||
(!localStorage.theme && window.matchMedia('(prefers-color-scheme: dark)').matches),
toggleTheme() {
this.dark = !this.dark;
},
init() {
// apply theme immediately
document.documentElement.classList.toggle('dark', this.dark);
// watch for changes
this.$watch('dark', val => {
localStorage.theme = val ? 'dark' : 'light';
document.documentElement.classList.toggle('dark', val);
});
}
}
}
</script>
<!DOCTYPE html>
<html lang="en" x-data="setupTheme()">
<head>
<?php include 'views/layouts/meta.php'; ?>
</head>
<body class="bg-slate-50 dark:bg-slate-950 text-slate-900 dark:text-slate-100">
<div class="container mx-auto px-6 py-10 max-w-7xl">
<?php include 'views/layouts/header.php'; ?>
<?php include 'views/components/breadcrumb.php'; ?>
<?php include 'views/components/system_info.php'; ?>
<main class="mt-10">
<div class="flex flex-col md:flex-row md:items-end justify-between gap-6 mb-10">
<div>
<h2 class="text-xl font-bold flex items-center gap-2 mb-4">
<i class="ph-duotone ph-stack text-indigo-500"></i>
Project Assets <span class="text-sm font-normal opacity-50">(<?= count($folders) ?> Items)</span>
</h2>
<div class="flex p-1 bg-slate-200/50 dark:bg-slate-800/50 rounded-xl w-fit">
<?php
$types = ['ALL', TYPE_FRAMEWORK, TYPE_CMS, TYPE_APP, TYPE_DIRECTORY];
foreach ($types as $type): ?>
<button
@click="filterType = '<?= $type ?>'"
:class="filterType === '<?= $type ?>' ? 'bg-white dark:bg-slate-700 shadow-sm text-indigo-600 dark:text-white' : 'text-slate-500 hover:text-slate-400'"
class="px-4 py-1.5 rounded-lg text-xs font-bold transition-all uppercase tracking-wider">
<?= $type === 'ALL' ? 'All' : str_replace('_', ' ', $type) ?>
</button>
<?php endforeach; ?>
</div>
</div>
<div class="relative w-full md:w-72">
<i class="ph-bold ph-magnifying-glass absolute left-3 top-1/2 -translate-y-1/2 text-slate-400"></i>
<input
<?php if (count($folders) === 0) echo 'disabled'; ?>
type="text" x-model="searchQuery" placeholder="Search projects..."
class="w-full pl-10 pr-4 py-2 disabled:cursor-not-allowed disabled:opacity-50 bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-xl outline-none focus:ring-2 focus:ring-indigo-500 shadow-sm">
</div>
</div>
<div x-data="{
visibleCount: <?= count($folders) ?>,
updateCount() {
this.$nextTick(() => {
this.visibleCount = Array.from($el.querySelectorAll('.project-card')).filter(el => el.style.display !== 'none').length
})
}
}"
x-init="$watch('searchQuery', () => updateCount()); $watch('filterType', () => updateCount())">
</div>
<?php if (empty($folders)): ?>
<?php include 'views/states/state_empty_folder.php'; ?>
<?php else: ?>
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5 gap-4">
<?php foreach ($folders as $name):
$info = detectProject($location['abs'] . '/' . $name);
include 'views/components/project_card.php';
endforeach; ?>
</div>
<?php include 'views/states/state_empty_search.php'; ?>
<?php endif; ?>
</main>
<?php include 'views/layouts/footer.php'; ?>
</div>
</body>
</html>