Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 11 additions & 13 deletions sql/auth/user_preferences.sql
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,35 @@ CREATE TABLE IF NOT EXISTS user_preferences (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
hide_from_leaderboard BOOLEAN NOT NULL DEFAULT false,
theme TEXT NOT NULL DEFAULT 'light',
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
UNIQUE(user_id)
);

-- Create RLS policies for user_preferences table
ALTER TABLE user_preferences ENABLE ROW LEVEL SECURITY;

-- Drop existing policies if they exist
DROP POLICY IF EXISTS "Users can read their own preferences" ON user_preferences;
DROP POLICY IF EXISTS "Users can insert their own preferences" ON user_preferences;
DROP POLICY IF EXISTS "Users can update their own preferences" ON user_preferences;
-- Users can read their own preferences
CREATE POLICY "Users can read their own preferences" ON user_preferences FOR
SELECT USING (auth.uid() = user_id);

-- Users can insert their own preferences
CREATE POLICY "Users can insert their own preferences" ON user_preferences FOR
INSERT WITH CHECK (auth.uid() = user_id);

-- Users can update their own preferences
CREATE POLICY "Users can update their own preferences" ON user_preferences FOR
UPDATE USING (auth.uid() = user_id);

-- Create function to automatically create user preferences on new user creation
CREATE OR REPLACE FUNCTION public.handle_new_user_preferences() RETURNS TRIGGER AS $$
BEGIN
INSERT INTO public.user_preferences (user_id, hide_from_leaderboard)
VALUES (NEW.id, false);
RETURN NEW;
CREATE OR REPLACE FUNCTION public.handle_new_user_preferences() RETURNS TRIGGER AS $$ BEGIN
INSERT INTO public.user_preferences (user_id, hide_from_leaderboard, theme)
VALUES (NEW.id, false, 'light');
RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

-- Create trigger to call the function when a new user is created
DROP TRIGGER IF EXISTS on_auth_user_created_preferences ON auth.users;
CREATE TRIGGER on_auth_user_created_preferences
AFTER INSERT ON auth.users
FOR EACH ROW EXECUTE FUNCTION public.handle_new_user_preferences();
AFTER
INSERT ON auth.users FOR EACH ROW EXECUTE FUNCTION public.handle_new_user_preferences();
67 changes: 45 additions & 22 deletions src/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,27 @@
@layer theme {
:root {
/* Fonts */
--font-sans:
Arial, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell,
'Open Sans', 'Helvetica Neue', sans-serif;
--font-sans: 'Courier New', Courier, monospace;
--font-mono: 'Fira Mono', monospace;

/* Colors */
/* Colors - Retro Computer Theme - Blue & Pink */
/* These are the default colors that will be overridden by theme selection */
/* The same variables are defined in src/lib/theme-options/retro-blue-light.js */
--color-white: oklch(1 0 0);
--color-black: oklch(0 0 0);
--color-primary: oklch(0.12 0 0);
--color-secondary: oklch(0.19 0 0);
--color-tertiary: oklch(0.28 0 0);
--color-accent: oklch(0.65 0.26 296.88);
--color-heading: oklch(1 0 0 / 0.87);
--color-text: oklch(1 0 0 / 0.6);
--color-text-muted: oklch(1 0 0 / 0.4);
--color-background: oklch(0.19 0 0 / 0.7);
--color-border: oklch(0.44 0 0);
--color-link: oklch(0.65 0.26 296.88);
--color-link-subtle: oklch(0.8 0.1 296.88);
--color-link-nav: oklch(1 0 0 / 0.8);
--color-username: oklch(0.65 0.26 296.88); /* Purple color for usernames */
--color-primary: oklch(0.9 0.03 240); /* Light blue background */
--color-secondary: oklch(0.95 0.02 240); /* Lighter blue for cards */
--color-tertiary: oklch(0.85 0.04 240); /* Slightly darker blue for headers */
--color-accent: oklch(0.7 0.2 350); /* Pink accent */
--color-heading: oklch(0.2 0 0 / 0.9); /* Dark text for headings */
--color-text: oklch(0.2 0 0 / 0.8); /* Dark text for body */
--color-text-muted: oklch(0.2 0 0 / 0.5); /* Muted dark text */
--color-background: oklch(0.9 0.03 240 / 0.7); /* Transparent blue background */
--color-border: oklch(0.75 0.05 240); /* Border color */
--color-link: oklch(0.7 0.2 350); /* Pink links */
--color-link-subtle: oklch(0.75 0.15 350); /* Subtle pink links */
--color-link-nav: oklch(0.2 0 0 / 0.9); /* Dark nav links */
--color-username: oklch(0.6 0.25 30); /* Orange for usernames */
--color-solved-row: color-mix(
in oklab,
rgb(34 197 94) 15%,
Expand Down Expand Up @@ -74,6 +74,12 @@ body {
background-color: var(--color-primary);
color: var(--color-text);
overscroll-behavior: none;
font-family: var(--font-sans);
background-image: linear-gradient(
to bottom,
var(--color-primary),
color-mix(in oklab, var(--color-primary) 90%, var(--color-tertiary))
);
}

#app {
Expand Down Expand Up @@ -190,31 +196,34 @@ img {
/* Component styles */
.card {
background-color: var(--color-secondary);
border-radius: 0.5rem;
border-radius: 0.25rem;
border: 1px solid var(--color-border);
padding: 1.5rem;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.1);
margin-bottom: 1rem;
}

.table {
width: 100%;
border-collapse: collapse;
border: 1px solid var(--color-border);
}

.table th {
text-align: left;
padding: 0.75rem;
border-bottom: 1px solid var(--color-tertiary);
border-bottom: 1px solid var(--color-border);
color: var(--color-heading);
background-color: var(--color-tertiary);
}

.table td {
padding: 0.75rem;
border-bottom: 1px solid var(--color-tertiary);
border-bottom: 1px solid var(--color-border);
}

.table tr:hover {
background-color: var(--color-tertiary);
background-color: color-mix(in oklab, var(--color-tertiary) 50%, transparent);
}

.badge {
Expand All @@ -228,16 +237,19 @@ img {
.badge-easy {
background-color: oklch(0.73 0.2 142.5);
color: white;
border: 1px solid oklch(0.63 0.2 142.5);
}

.badge-medium {
background-color: oklch(0.71 0.19 54.65);
color: white;
border: 1px solid oklch(0.61 0.19 54.65);
}

.badge-hard {
background-color: oklch(0.65 0.27 29.23);
color: white;
border: 1px solid oklch(0.55 0.27 29.23);
}

/* Responsive utilities */
Expand Down Expand Up @@ -302,3 +314,14 @@ img {
width: 100%;
margin: 0 auto;
}

/* Dark theme specific overrides */
body.dark-theme .text-red-500,
body.dark-theme .text-red-600,
body.dark-theme .text-red-700 {
color: rgb(252, 165, 165) !important; /* lighter red for dark theme */
}

body.dark-theme .text-[var(--color-accent)] {
color: rgb(252, 165, 165) !important; /* lighter red for dark theme */
}
63 changes: 63 additions & 0 deletions src/app.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,69 @@
name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"
/>
<!-- Preload styles to prevent theme flashing -->
<style>
:root {
/* Default light theme colors to prevent flashing */
--color-primary: oklch(0.9 0.03 240);
--color-secondary: oklch(0.95 0.02 240);
--color-tertiary: oklch(0.85 0.04 240);
--color-accent: oklch(0.7 0.2 350);
--color-heading: oklch(0.2 0 0 / 0.9);
--color-text: oklch(0.2 0 0 / 0.8);
--color-text-muted: oklch(0.2 0 0 / 0.5);
--color-background: oklch(0.9 0.03 240 / 0.7);
--color-border: oklch(0.75 0.05 240);
}

body {
background-color: var(--color-primary);
color: var(--color-text);
font-family: 'Courier New', Courier, monospace;
transition:
background-color 0.3s ease,
color 0.3s ease;
}
</style>

<!-- Script to apply theme from localStorage immediately -->
<script>
(function () {
try {
const storedTheme = localStorage.getItem('gitgud-theme');
if (storedTheme === 'dark') {
// Add dark theme class to body
document.body.classList.add('dark-theme');
document.body.classList.remove('light-theme');

// Apply dark theme immediately
document.documentElement.style.setProperty('--color-primary', 'oklch(0.2 0.05 240)');
document.documentElement.style.setProperty('--color-secondary', 'oklch(0.25 0.04 240)');
document.documentElement.style.setProperty('--color-tertiary', 'oklch(0.15 0.06 240)');
document.documentElement.style.setProperty('--color-heading', 'oklch(0.9 0 0 / 0.9)');
document.documentElement.style.setProperty('--color-text', 'oklch(0.9 0 0 / 0.8)');
document.documentElement.style.setProperty(
'--color-text-muted',
'oklch(0.9 0 0 / 0.5)'
);
document.documentElement.style.setProperty(
'--color-background',
'oklch(0.2 0.05 240 / 0.7)'
);
document.documentElement.style.setProperty('--color-border', 'oklch(0.3 0.08 240)');
document.documentElement.style.setProperty('--color-link-nav', 'oklch(0.9 0 0 / 0.9)');
document.documentElement.style.setProperty('--color-link', 'oklch(0.85 0.25 350)');
document.documentElement.style.setProperty('--color-link-subtle', 'oklch(0.8 0.2 350)');
} else {
// Add light theme class to body
document.body.classList.add('light-theme');
document.body.classList.remove('dark-theme');
}
} catch (e) {
console.error('Error applying theme:', e);
}
})();
</script>
%sveltekit.head%
</head>
<body>
Expand Down
Loading