diff --git a/frontend/src/pages/Settings.jsx b/frontend/src/pages/Settings.jsx
index 468a59c5..9f59efbf 100644
--- a/frontend/src/pages/Settings.jsx
+++ b/frontend/src/pages/Settings.jsx
@@ -3,7 +3,7 @@ import { useAuth } from '../contexts/AuthContext';
import api from '../services/api';
import UsersTab from '../components/settings/UsersTab';
import AuditLogTab from '../components/settings/AuditLogTab';
-import { Github, FileText, HelpCircle, MessageSquare, Bug, Check, Layers, Download, CheckCircle, RefreshCw, ExternalLink } from 'lucide-react';
+import { Github, FileText, HelpCircle, MessageSquare, Bug, Check, Layers, Download, CheckCircle, RefreshCw, ExternalLink, Star, X } from 'lucide-react';
const Settings = () => {
const [activeTab, setActiveTab] = useState('profile');
@@ -1647,10 +1647,15 @@ const SystemInfo = () => {
);
};
+const STAR_PROMPT_KEY = 'serverkit-star-prompt-dismissed';
+
const AboutSection = () => {
const [version, setVersion] = useState('...');
const [updateInfo, setUpdateInfo] = useState(null);
const [checkingUpdate, setCheckingUpdate] = useState(false);
+ const [showStarPrompt, setShowStarPrompt] = useState(() => {
+ return localStorage.getItem(STAR_PROMPT_KEY) !== 'true';
+ });
useEffect(() => {
const fetchVersion = async () => {
@@ -1664,6 +1669,11 @@ const AboutSection = () => {
fetchVersion();
}, []);
+ const dismissStarPrompt = () => {
+ setShowStarPrompt(false);
+ localStorage.setItem(STAR_PROMPT_KEY, 'true');
+ };
+
const checkForUpdate = async () => {
setCheckingUpdate(true);
try {
@@ -1733,6 +1743,30 @@ const AboutSection = () => {
+ {showStarPrompt && (
+
+
+
+
+
+
+
Enjoying ServerKit?
+
If you find ServerKit useful, consider starring the repository on GitHub. It helps others discover the project!
+
+
+ Star on GitHub
+
+
+
+ )}
+
Features
diff --git a/frontend/src/styles/pages/_settings.less b/frontend/src/styles/pages/_settings.less
index 34ee04e7..436119ed 100644
--- a/frontend/src/styles/pages/_settings.less
+++ b/frontend/src/styles/pages/_settings.less
@@ -660,6 +660,81 @@
to { transform: rotate(360deg); }
}
+// Star Prompt Card
+.star-prompt-card {
+ position: relative;
+ background: linear-gradient(135deg, @accent-glow 0%, fade(@accent-primary, 8%) 100%);
+ border: 1px solid fade(@accent-primary, 30%);
+ border-radius: @radius-lg;
+ padding: @space-6;
+ display: flex;
+ align-items: flex-start;
+ gap: @space-4;
+
+ .dismiss-btn {
+ position: absolute;
+ top: @space-3;
+ right: @space-3;
+ background: none;
+ border: none;
+ color: @text-tertiary;
+ cursor: pointer;
+ padding: @space-1;
+ border-radius: @radius-sm;
+ transition: all @transition-fast;
+
+ &:hover {
+ background: @bg-hover;
+ color: @text-primary;
+ }
+ }
+
+ .star-icon {
+ flex-shrink: 0;
+ width: 48px;
+ height: 48px;
+ background: linear-gradient(135deg, @warning 0%, darken(@warning, 10%) 100%);
+ border-radius: @radius-lg;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: white;
+ }
+
+ .star-content {
+ flex: 1;
+ padding-right: @space-6;
+
+ h4 {
+ margin: 0 0 @space-2;
+ font-size: @font-size-md;
+ font-weight: @font-weight-semibold;
+ }
+
+ p {
+ margin: 0 0 @space-4;
+ font-size: @font-size-sm;
+ color: @text-secondary;
+ line-height: @line-height-relaxed;
+ }
+
+ .btn {
+ display: inline-flex;
+ align-items: center;
+ gap: @space-2;
+ }
+ }
+
+ @media (max-width: @breakpoint-sm) {
+ flex-direction: column;
+ text-align: center;
+
+ .star-content {
+ padding-right: 0;
+ }
+ }
+}
+
// Feature List
.feature-list {
list-style: none;