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
2 changes: 0 additions & 2 deletions .eslintignore

This file was deleted.

59 changes: 0 additions & 59 deletions .eslintrc

This file was deleted.

4 changes: 3 additions & 1 deletion bin/rss/RssFeedGenerator.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { join } from "node:path";

import { describe, it, expect, assert } from "vitest";

import { RssFeedGenerator } from "./RssFeedGenerator";

describe("RssFeedGenerator", () => {
Expand Down Expand Up @@ -67,7 +69,7 @@ describe("RssFeedGenerator", () => {
const articles = feed.match(/<entry>.*?<\/entry>/gs);

if (articles === null) {
fail("No articles found");
assert.fail("No articles found");
}

expect(articles[0]).toMatch(/<title type="html"><!\[CDATA\[Newest\]\]><\/title>/);
Expand Down
16 changes: 3 additions & 13 deletions bin/rss/RssFeedGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,7 @@ export class RssFeedGenerator {
const BASE_URL = "https://codecoolture.com";

const feed = new Feed({
author: {
name: "Sergio Álvarez",
email: "[email protected]",
link: "https://codecoolture.com/about",
},
author: { name: "Sergio Álvarez", email: "[email protected]", link: "https://codecoolture.com/about" },
copyright: `All rights reserved. Sergio Álvarez. ${new Date().getFullYear()}`,
description:
"Articles and notes about software development. Written by Sergio Álvarez. Better code, one piece at a time.",
Expand All @@ -40,18 +36,12 @@ export class RssFeedGenerator {

for (const apiArticle of apiArticlesFromNewestToOldest) {
feed.addItem({
author: [
{
email: "[email protected]",
link: "https://codecoolture.com/about",
name: "Sergio Álvarez",
},
],
author: [{ email: "[email protected]", link: "https://codecoolture.com/about", name: "Sergio Álvarez" }],
title: apiArticle.title,
id: `${BASE_URL}${apiArticle.url}`,
link: `${BASE_URL}${apiArticle.url}`,
description: apiArticle.spoiler ?? undefined,
content: marked(apiArticle.content),
content: await marked(apiArticle.content),
date: new Date(apiArticle.date),
image: apiArticle.cover ?? undefined,
});
Expand Down
2 changes: 2 additions & 0 deletions cms/lib/Markdown.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { join } from "node:path";

import { beforeEach, describe, expect, it } from "vitest";

import { Markdown } from "./Markdown";

describe("Markdown", () => {
Expand Down
2 changes: 2 additions & 0 deletions cms/lib/MarkdownRepository.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { join } from "path";

import { describe, it, expect } from "vitest";

import { DirectoryNotFound, FileNotFound } from "./errors";
import { MarkdownRepository } from "./MarkdownRepository";

Expand Down
2 changes: 2 additions & 0 deletions cms/models/Article.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { join } from "node:path";

import { describe, it, expect } from "vitest";

import { Markdown } from "@/cms/lib/Markdown";

import { Article } from "./Article";
Expand Down
2 changes: 1 addition & 1 deletion components/Blockquote/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export function Blockquote({ children }: Pick<JSX.IntrinsicElements["blockquote"], "children">) {
export function Blockquote({ children }: Pick<React.JSX.IntrinsicElements["blockquote"], "children">) {
return <blockquote className="Blockquote">{children}</blockquote>;
}
2 changes: 1 addition & 1 deletion components/Code/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { classNames } from "@/lib/classNames";

type CodeProps = Pick<JSX.IntrinsicElements["code"], "className" | "children"> & {
type CodeProps = Pick<React.JSX.IntrinsicElements["code"], "className" | "children"> & {
"data-qa"?: string;
};

Expand Down
2 changes: 1 addition & 1 deletion components/Codeblock/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useDarkMode } from "@/hooks";
import { classNames } from "@/lib/classNames";

type CodeblockProps = Pick<JSX.IntrinsicElements["pre"], "children" | "className">;
type CodeblockProps = Pick<React.JSX.IntrinsicElements["pre"], "children" | "className">;

export function Codeblock({ children }: CodeblockProps) {
const { isDarkModeEnabled } = useDarkMode();
Expand Down
2 changes: 1 addition & 1 deletion components/Figure/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
alt?: string;
className?: string;
loading?: "eager" | "lazy";
src?: string;
src?: React.JSX.IntrinsicElements["img"]["src"];
title?: string;
};

export function Figure({ className, title, ...props }: FigureProps) {
return (
<figure className={classNames("Figure", className)}>
<img className="Figure__Img" loading="lazy" {...props} />

Check warning on line 14 in components/Figure/index.tsx

View workflow job for this annotation

GitHub Actions / analyze

img elements must have an alt prop, either with meaningful text, or an empty string for decorative images

Check warning on line 14 in components/Figure/index.tsx

View workflow job for this annotation

GitHub Actions / analyze

Using `<img>` could result in slower LCP and higher bandwidth. Consider using `<Image />` from `next/image` or a custom image loader to automatically optimize images. This may incur additional usage or cost from your provider. See: https://nextjs.org/docs/messages/no-img-element

<figcaption className="Figure__Caption">{title}</figcaption>
</figure>
Expand Down
2 changes: 1 addition & 1 deletion components/Link/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { classNames } from "@/lib/classNames";

export type LinkProps = Pick<
JSX.IntrinsicElements["a"],
React.JSX.IntrinsicElements["a"],
"href" | "rel" | "target" | "className" | "children" | "id"
> & {
as?: React.ElementType;
Expand Down
4 changes: 2 additions & 2 deletions components/List/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { classNames } from "@/lib/classNames";

function Item({ children, id }: Pick<JSX.IntrinsicElements["li"], "children" | "id">) {
function Item({ children, id }: Pick<React.JSX.IntrinsicElements["li"], "children" | "id">) {
return (
<li className="List__Item" id={id}>
<div className="List__Item__Wrapper">{children}</div>
</li>
);
}

export type ListProps = Pick<JSX.IntrinsicElements["ul"], "children"> & {
export type ListProps = Pick<React.JSX.IntrinsicElements["ul"], "children"> & {
type?: "bullet" | "number";
};

Expand Down
2 changes: 1 addition & 1 deletion components/Text/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export type TextProps = Pick<JSX.IntrinsicElements["p"], "children" | "className"> & {
export type TextProps = Pick<React.JSX.IntrinsicElements["p"], "children" | "className"> & {
size?: "l" | "m";
};

Expand Down
13 changes: 7 additions & 6 deletions contexts/DarkModeContext.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { noop } from "lodash";
import { createContext, ReactNode, useEffect, useMemo, useState } from "react";
import { createContext, ReactNode, useMemo, useState } from "react";

type DarkModeContextValue = {
isDarkModeEnabled: boolean;
Expand All @@ -12,14 +12,15 @@
/**
* We make dark mode enabled by default.
*/
const [isDarkModeEnabled, setIsDarkModeEnabled] = useState(true);
const [isDarkModeEnabled, setIsDarkModeEnabled] = useState(() => {
if (typeof window === "undefined") {
return true;
}

/**
* We check if the user has a preference for dark mode and we set it accordingly.
*/
useEffect(() => setIsDarkModeEnabled(window.localStorage.getItem("darkMode") !== "false"), []);
return window.localStorage.getItem("darkMode") !== "false";
});

const toggleDarkMode = (enable?: boolean) => {

Check warning on line 23 in contexts/DarkModeContext.tsx

View workflow job for this annotation

GitHub Actions / analyze

The 'toggleDarkMode' function makes the dependencies of useMemo Hook (at line 31) change on every render. Move it inside the useMemo callback. Alternatively, wrap the definition of 'toggleDarkMode' in its own useCallback() Hook
const toggleTo = enable ?? !isDarkModeEnabled;

window.localStorage.setItem("darkMode", toggleTo.toString());
Expand Down
47 changes: 47 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { defineConfig } from "eslint/config";
import nextVitals from "eslint-config-next/core-web-vitals";
import nextTypeScript from "eslint-config-next/typescript";
import prettier from "eslint-plugin-prettier/recommended";

export default defineConfig([
...nextVitals,

...nextTypeScript,

prettier,

{
rules: {
"no-restricted-imports": [
"error",
{
patterns: [
{
group: ["../*"],
message: "Usage of relative parent imports is not allowed.",
},
],
},
],

"react/react-in-jsx-scope": "off",

"react/no-unknown-property": [2, { ignore: ["jsx", "global"] }],

"import/no-unresolved": "error",

"import/order": [
"error",
{
"newlines-between": "always",
pathGroups: [
{
pattern: "@/**",
group: "parent",
},
],
},
],
},
},
]);
15 changes: 0 additions & 15 deletions jest.config.js

This file was deleted.

4 changes: 2 additions & 2 deletions layouts/Application/components/Article/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ export function Article({ breadcrumbs = [], children, className }: ArticleProps)
a: Link,
blockquote: Blockquote,
code: Code,
h1: function h1(props: JSX.IntrinsicElements["h1"]) {
h1: function h1(props: React.JSX.IntrinsicElements["h1"]) {
return <Heading el="h1" size="jumbo" {...props} />;
},
h2: function h2(props: JSX.IntrinsicElements["h2"]) {
h2: function h2(props: React.JSX.IntrinsicElements["h2"]) {
return <Heading el="h2" size="l" {...props} />;
},
inlineCode: Code,
Expand Down
10 changes: 5 additions & 5 deletions layouts/Post/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,19 @@ export function Post({ breadcrumbs, mdx, post }: PostProps) {
a: Link,
blockquote: Blockquote,
code: Code,
h1: function h1(props: JSX.IntrinsicElements["h1"]) {
h1: function h1(props: React.JSX.IntrinsicElements["h1"]) {
return <Heading el="h1" size="jumbo" {...props} />;
},
h2: function h2(props: JSX.IntrinsicElements["h2"]) {
h2: function h2(props: React.JSX.IntrinsicElements["h2"]) {
return <Heading el="h2" size="l" {...props} />;
},
h3: function h3(props: JSX.IntrinsicElements["h3"]) {
h3: function h3(props: React.JSX.IntrinsicElements["h3"]) {
return <Heading el="h3" size="m" {...props} />;
},
img: (props: JSX.IntrinsicElements["img"]) => <Figure className="Post__Figure" {...props} />,
img: (props: React.JSX.IntrinsicElements["img"]) => <Figure className="Post__Figure" {...props} />,
inlineCode: Code,
li: List.Item,
ol: function OrderedList(props: JSX.IntrinsicElements["ol"]) {
ol: function OrderedList(props: React.JSX.IntrinsicElements["ol"]) {
return <List type="number">{props.children}</List>;
},
p: Text,
Expand Down
3 changes: 2 additions & 1 deletion next-env.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
import "./.next/dev/types/routes.d.ts";

// NOTE: This file should not be edited
// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information.
// see https://nextjs.org/docs/pages/api-reference/config/typescript for more information.
Loading
Loading