SPB Git

Repository Public

teaching-platforms.tsx 3.2 KB 81 lines tsx

1/*2  teaching-platforms.tsx3  spboucher.ai Web4  Author: Simon-Pierre Boucher5  Mail: contact@spboucher.ai6*/78import { ArrowUpRight, Calculator, GraduationCap, type LucideIcon } from "lucide-react";910/** Teaching platforms designed and built by Simon-Pierre Boucher for his UQO courses. */11export const teachingPlatforms: {12  href: string;13  name: string;14  kicker: string;15  description: string;16  icon: LucideIcon;17}[] = [18  {19    href: "https://www.uqo-eval.app",20    name: "UQO Éval",21    kicker: "Appraisal laboratory",22    description:23      "A teaching laboratory for real-estate appraisal built on real Québec data: registered sales, assessment rolls, comparable search, land-adjustment grids and a quantity-survey module. Students use it for their assignments and take-home exams.",24    icon: Calculator,25  },26  {27    href: "https://www.uqo-imm1003.app",28    name: "IMM1003",29    kicker: "Éléments d’évaluation immobilière",30    description:31      "The interactive course site: lecture notes, slide decks for every session, practical assignments, exam preparation and worked cases for the introductory appraisal course.",32    icon: GraduationCap,33  },34  {35    href: "https://www.uqo-imm1033.app",36    name: "IMM1033",37    kicker: "Méthodes du coût",38    description:39      "The interactive course site for the cost approach: land valuation, replacement cost, quantity surveys and depreciation, with notes, slides, assignments and complete cases.",40    icon: GraduationCap,41  },42];4344export function TeachingPlatforms() {45  return (46    <div className="grid gap-3 md:grid-cols-3">47      {teachingPlatforms.map(({ href, name, kicker, description, icon: Icon }, i) => (48        <a49          key={href}50          href={href}51          target="_blank"52          rel="noopener noreferrer"53          className="group flex flex-col border border-foreground/15 bg-card p-5 transition-all hover:-translate-y-px hover:border-primary/60 hover:shadow-[var(--shadow-soft)]"54        >55          <div className="flex items-start justify-between">56            <span className="inline-flex h-10 w-10 items-center justify-center border border-primary/25 bg-primary/5 text-primary transition-colors group-hover:bg-primary group-hover:text-primary-foreground">57              <Icon className="h-5 w-5" aria-hidden="true" />58            </span>59            <span className="font-mono text-[0.62rem] uppercase tracking-[0.2em] text-muted-foreground/70">60              0{i + 1}61            </span>62          </div>63          <p className="mt-4 font-mono text-[0.62rem] font-medium uppercase tracking-[0.16em] text-primary/80">64            {kicker}65          </p>66          <h3 className="mt-1 font-display text-xl font-semibold tracking-tight">67            {name}68          </h3>69          <p className="mt-2 flex-1 text-sm leading-relaxed text-muted-foreground">70            {description}71          </p>72          <p className="mt-4 inline-flex items-center gap-1 font-mono text-[0.68rem] uppercase tracking-[0.12em] text-foreground/80 group-hover:text-primary">73            {href.replace("https://", "")}74            <ArrowUpRight className="h-3.5 w-3.5" aria-hidden="true" />75          </p>76        </a>77      ))}78    </div>79  );80}81
Files main
Menu

Theme