From c53e46c264a4da6a76c8303490ae195268f124d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Casal?= Date: Wed, 1 May 2024 20:10:26 +0100 Subject: [PATCH] SEO optimized tutoring page --- app/components/newsletter.tsx | 1 + app/routes/_marketing+/tutoring.tsx | 20 ++- .../_pseo+/explicacoes.$subjectslug.tsx | 136 ++++++++++++++++++ app/routes/_pseo+/subject-data.ts | 74 ++++++++++ 4 files changed, 228 insertions(+), 3 deletions(-) create mode 100644 app/routes/_pseo+/explicacoes.$subjectslug.tsx create mode 100644 app/routes/_pseo+/subject-data.ts diff --git a/app/components/newsletter.tsx b/app/components/newsletter.tsx index 93dbba2..c8183b2 100644 --- a/app/components/newsletter.tsx +++ b/app/components/newsletter.tsx @@ -61,6 +61,7 @@ const Newsletter = ({ className, title, description, buttonText }: NewsletterPro action="/newsletter" className={`col-start-1 row-start-1 ${state === 'initial' ? ' opacity-100' : 'pointer-events-none opacity-0'}`} {...form.props} + encType="multipart/form-data" > diff --git a/app/routes/_marketing+/tutoring.tsx b/app/routes/_marketing+/tutoring.tsx index bdb65c9..5f8f10c 100644 --- a/app/routes/_marketing+/tutoring.tsx +++ b/app/routes/_marketing+/tutoring.tsx @@ -12,7 +12,7 @@ import satisfactionGuarantee from './images/satisfaction-guarantee.png' import signatureBlack from './images/signature-black.png' import signatureWhite from './images/signature-white.png' import { Link } from '@remix-run/react' -import { type LinksFunction } from '@remix-run/node' +import { type V2_MetaFunction, type LinksFunction } from '@remix-run/node' import { Container } from '~/ui_components/layout/container.tsx' import { H1 } from '~/ui_components/typography/h1.tsx' import { P } from '~/ui_components/typography/p.tsx' @@ -25,6 +25,20 @@ export const links: LinksFunction = () => { return [{ rel: 'canonical', href: 'https://andrecasal.com/tutoring' }] } +export const meta: V2_MetaFunction = () => { + return [ + { title: 'Private tutor for coding or programming subjects' }, + { + name: 'description', + content: "Searching for a tutoring and what results? I've helped 650+ students obliterate their exams! Satisfaction 100% guaranteed!", + }, + { + name: 'keywords', + content: 'tutoring, private tutoring, private tutor, tutor, programming tutor, coding tutor, computer science tutor, software engineering tutor, web development tutor', + }, + ] +} + const Tutoring = () => { const features = [ { @@ -358,9 +372,9 @@ const Tutoring = () => {
-

+

About André -

+

André is a serial entrepreneur with a background in software engineering, working for more than {new Date().getFullYear() - 2006} years, with companies like Calouste Gulbenkian Foundation, American TV network NBC, and energy drink Monster Energy. He has provided technical direction to countless startups, and diff --git a/app/routes/_pseo+/explicacoes.$subjectslug.tsx b/app/routes/_pseo+/explicacoes.$subjectslug.tsx new file mode 100644 index 0000000..ccd09b7 --- /dev/null +++ b/app/routes/_pseo+/explicacoes.$subjectslug.tsx @@ -0,0 +1,136 @@ +import { Button } from '~/components/ui/button.tsx' +import { Icon } from '~/components/ui/icon.tsx' +import BackgroundDiagonal from './components/bg-diagonal.tsx' +import BackgroundBlur from './components/bg-blur.tsx' +import BackgroundSquareLines from './components/bg-square-lines.tsx' +import collegeLife from '../_marketing+/images/college-life.jpg' +import andreOnMacBookPro from './images/andre-on-macbook-pro.png' +import goncaloBarreiros from './images/goncalo-barreiros.png' +import pauloJorge from './images/paulo-jorge.png' +import miguelFerreira from './images/miguel-ferreira.png' +import satisfactionGuarantee from './images/satisfaction-guarantee.png' +import signatureBlack from './images/signature-black.png' +import signatureWhite from './images/signature-white.png' +import { Link, useLoaderData } from '@remix-run/react' +import { type LoaderFunction, json, type LinksFunction, type V2_MetaFunction, type LoaderArgs } from '@remix-run/node' +import { Container } from '~/ui_components/layout/container.tsx' +import { H1 } from '~/ui_components/typography/h1.tsx' +import { P } from '~/ui_components/typography/p.tsx' +import { H2 } from '~/ui_components/typography/h2.tsx' +import { H3 } from '~/ui_components/typography/h3.tsx' +import { Span } from '~/ui_components/typography/span.tsx' +import { H4 } from '~/ui_components/typography/h4.tsx' +import { subjects } from './subject-data.ts' +import { Ul } from '~/ui_components/typography/ul.tsx' + +export const meta: V2_MetaFunction = ({ params }) => { + const { subjectslug } = params + const subject = subjects.find(s => s.slug === subjectslug) + const { slug, name, prerequisites, topics, software, exercises, isTutorable } = subject + return [ + { title: `Explicações de ${name}` }, + { + name: 'description', + content: `Procuras explicações de ${name} e queres resultados? Ajudei 650+ alunos a obliterar os exames! Satisfação 100% garantida!`, + }, + { + name: 'keywords', + content: `explicações, ${name}, tutoria, universidade, estudantes, notas, exames, sucesso, resultados, garantia, tutor, explicador, mentor, explicação, explicadores, mentores, tutorias`, + }, + ] +} + +export const links: LinksFunction = () => { + return [ + { + rel: 'preload', + href: collegeLife, + as: 'image', + }, + { + rel: 'canonical', + href: `https://andrecasal.com/explicacoes/programacao`, + }, + ] +} + +export async function loader({ params }: LoaderArgs) { + const { subjectslug } = params + const subject = subjects.find(s => s.slug === subjectslug)! + return json({ subject }) +} + +const Explicacoes = () => { + const { subject } = useLoaderData() + const { slug, name, prerequisites, topics, software, exercises, isTutorable } = subject + + return ( + <> + +

+
+
+

+ Explicações de {name} +

+

+ Aqui tens tudo o que precisas para ter sucesso em {name}! +

+
+
+
+ Explicações de Programação +
+
+ + +
+

+ Pré-requisitos de {name} +

+

Estas são as coisas que já tens que dominar de forma a estares preparado para {name}:

+
    + {prerequisites.map(prerequisite => ( +
  • {prerequisite}
  • + ))} +
+

+ Tópicos de {name} +

+

Esta é a lista da matéria para {name}:

+
    + {topics.map(({ name, children }) => ( +
  • + {name} + {children ? ( +
      + {children.map(({ name }) => ( +
    • {name}
    • + ))} +
    + ) : null} +
  • + ))} +
+

+ Software útil para {name} +

+
    + {software.map(({ name, link }) => ( +
  • + + {name} + +
  • + ))} +
+
+
+ + ) +} +export default Explicacoes diff --git a/app/routes/_pseo+/subject-data.ts b/app/routes/_pseo+/subject-data.ts new file mode 100644 index 0000000..2b1212a --- /dev/null +++ b/app/routes/_pseo+/subject-data.ts @@ -0,0 +1,74 @@ +type Software = { + name: string + link: string +} + +type List = { + name: string + children?: List[] +} + +type Subject = { + slug: string + name: string + prerequisites: string[] + topics: List[] + software: Software[] + exercises: string[] + isTutorable: boolean +} + +export const subjects: Subject[] = [ + { + slug: 'sistemas-digitais', + name: 'Sistemas Digitais', + prerequisites: ['Conhecimento básico de álgebra', 'Aritmética e sistemas numéricos (especialmente binário)', 'Manipulação de números e expressões lógicas'], + topics: [ + { name: 'Álgebra de Boole' }, + { name: 'Portas Lógicas (AND, OR, NOT, NAND, NOR, XOR, XNOR)' }, + { name: 'Expressões Booleanas' }, + { name: 'Tabelas de verdade' }, + { name: 'Mapas de Karnaugh' }, + { name: 'Expressões simplificadas' }, + { + name: 'Circuitos Combinatórios', + children: [ + { name: 'Multiplexadores' }, + { name: 'Demultiplexadores' }, + { name: 'Codificadores' }, + { name: 'Descodificadores' }, + { name: 'Somador' }, + { name: 'Somador completo' }, + ], + }, + { + name: 'Circuitos Sequenciais', + children: [ + { name: 'Flip-flops (Latch SR, Latch JK, Flip-flop D, Flip-flop T)' }, + { name: 'Registos' }, + { name: 'Contadores' }, + { name: 'Somador sequencial' }, + { name: 'Subtrator sequencial' }, + ], + }, + { name: 'Máquinas de Estado Finito (FSMs)' }, + { name: 'Síntese Lógica' }, + { name: 'Projeto de Circuitos Digitais' }, + { name: 'Famílias Lógicas (TTL, CMOS)' }, + { name: 'Temporização de Circuitos' }, + { name: 'Memórias (RAM, ROM, EEPROM, Flash)' }, + { name: 'Interfaces Digitais' }, + { name: 'FPGA (Field-Programmable Gate Array)' }, + { name: 'VHDL/Verilog' }, + { name: 'Application-Specific Integrated Circuits (ASICs)' }, + ], + software: [ + { + name: 'Logisim', + link: 'https://sourceforge.net/projects/circuit/', + }, + ], + exercises: ['Construção de circuitos combinatórios', 'Construção de circuitos sequenciais', 'Programação de microcontroladores'], + isTutorable: true, + }, +]