Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add TODOs for dark mode, add support for /catalog #2003

Merged
merged 6 commits into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
2 changes: 1 addition & 1 deletion app/components/beta-course-label.hbs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div
class="inline-flex text-xs text-white font-semibold border border-teal-500 bg-teal-500 rounded px-1.5 py-0.5 w-fit"
class="inline-flex text-xs text-white dark:text-teal-300 font-semibold border border-teal-500 dark:border-teal-800 bg-teal-500 dark:bg-teal-900 rounded px-1.5 py-0.5 w-fit"
data-test-course-beta-label
...attributes
>
Expand Down
22 changes: 12 additions & 10 deletions app/components/course-card.hbs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
{{! template-lint-disable no-invalid-interactive }}
<LinkTo
class="group bg-white p-5 rounded-md shadow hover:shadow-md transition-all cursor-pointer flex flex-col justify-between border relative"
class="group bg-white dark:bg-gray-950 p-5 rounded-md shadow hover:shadow-md transition-all cursor-pointer flex flex-col justify-between border dark:border-gray-800 relative"
@route={{this.linkToRoute.name}}
@model={{this.linkToRoute.model}}
@query={{this.linkToRoute.query}}
Expand All @@ -9,7 +8,7 @@
{{! Logo }}
<div class="w-8 transform scale-100 group-hover:scale-105 flex-shrink-0 transition-all absolute top-5 right-5">
{{#if this.isSkeleton}}
<div class="bg-gray-100 w-8 h-8 rounded-full" />
<div class="bg-gray-100 dark:bg-gray-800 w-8 h-8 rounded-full" />
{{else}}
<CourseLogo @course={{@course}} />
{{/if}}
Expand All @@ -18,7 +17,7 @@
{{! Text }}
<div class="mb-6">
<div class="flex items-center mb-3 flex-wrap gap-y-2 pr-10">
<div class="text-lg font-semibold text-gray-600 mr-2" data-test-course-name>
<div class="text-lg font-semibold text-gray-600 dark:text-gray-300 mr-2" data-test-course-name>
{{#if this.isSkeleton}}
<span class="inline-block bg-gray-100 rounded">{{#each (repeat 30)}}&nbsp;{{/each}}</span>
{{else}}
Expand All @@ -31,10 +30,10 @@
{{#if this.isSkeleton}}
<div>
<div class="relative inline-block w-full">{{#each (repeat 15)}}&nbsp;{{/each}}
<div class="absolute left-0 right-0 top-[2px] bottom-[2px] bg-gray-100 rounded"></div>
<div class="absolute left-0 right-0 top-[2px] bottom-[2px] bg-gray-100 dark:bg-gray-800 rounded"></div>
</div>
<div class="relative inline-block w-full">{{#each (repeat 15)}}&nbsp;{{/each}}
<div class="absolute left-0 right-0 top-[2px] bottom-[2px] bg-gray-100 rounded"></div>
<div class="absolute left-0 right-0 top-[2px] bottom-[2px] bg-gray-100 dark:bg-gray-800 rounded"></div>
</div>
</div>
{{else}}
Expand All @@ -47,13 +46,16 @@
<div class="flex items-center justify-between">
<div class="flex items-center gap-3">
{{#if this.isSkeleton}}
<div class="bg-gray-100 rounded h-4 w-24"></div>
<div class="bg-gray-100 dark:bg-gray-800 rounded h-4 w-24"></div>
{{else}}
{{#if this.lastUsedRepository}}
<CourseCard::ProgressBar @course={{@course}} @lastUsedRepository={{this.lastUsedRepository}} class="flex-shrink-0" />
{{else}}
{{#if @course.releaseStatusIsAlpha}}
<div class="text-xs text-gray-400 font-semibold border border-gray-300 rounded px-1 py-0.25 mr-3" data-test-course-alpha-label>
<div
class="text-xs text-gray-400 dark:text-gray-600 font-semibold border border-gray-300 rounded px-1 py-0.25 mr-3"
data-test-course-alpha-label
>
ALPHA
</div>
{{else if @course.releaseStatusIsBeta}}
Expand All @@ -62,8 +64,8 @@
<FreeCourseLabel @course={{@course}} />
{{else}}
<div class="flex items-center">
{{svg-jar "academic-cap" class="w-4 mr-1 fill-current text-gray-300"}}
<span class="text-xs text-gray-400">{{@course.stages.length}} stages</span>
{{svg-jar "academic-cap" class="w-4 mr-1 fill-current text-gray-300 dark:text-gray-700"}}
<span class="text-xs text-gray-400 dark:text-gray-600">{{@course.stages.length}} stages</span>
</div>
{{/if}}
{{/if}}
Expand Down
2 changes: 1 addition & 1 deletion app/components/free-course-label.hbs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div
class="inline-flex text-xs text-white font-semibold border border-teal-500 bg-teal-500 rounded px-1.5 py-0.5 w-fit"
class="inline-flex text-xs text-white dark:text-teal-300 font-semibold border border-teal-500 dark:border-teal-800 bg-teal-500 dark:bg-teal-900 rounded px-1.5 py-0.5 w-fit"
data-test-course-free-label
...attributes
>
Expand Down
10 changes: 5 additions & 5 deletions app/components/tracks-page/track-card.hbs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div
class="group bg-white p-5 rounded-md shadow-sm hover:shadow transition-all cursor-pointer flex flex-col justify-between border relative"
class="group bg-white dark:bg-gray-950 p-5 rounded-md shadow-sm hover:shadow transition-all cursor-pointer flex flex-col justify-between border dark:border-gray-800 relative"
role="button"
{{on "click" this.navigateToTrack}}
data-test-track-card
Expand All @@ -12,7 +12,7 @@
{{! Text }}
<div class="mb-8">
<div class="flex items-center flex-wrap gap-y-2 pr-16">
<div class="text-gray-600 mr-2" data-test-track-name>
<div class="text-gray-600 dark:text-gray-400 mr-2" data-test-track-name>
{{@language.name}}
</div>

Expand All @@ -36,8 +36,8 @@
/>
{{else}}
<div class="flex items-center">
{{svg-jar "academic-cap" class="w-4 mr-1 fill-current text-gray-300"}}
<span class="text-xs text-gray-400">{{this.stagesCount}} stages</span>
{{svg-jar "academic-cap" class="w-4 mr-1 fill-current text-gray-300 dark:text-gray-700"}}
<span class="text-xs text-gray-400 dark:text-gray-600">{{this.stagesCount}} stages</span>
</div>
{{/if}}

Expand All @@ -50,7 +50,7 @@
{{/if}}
</span>

{{svg-jar "arrow-right" class="w-4 fill-current text-gray-300 group-hover:text-teal-500 transition-colors"}}
{{svg-jar "arrow-right" class="w-4 fill-current text-gray-300 dark:text-gray-700 group-hover:text-teal-500 transition-colors"}}
</div>
</div>
</div>
42 changes: 22 additions & 20 deletions app/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ export default class Router extends EmberRouter {
}

Router.map(function () {
this.route('account-deleted');
this.route('account-deleted'); // TODO: Add dark mode support
this.route('badges');
this.route('catalog');
this.route('code-walkthrough', { path: '/walkthroughs/:code_walkthrough_slug' });
this.route('concepts');
this.route('concept', { path: '/concepts/:concept_slug' });
this.route('catalog'); // TODO: Add dark mode support
this.route('code-walkthrough', { path: '/walkthroughs/:code_walkthrough_slug' }); // TODO: Add dark mode support
this.route('concepts'); // TODO: Add dark mode support
this.route('concept', { path: '/concepts/:concept_slug' }); // TODO: Add dark mode support

this.route('concept-admin', { path: '/concepts/:concept_slug/admin' }, function () {
this.route('basic-details');
Expand All @@ -21,7 +21,7 @@ Router.map(function () {
this.route('questions');
});

this.route('concept-group', { path: '/collections/:concept_group_slug' });
this.route('concept-group', { path: '/collections/:concept_group_slug' }); // TODO: Add dark mode support
this.route('contests');
this.route('contest', { path: '/contests/:contest_slug' });
this.route('courses');
Expand All @@ -43,6 +43,7 @@ Router.map(function () {
this.route('updates');
});

// TODO: Add dark mode support
this.route('course', { path: '/courses/:course_slug' }, function () {
this.route('introduction');
this.route('setup');
Expand All @@ -60,43 +61,44 @@ Router.map(function () {
this.route('completed');
});

this.route('course-overview', { path: '/courses/:course_slug/overview' });
this.route('course-overview', { path: '/courses/:course_slug/overview' }); // TODO: Add dark mode support
this.route('debug');
this.route('join');
this.route('login');
this.route('logged-in');
this.route('membership');
this.route('pay');
this.route('join'); // TODO: Add dark mode support
this.route('login'); // TODO: Add dark mode support?
this.route('logged-in'); // TODO: Add dark mode support?
this.route('membership'); // TODO: Add dark mode support
this.route('pay'); // TODO: Add dark mode support

this.route('perk', { path: '/perks/:slug' }, function () {
this.route('claim');
});

this.route('partner');
this.route('refer');
this.route('referral-link', { path: '/r/:referral_link_slug' });
this.route('refer'); // TODO: Add dark mode support
this.route('referral-link', { path: '/r/:referral_link_slug' }); // TODO: Add dark mode support

this.route('settings', function () {
this.route('profile');
this.route('account');
});

this.route('team', { path: '/teams/:team_id' });
this.route('teams.create', { path: '/teams/create' });
this.route('team', { path: '/teams/:team_id' }); // TODO: Add dark mode support
this.route('teams.create', { path: '/teams/create' }); // TODO: Add dark mode support
this.route('teams.pay', { path: '/teams/pay' });
this.route('track', { path: '/tracks/:track_slug' });
this.route('track', { path: '/tracks/:track_slug' }); // TODO: Add dark mode support
this.route('tracks');
this.route('update-required');
this.route('user', { path: '/users/:username' });
this.route('update-required'); // TODO: Add dark mode support
this.route('user', { path: '/users/:username' }); // TODO: Add dark mode support

// TODO: Add dark mode support
this.route('vote', function () {
this.route('course-ideas', { path: '/challenge-ideas' });
this.route('course-extension-ideas', { path: '/challenge-extension-ideas' });
});

this.route('welcome');

this.route('not-found', { path: '/*path' }); // Catch-all
this.route('not-found', { path: '/*path' }); // Catch-all (TODO: Add dark mode support)
this.route('not-found', { path: '/404' }); // Allow redirecting to this route

this.route('demo', function () {
Expand Down
5 changes: 5 additions & 0 deletions app/routes/catalog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type AuthenticatorService from 'codecrafters-frontend/services/authentica
import BaseRoute from 'codecrafters-frontend/utils/base-route';
import RepositoryPoller from 'codecrafters-frontend/utils/repository-poller';
import RSVP from 'rsvp';
import RouteInfoMetadata, { RouteColorScheme } from 'codecrafters-frontend/utils/route-info-metadata';

export type ModelType = {
repositories?: RepositoryModel[];
Expand All @@ -17,6 +18,10 @@ export default class CatalogRoute extends BaseRoute {
@service declare authenticator: AuthenticatorService;
@service declare store: Store;

buildRouteInfoMetadata(): RouteInfoMetadata {
return new RouteInfoMetadata({ colorScheme: RouteColorScheme.Both });
}

model(): Promise<ModelType> {
const modelPromises: {
repositories?: Promise<RepositoryModel[]>;
Expand Down
3 changes: 2 additions & 1 deletion app/services/dark-mode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ export default class DarkModeService extends Service {
* Writes the new Dark Mode preference to localStorage and updates loaded `localStoragePreference`
* @param {'system'|'dark'|'light'|null} newValue New dark mode preference
*/
@action updateLocalStoragePreference(newValue?: LocalStoragePreference) {
@action
updateLocalStoragePreference(newValue?: LocalStoragePreference) {
if (!newValue) {
this.localStorage.removeItem(LOCAL_STORAGE_KEY);
} else {
Expand Down
8 changes: 4 additions & 4 deletions app/templates/catalog.hbs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{{page-title "Catalog"}}

<div class="container mx-auto lg:max-w-screen-lg pt-6 md:pt-10 pb-10 md:pb-48 px-3 md:px-6">
<div class="border-b pb-2 mb-6">
<h1 class="text-3xl text-gray-700 font-bold tracking-tighter">Challenges</h1>
<div class="border-b dark:border-gray-800 pb-2 mb-6">
<h1 class="text-3xl text-gray-700 dark:text-gray-300 font-bold tracking-tighter">Challenges</h1>
</div>

{{#if this.authenticator.currentUser.pendingProductWalkthroughFeatureSuggestion}}
Expand All @@ -21,8 +21,8 @@
{{/each}}
</div>

<div class="border-b pb-2 mb-6">
<h1 class="text-3xl text-gray-700 font-bold tracking-tighter">Language Tracks</h1>
<div class="border-b dark:border-gray-800 pb-2 mb-6">
<h1 class="text-3xl text-gray-700 dark:text-gray-300 font-bold tracking-tighter">Language Tracks</h1>
</div>

<div class="grid grid-cols-1 gap-3 md:grid-cols-2 lg:grid-cols-3 mb-8">
Expand Down
16 changes: 16 additions & 0 deletions tests/acceptance/view-courses-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,22 @@ module('Acceptance | view-courses', function (hooks) {
assert.notOk(catalogPage.courseCardByName('Build your own SQLite').hasBetaLabel, 'live challenges should not have beta label');
});

test('it renders with dark mode', async function (assert) {
testScenario(this.server);
signIn(this.owner, this.server);

const darkMode = this.owner.lookup('service:dark-mode');
darkMode.updateLocalStoragePreference('dark');

const course = this.server.schema.courses.findBy({ slug: 'grep' });
course.update({ releaseStatus: 'beta' });

await catalogPage.visit();
assert.strictEqual(catalogPage.courseCards.length, 5, 'expected 5 course cards to be present');

await percySnapshot('Catalog Page - Dark Mode');
});

test('it renders alpha courses if user is staff', async function (assert) {
testScenario(this.server);
signInAsStaff(this.owner, this.server);
Expand Down
Loading