radix-cms 0.1.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +17 -0
- package/CHANGELOG.md +10 -0
- package/CONTRIBUTING.md +40 -0
- package/LICENSE +197 -0
- package/NOTICE +3 -0
- package/README.md +126 -56
- package/SECURITY.md +22 -0
- package/dist/app.js +80 -0
- package/dist/config/db.js +66 -0
- package/dist/init/dbInit.js +132 -0
- package/dist/init/dbInit2.js +234 -0
- package/dist/middleware/auth.js +48 -0
- package/dist/plugins/my-seo-plugin/index.js +29 -0
- package/dist/routes/admin.js +808 -0
- package/dist/routes/index.js +218 -0
- package/dist/sql/radix.sql +118 -0
- package/dist/types/plugin.js +10 -0
- package/dist/utils/PluginManager.js +112 -0
- package/dist/utils/settings.js +80 -0
- package/dist/utils/themeScanner.js +33 -0
- package/dist/utils/versionCheck.js +74 -0
- package/docs/CMS_CODE_GUIDE.md +372 -0
- package/docs/CMS_USER_GUIDE.md +344 -0
- package/docs/Publishing Guidelines.txt +14 -0
- package/package.json +62 -6
- package/public/css/admin.css +178 -0
- package/public/css/fallback.css +53 -0
- package/public/hello.html +1 -0
- package/views/admin/create-page.ejs +82 -0
- package/views/admin/dashboard.ejs +44 -0
- package/views/admin/edit-page.ejs +87 -0
- package/views/admin/edit-user.ejs +45 -0
- package/views/admin/login.ejs +39 -0
- package/views/admin/media.ejs +79 -0
- package/views/admin/pages.ejs +82 -0
- package/views/admin/partials/footer.ejs +4 -0
- package/views/admin/partials/header.ejs +57 -0
- package/views/admin/settings.ejs +91 -0
- package/views/admin/setup-admin.ejs +69 -0
- package/views/admin/setup-db.ejs +112 -0
- package/views/admin/themes.ejs +24 -0
- package/views/admin/updates.ejs +79 -0
- package/views/admin/users.ejs +107 -0
- package/views/defaults/404.ejs +20 -0
- package/views/defaults/500.ejs +20 -0
- package/views/layouts/admin-layout.ejs +18 -0
- package/views/pages/gallery.ejs +5 -0
- package/views/pages/hello.ejs +4 -0
- package/views/pages/services.ejs +3 -0
- package/views/themes/default/assets/css/style.css +199 -0
- package/views/themes/default/assets/js/main.js +8 -0
- package/views/themes/default/index.ejs +55 -0
- package/views/themes/landing/assets/css/style.css +6 -0
- package/views/themes/landing/assets/js/main.js +8 -0
- package/views/themes/landing/index.ejs +26 -0
- package/views/themes/test/default.ejs +0 -0
- package/views/themes/test/full-width.ejs +0 -0
- package/views/themes/test/landing-page.ejs +0 -0
- package/index.js +0 -15
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
<%- include('partials/header', { title: 'User Management', activeNav: 'users' }) %>
|
|
2
|
+
|
|
3
|
+
<!-- Create New User Form Card -->
|
|
4
|
+
<div class="card" style="margin-bottom: 25px;">
|
|
5
|
+
<h2 style="font-size: 1.25rem; margin-bottom: 15px;">Create New User</h2>
|
|
6
|
+
|
|
7
|
+
<form action="/admin/users/create" method="POST" style="display: flex; flex-wrap: wrap; gap: 15px; align-items: flex-end;">
|
|
8
|
+
<div style="flex: 1; min-width: 180px;">
|
|
9
|
+
<label for="username" style="display: block; font-weight: 600; font-size: 0.85rem; margin-bottom: 5px;">Username:</label>
|
|
10
|
+
<input type="text" id="username" name="username" required placeholder="johndoe" style="width: 100%; padding: 8px 10px; border: 1px solid var(--border-color); border-radius: 4px; font-size: 0.9rem;">
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
<div style="flex: 1; min-width: 200px;">
|
|
14
|
+
<label for="full_name" style="display: block; font-weight: 600; font-size: 0.85rem; margin-bottom: 5px;">Full Name (Optional):</label>
|
|
15
|
+
<input type="text" id="full_name" name="full_name" placeholder="John Doe" style="width: 100%; padding: 8px 10px; border: 1px solid var(--border-color); border-radius: 4px; font-size: 0.9rem;">
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
<div style="flex: 1; min-width: 220px;">
|
|
19
|
+
<label for="email" style="display: block; font-weight: 600; font-size: 0.85rem; margin-bottom: 5px;">Email (Optional):</label>
|
|
20
|
+
<input type="email" id="email" name="email" placeholder="john@example.com" style="width: 100%; padding: 8px 10px; border: 1px solid var(--border-color); border-radius: 4px; font-size: 0.9rem;">
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<div style="flex: 1; min-width: 180px;">
|
|
24
|
+
<label for="password" style="display: block; font-weight: 600; font-size: 0.85rem; margin-bottom: 5px;">Password:</label>
|
|
25
|
+
<input type="password" id="password" name="password" required placeholder="••••••••" style="width: 100%; padding: 8px 10px; border: 1px solid var(--border-color); border-radius: 4px; font-size: 0.9rem;">
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
<div style="width: 160px;">
|
|
29
|
+
<label for="role" style="display: block; font-weight: 600; font-size: 0.85rem; margin-bottom: 5px;">Role:</label>
|
|
30
|
+
<select id="role" name="role" style="width: 100%; padding: 8px 10px; border: 1px solid var(--border-color); border-radius: 4px; font-size: 0.9rem;">
|
|
31
|
+
<option value="Editor">Editor</option>
|
|
32
|
+
<option value="Manager">Manager</option>
|
|
33
|
+
<option value="Administrator">Administrator</option>
|
|
34
|
+
<option value="Registered" selected>Registered</option>
|
|
35
|
+
<option value="Unregistered">Unregistered</option>
|
|
36
|
+
</select>
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
<div>
|
|
40
|
+
<button type="submit" class="btn btn-primary" style="padding: 9px 18px;">+ Add User</button>
|
|
41
|
+
</div>
|
|
42
|
+
</form>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
<!-- User List Table Card -->
|
|
46
|
+
<div class="card">
|
|
47
|
+
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
|
|
48
|
+
<div>
|
|
49
|
+
<h1 style="font-size: 1.5rem; margin-bottom: 4px;">User Accounts & RBAC</h1>
|
|
50
|
+
<p style="color: #64748b; font-size: 0.9rem;">Manage user privileges and assign access control roles.</p>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
<table class="data-table">
|
|
55
|
+
<thead>
|
|
56
|
+
<tr>
|
|
57
|
+
<th>Full Name</th>
|
|
58
|
+
<th>Username</th>
|
|
59
|
+
<th>Email</th>
|
|
60
|
+
<th>Current Role</th>
|
|
61
|
+
<th>Registered</th>
|
|
62
|
+
<th>Actions</th>
|
|
63
|
+
</tr>
|
|
64
|
+
</thead>
|
|
65
|
+
<tbody>
|
|
66
|
+
<% if (users && users.length > 0) { %>
|
|
67
|
+
<% users.forEach(u => { %>
|
|
68
|
+
<tr>
|
|
69
|
+
<td><%= u.full_name || 'N/A' %></td>
|
|
70
|
+
<td><strong><%= u.username %></strong></td>
|
|
71
|
+
<td><%= u.email || 'N/A' %></td>
|
|
72
|
+
<td>
|
|
73
|
+
<form action="/admin/users/update-role" method="POST" style="display: inline-flex; align-items: center; gap: 8px;">
|
|
74
|
+
<input type="hidden" name="userId" value="<%= u.id %>">
|
|
75
|
+
<select name="newRole" style="padding: 5px 8px; border-radius: 4px; border: 1px solid var(--border-color); font-size: 0.85rem;">
|
|
76
|
+
<option value="Administrator" <%= u.role === 'Administrator' ? 'selected' : '' %>>Administrator</option>
|
|
77
|
+
<option value="Manager" <%= u.role === 'Manager' ? 'selected' : '' %>>Manager</option>
|
|
78
|
+
<option value="Editor" <%= u.role === 'Editor' ? 'selected' : '' %>>Editor</option>
|
|
79
|
+
<option value="Registered" <%= u.role === 'Registered' ? 'selected' : '' %>>Registered</option>
|
|
80
|
+
<option value="Unregistered" <%= u.role === 'Unregistered' ? 'selected' : '' %>>Unregistered</option>
|
|
81
|
+
</select>
|
|
82
|
+
<button type="submit" class="btn btn-primary" style="padding: 4px 8px; font-size: 0.8rem;">Save</button>
|
|
83
|
+
</form>
|
|
84
|
+
</td>
|
|
85
|
+
<td><%= new Date(u.created_at).toLocaleDateString() %></td>
|
|
86
|
+
<td>
|
|
87
|
+
<a href="/admin/users/edit/<%= u.id %>" class="btn btn-primary" style="padding: 4px 10px; font-size: 0.8rem;">Edit</a>
|
|
88
|
+
<% if (user && user.id !== u.id) { %>
|
|
89
|
+
<form action="/admin/users/delete/<%= u.id %>" method="POST" style="display: inline;" onsubmit="return confirm('Are you sure you want to delete user <%= u.username %>?');">
|
|
90
|
+
<button type="submit" class="btn btn-danger" style="padding: 4px 10px; font-size: 0.8rem;">Delete</button>
|
|
91
|
+
</form>
|
|
92
|
+
<% } else { %>
|
|
93
|
+
<span style="font-size: 0.8rem; color: #94a3b8; font-style: italic;">Active Self</span>
|
|
94
|
+
<% } %>
|
|
95
|
+
</td>
|
|
96
|
+
</tr>
|
|
97
|
+
<% }) %>
|
|
98
|
+
<% } else { %>
|
|
99
|
+
<tr>
|
|
100
|
+
<td colspan="6">No users found in database.</td>
|
|
101
|
+
</tr>
|
|
102
|
+
<% } %>
|
|
103
|
+
</tbody>
|
|
104
|
+
</table>
|
|
105
|
+
</div>
|
|
106
|
+
|
|
107
|
+
<%- include('partials/footer') %>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Page Not Found | Radix CMS</title>
|
|
7
|
+
<link rel="stylesheet" href="/css/fallback.css">
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div class="error-card status-404">
|
|
11
|
+
<h1>404</h1>
|
|
12
|
+
<h2>Page Not Found</h2>
|
|
13
|
+
<p>The page you are looking for doesn't exist or has been moved to a new destination.</p>
|
|
14
|
+
<nav>
|
|
15
|
+
<a href="/">Home</a>
|
|
16
|
+
<a href="/admin">Dashboard</a>
|
|
17
|
+
</nav>
|
|
18
|
+
</div>
|
|
19
|
+
</body>
|
|
20
|
+
</html>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>System Error | Radix CMS</title>
|
|
7
|
+
<link rel="stylesheet" href="/css/fallback.css">
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div class="error-card status-500">
|
|
11
|
+
<h1>500</h1>
|
|
12
|
+
<h2>Database Connection Error</h2>
|
|
13
|
+
<p>We are experiencing a temporary system disruption. The database might be unreachable or undergoing maintenance.</p>
|
|
14
|
+
<nav>
|
|
15
|
+
<a href="/">Try Again</a>
|
|
16
|
+
<a href="/admin">Admin Panel</a>
|
|
17
|
+
</nav>
|
|
18
|
+
</div>
|
|
19
|
+
</body>
|
|
20
|
+
</html>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>Radix CMS Admin</title>
|
|
5
|
+
</head>
|
|
6
|
+
<body>
|
|
7
|
+
<nav>
|
|
8
|
+
<% if (user && ['Editor', 'Manager', 'Administrator'].includes(user.role)) { %>
|
|
9
|
+
<span>Logged in as <strong><%= user.username %></strong> (<%= user.role %>)</span>
|
|
10
|
+
<a href="/admin/logout">Logout</a>
|
|
11
|
+
<% } %>
|
|
12
|
+
</nav>
|
|
13
|
+
|
|
14
|
+
<!-- Express automatically injects view content here -->
|
|
15
|
+
<%- body %>
|
|
16
|
+
|
|
17
|
+
</body>
|
|
18
|
+
</html>
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--bg: #eef3f8;
|
|
3
|
+
--panel: #ffffff;
|
|
4
|
+
--panel-alt: #f7fafc;
|
|
5
|
+
--primary: #2b6cb0;
|
|
6
|
+
--primary-dark: #1d4f7a;
|
|
7
|
+
--text: #1f2937;
|
|
8
|
+
--muted: #5f6f82;
|
|
9
|
+
--border: #dfe7f0;
|
|
10
|
+
--footer: #1d2a36;
|
|
11
|
+
--shadow: rgba(34, 56, 84, 0.12);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
* { box-sizing: border-box; }
|
|
15
|
+
|
|
16
|
+
html, body {
|
|
17
|
+
margin: 0;
|
|
18
|
+
padding: 0;
|
|
19
|
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
20
|
+
background: linear-gradient(180deg, #f5f7fa 0%, #edf3f8 100%);
|
|
21
|
+
color: var(--text);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
body {
|
|
25
|
+
min-height: 100vh;
|
|
26
|
+
display: flex;
|
|
27
|
+
flex-direction: column;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.container {
|
|
31
|
+
width: min(1120px, calc(100% - 40px));
|
|
32
|
+
margin: 0 auto;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.site-header {
|
|
36
|
+
background: #ffffff;
|
|
37
|
+
border-bottom: 1px solid var(--border);
|
|
38
|
+
box-shadow: 0 1px 0 rgba(15, 23, 42, 0.04);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.topbar {
|
|
42
|
+
display: flex;
|
|
43
|
+
align-items: center;
|
|
44
|
+
justify-content: space-between;
|
|
45
|
+
min-height: 88px;
|
|
46
|
+
gap: 20px;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.brand {
|
|
50
|
+
display: inline-flex;
|
|
51
|
+
align-items: center;
|
|
52
|
+
gap: 14px;
|
|
53
|
+
font-weight: 700;
|
|
54
|
+
color: var(--text);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.brand-logo {
|
|
58
|
+
display: inline-flex;
|
|
59
|
+
align-items: center;
|
|
60
|
+
justify-content: center;
|
|
61
|
+
width: 38px;
|
|
62
|
+
height: 38px;
|
|
63
|
+
border-radius: 10px;
|
|
64
|
+
background: linear-gradient(135deg, var(--primary), #4a90d9);
|
|
65
|
+
color: #fff;
|
|
66
|
+
font-size: 1.15rem;
|
|
67
|
+
font-weight: 700;
|
|
68
|
+
box-shadow: 0 10px 25px rgba(43, 108, 176, 0.2);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.brand-text {
|
|
72
|
+
font-size: 1.5rem;
|
|
73
|
+
letter-spacing: -0.03em;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.main-nav {
|
|
77
|
+
display: flex;
|
|
78
|
+
align-items: center;
|
|
79
|
+
gap: 24px;
|
|
80
|
+
flex-wrap: wrap;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.main-nav a {
|
|
84
|
+
color: var(--muted);
|
|
85
|
+
text-decoration: none;
|
|
86
|
+
font-size: 1rem;
|
|
87
|
+
font-weight: 600;
|
|
88
|
+
transition: color 0.2s ease;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.main-nav a:hover {
|
|
92
|
+
color: var(--primary-dark);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.page-shell {
|
|
96
|
+
flex: 1;
|
|
97
|
+
padding: 42px 0 64px;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.hero {
|
|
101
|
+
background: linear-gradient(145deg, #ffffff 0%, #f4f8fc 100%);
|
|
102
|
+
border: 1px solid var(--border);
|
|
103
|
+
border-radius: 18px;
|
|
104
|
+
box-shadow: 0 16px 38px var(--shadow);
|
|
105
|
+
padding: 52px 44px;
|
|
106
|
+
margin-bottom: 28px;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.eyebrow {
|
|
110
|
+
margin: 0 0 12px;
|
|
111
|
+
color: var(--primary);
|
|
112
|
+
text-transform: uppercase;
|
|
113
|
+
letter-spacing: 0.1em;
|
|
114
|
+
font-size: 0.75rem;
|
|
115
|
+
font-weight: 700;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.hero-copy h1 {
|
|
119
|
+
margin: 0 0 14px;
|
|
120
|
+
font-size: clamp(2.2rem, 4vw, 3.6rem);
|
|
121
|
+
line-height: 1.08;
|
|
122
|
+
letter-spacing: -0.04em;
|
|
123
|
+
color: #1d2a36;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.lead {
|
|
127
|
+
margin: 0;
|
|
128
|
+
max-width: 700px;
|
|
129
|
+
color: var(--muted);
|
|
130
|
+
font-size: 1.1rem;
|
|
131
|
+
line-height: 1.7;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.content-panel {
|
|
135
|
+
background: var(--panel);
|
|
136
|
+
border: 1px solid var(--border);
|
|
137
|
+
border-radius: 16px;
|
|
138
|
+
box-shadow: 0 10px 22px rgba(15, 23, 42, 0.04);
|
|
139
|
+
padding: 28px 30px;
|
|
140
|
+
line-height: 1.7;
|
|
141
|
+
color: var(--text);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.content-panel h1,
|
|
145
|
+
.content-panel h2,
|
|
146
|
+
.content-panel h3 {
|
|
147
|
+
color: #1d2a36;
|
|
148
|
+
margin-top: 0;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.content-panel p,
|
|
152
|
+
.content-panel li {
|
|
153
|
+
color: var(--text);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.site-footer {
|
|
157
|
+
background: var(--footer);
|
|
158
|
+
color: rgba(255, 255, 255, 0.75);
|
|
159
|
+
border-top: 1px solid rgba(255, 255, 255, 0.08);
|
|
160
|
+
padding: 24px 0;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.footer-inner {
|
|
164
|
+
display: flex;
|
|
165
|
+
justify-content: space-between;
|
|
166
|
+
align-items: center;
|
|
167
|
+
gap: 20px;
|
|
168
|
+
flex-wrap: wrap;
|
|
169
|
+
font-size: 0.92rem;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.footer-inner p {
|
|
173
|
+
margin: 0;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
@media (max-width: 760px) {
|
|
177
|
+
.topbar {
|
|
178
|
+
flex-direction: column;
|
|
179
|
+
align-items: flex-start;
|
|
180
|
+
padding: 18px 0;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
.main-nav {
|
|
184
|
+
gap: 16px;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.hero {
|
|
188
|
+
padding: 32px 24px;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.content-panel {
|
|
192
|
+
padding: 20px 18px;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.footer-inner {
|
|
196
|
+
flex-direction: column;
|
|
197
|
+
align-items: flex-start;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**************************************************************************************************
|
|
2
|
+
* RadixCMS
|
|
3
|
+
*
|
|
4
|
+
* DESCRIPTION: client-side behavior for the default theme.
|
|
5
|
+
*
|
|
6
|
+
* Copyright (C) 2026 Ultra Spark Software <salve@ultraspark.net>
|
|
7
|
+
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
8
|
+
**************************************************************************************************/
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title><%= title %> - <%= siteName || 'Radix' %></title>
|
|
7
|
+
<link rel="stylesheet" href="/themes/default/assets/css/style.css">
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<header class="site-header">
|
|
11
|
+
<div class="container topbar">
|
|
12
|
+
<div class="brand" aria-label="Brand logo">
|
|
13
|
+
<div class="brand-logo">R</div>
|
|
14
|
+
<div class="brand-text"><%= siteName || 'Radix' %></div>
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
<nav class="main-nav" aria-label="Main navigation">
|
|
18
|
+
<a href="/">Home</a>
|
|
19
|
+
<a href="/about">About</a>
|
|
20
|
+
<% if (user && ['Editor', 'Manager', 'Administrator'].includes(user.role)) { %>
|
|
21
|
+
<a href="/admin">Admin</a>
|
|
22
|
+
<a href="/admin/logout">Logout</a>
|
|
23
|
+
<% } else if (user && user.role === 'Registered') { %>
|
|
24
|
+
<a href="/admin/logout">Logout</a>
|
|
25
|
+
<% } else { %>
|
|
26
|
+
<a href="/admin/login">Login</a>
|
|
27
|
+
<% } %>
|
|
28
|
+
</nav>
|
|
29
|
+
</div>
|
|
30
|
+
</header>
|
|
31
|
+
|
|
32
|
+
<main class="page-shell">
|
|
33
|
+
<div class="container">
|
|
34
|
+
<section class="hero">
|
|
35
|
+
<div class="hero-copy">
|
|
36
|
+
<p class="eyebrow">Welcome</p>
|
|
37
|
+
<h1><%= title %></h1>
|
|
38
|
+
<p class="lead">A modern, lightweight CMS built for straightforward content publishing and administration.</p>
|
|
39
|
+
</div>
|
|
40
|
+
</section>
|
|
41
|
+
|
|
42
|
+
<article class="content-panel">
|
|
43
|
+
<%- content %>
|
|
44
|
+
</article>
|
|
45
|
+
</div>
|
|
46
|
+
</main>
|
|
47
|
+
|
|
48
|
+
<footer class="site-footer">
|
|
49
|
+
<div class="container footer-inner">
|
|
50
|
+
<p>Built by <a href="https://www.ultraspark.net" style="font-weight: bold;color: #FFF;text-decoration: none" target="_blank">ULTRASPARK</a></p>
|
|
51
|
+
<p>Version <%= appVersion || '0.11.0' %></p>
|
|
52
|
+
</div>
|
|
53
|
+
</footer>
|
|
54
|
+
</body>
|
|
55
|
+
</html>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**************************************************************************************************
|
|
2
|
+
* RadixCMS
|
|
3
|
+
*
|
|
4
|
+
* DESCRIPTION: client-side behavior for the landing theme.
|
|
5
|
+
*
|
|
6
|
+
* Copyright (C) 2026 Ultra Spark Software <salve@ultraspark.net>
|
|
7
|
+
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
8
|
+
**************************************************************************************************/
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<title><%= title %></title>
|
|
6
|
+
<!-- Resolve the theme stylesheet cleanly -->
|
|
7
|
+
<link rel="stylesheet" href="/themes/<%= currentTheme %>/assets/css/style.css">
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<nav>
|
|
11
|
+
<a href="/">Home</a> | <a href="/about">About</a> |
|
|
12
|
+
<% if (user && ['Editor', 'Manager', 'Administrator'].includes(user.role)) { %>
|
|
13
|
+
<a href="/admin">Admin</a> | <a href="/admin/logout">Logout</a>
|
|
14
|
+
<% } else if (user && user.role === 'Registered') { %>
|
|
15
|
+
<a href="/admin/logout">Logout</a>
|
|
16
|
+
<% } else { %>
|
|
17
|
+
<a href="/admin/login">Login</a>
|
|
18
|
+
<% } %>
|
|
19
|
+
</nav>
|
|
20
|
+
Landing Theme
|
|
21
|
+
<hr>
|
|
22
|
+
<main>
|
|
23
|
+
<%- content %>
|
|
24
|
+
</main>
|
|
25
|
+
</body>
|
|
26
|
+
</html>
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/index.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
const http = require('http');
|
|
3
|
-
|
|
4
|
-
const hostname = '127.0.0.1';
|
|
5
|
-
const port = 3000;
|
|
6
|
-
|
|
7
|
-
const server = http.createServer((req, res) => {
|
|
8
|
-
res.statusCode = 200;
|
|
9
|
-
res.setHeader('Content-Type', 'text/html');
|
|
10
|
-
res.end('<h1>Hello, World!</h1>');
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
server.listen(port, hostname, () => {
|
|
14
|
-
console.log(`Server running at http://${hostname}:${port}/`);
|
|
15
|
-
});
|