Compare commits

...

6 Commits

Author SHA1 Message Date
naomi 0dc8dcc09d feat: add disclaimer modal
Node.js CI / CI (pull_request) Failing after 34s
Security Scan and Upload / Security & DefectDojo Upload (pull_request) Successful in 54s
2025-12-27 13:52:15 -08:00
naomi 7bd1ef9550 feat: initial theming
Node.js CI / CI (pull_request) Failing after 34s
Security Scan and Upload / Security & DefectDojo Upload (pull_request) Successful in 52s
2025-12-27 13:21:23 -08:00
naomi d33422be37 feat: components 2025-12-27 13:16:26 -08:00
naomi 6bbcb4d8fa feat: linter and tests work now
Node.js CI / CI (pull_request) Successful in 32s
Security Scan and Upload / Security & DefectDojo Upload (pull_request) Successful in 53s
2025-12-27 12:42:17 -08:00
naomi 7e7dd9c134 temp: test if tests can run in ci
Node.js CI / CI (pull_request) Successful in 20s
Security Scan and Upload / Security & DefectDojo Upload (pull_request) Successful in 51s
2025-12-27 12:18:08 -08:00
naomi 2bc5c03ff7 feat: initial angular scaffolding
Node.js CI / CI (pull_request) Failing after 19s
Security Scan and Upload / Security & DefectDojo Upload (pull_request) Successful in 52s
2025-12-27 12:13:58 -08:00
69 changed files with 10056 additions and 14 deletions
+47
View File
@@ -0,0 +1,47 @@
name: Node.js CI
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
ci:
name: CI
runs-on: ubuntu-latest
steps:
- name: Checkout Source Files
uses: actions/checkout@v4
- name: Use Node.js v24
uses: actions/setup-node@v4
with:
node-version: 24
- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: 10
- name: Ensure Dependencies are Pinned
uses: naomi-lgbt/dependency-pin-check@main
with:
language: javascript
dev-dependencies: true
peer-dependencies: true
optional-dependencies: true
- name: Install Dependencies
run: pnpm install
- name: Lint Source Files
run: pnpm run lint
- name: Verify Build
run: pnpm run build
- name: Run Tests
run: pnpm run test
+43
View File
@@ -0,0 +1,43 @@
# See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files.
# Compiled output
/dist
/tmp
/out-tsc
/bazel-out
# Node
/node_modules
npm-debug.log
yarn-error.log
# IDEs and editors
.idea/
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# Visual Studio Code
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.history/*
# Miscellaneous
/.angular/cache
.sass-cache/
/connect.lock
/coverage
/libpeerconnection.log
testem.log
/typings
__screenshots__/
# System files
.DS_Store
Thumbs.db
+5
View File
@@ -0,0 +1,5 @@
{
"plugins": {
"@tailwindcss/postcss": {}
}
}
+4
View File
@@ -0,0 +1,4 @@
{
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846
"recommendations": ["angular.ng-template"]
}
+20
View File
@@ -0,0 +1,20 @@
{
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "ng serve",
"type": "chrome",
"request": "launch",
"preLaunchTask": "npm: start",
"url": "http://localhost:4200/"
},
{
"name": "ng test",
"type": "chrome",
"request": "launch",
"preLaunchTask": "npm: test",
"url": "http://localhost:9876/debug.html"
}
]
}
+7
View File
@@ -0,0 +1,7 @@
{
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"eslint.validate": ["typescript"],
}
+42
View File
@@ -0,0 +1,42 @@
{
// For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "start",
"isBackground": true,
"problemMatcher": {
"owner": "typescript",
"pattern": "$tsc",
"background": {
"activeOnStart": true,
"beginsPattern": {
"regexp": "(.*?)"
},
"endsPattern": {
"regexp": "bundle generation complete"
}
}
}
},
{
"type": "npm",
"script": "test",
"isBackground": true,
"problemMatcher": {
"owner": "typescript",
"pattern": "$tsc",
"background": {
"activeOnStart": true,
"beginsPattern": {
"regexp": "(.*?)"
},
"endsPattern": {
"regexp": "bundle generation complete"
}
}
}
}
]
}
+4 -14
View File
@@ -1,20 +1,10 @@
# New Repository Template
# Lore
This template contains all of our basic files for a new GitHub repository. There is also a handy workflow that will create an issue on a new repository made from this template, with a checklist for the steps we usually take in setting up a new repository.
If you're starting a Node.JS project with TypeScript, we have a [specific template](https://github.com/naomi-lgbt/nodejs-typescript-template) for that purpose.
## Readme
Delete all of the above text (including this line), and uncomment the below text to use our standard readme template.
<!-- # Project Name
Project Description
A web app that contains the lore for Naomi's fictional persona and characters.
## Live Version
This page is currently deployed. [View the live website.]
This page is currently deployed. [View the live website.](https://lore.nhcarrigan.com)
## Feedback and Bugs
@@ -36,4 +26,4 @@ Copyright held by Naomi Carrigan.
## Contact
We may be contacted through our [Chat Server](http://chat.nhcarrigan.com) or via email at `contact@nhcarrigan.com`. -->
We may be contacted through our [Chat Server](http://chat.nhcarrigan.com) or via email at `contact@nhcarrigan.com`.
+73
View File
@@ -0,0 +1,73 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"cli": {
"packageManager": "npm"
},
"newProjectRoot": "projects",
"projects": {
"lore": {
"projectType": "application",
"schematics": {},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular/build:application",
"options": {
"browser": "src/main.ts",
"tsConfig": "tsconfig.app.json",
"assets": [
{
"glob": "**/*",
"input": "public"
}
],
"styles": [
"src/styles.css"
]
},
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "500kB",
"maximumError": "1MB"
},
{
"type": "anyComponentStyle",
"maximumWarning": "4kB",
"maximumError": "8kB"
}
],
"outputHashing": "all"
},
"development": {
"optimization": false,
"extractLicenses": false,
"sourceMap": true
}
},
"defaultConfiguration": "production"
},
"serve": {
"builder": "@angular/build:dev-server",
"configurations": {
"production": {
"buildTarget": "lore:build:production"
},
"development": {
"buildTarget": "lore:build:development"
}
},
"defaultConfiguration": "development"
},
"test": {
"builder": "@angular/build:unit-test"
}
}
}
}
}
+51
View File
@@ -0,0 +1,51 @@
import NaomisConfig from "@nhcarrigan/eslint-config";
const srcRules = NaomisConfig.find((rule) => rule.files?.includes("src/**/*.ts"));
const testRules = NaomisConfig.find((rule) => rule.files?.includes("test/**/*.spec.ts"));
export default [
...NaomisConfig,
{
files: ["src/**/*.ts"],
languageOptions: {
parserOptions: {
project: "./tsconfig.app.json"
}
},
plugins: {
...srcRules?.plugins,
},
rules: {
...srcRules?.rules,
"new-cap": "off",
// This causes a circular fix error?
"stylistic/no-multi-spaces": "off",
// This must be off because this is not a module.
"import/extensions": [ "error", "never" ],
// This is a web app
"no-console": "off",
// Sometimes a component class will be empty. Not all components require logic.
"@typescript-eslint/no-extraneous-class": "off",
}
},
{
files: ["src/**/*.spec.ts"],
languageOptions: {
parserOptions: {
project: "./tsconfig.spec.json"
}
},
plugins: {
...testRules?.plugins,
},
rules: {
...testRules?.rules,
// This must be off because this is not a module.
"import/extensions": "off",
// We turn this off because the test bed has weak types.
"@typescript-eslint/consistent-type-assertions": "off",
// This one allows us to define test globals.
"@typescript-eslint/init-declarations": "off",
}
}
]
+49
View File
@@ -0,0 +1,49 @@
{
"name": "lore",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test",
"lint": "eslint src --max-warnings 0"
},
"prettier": {
"printWidth": 100,
"singleQuote": true,
"overrides": [
{
"files": "*.html",
"options": {
"parser": "angular"
}
}
]
},
"private": true,
"packageManager": "pnpm@10.0.0",
"dependencies": {
"@angular/common": "21.0.6",
"@angular/compiler": "21.0.6",
"@angular/core": "21.0.6",
"@angular/forms": "21.0.6",
"@angular/platform-browser": "21.0.6",
"@angular/router": "21.0.6",
"rxjs": "7.8.2",
"tslib": "2.8.1"
},
"devDependencies": {
"@angular/build": "21.0.4",
"@angular/cli": "21.0.4",
"@angular/compiler-cli": "21.0.6",
"@nhcarrigan/eslint-config": "5.2.0",
"@tailwindcss/postcss": "4.1.18",
"eslint": "9.39.2",
"jsdom": "27.4.0",
"postcss": "8.5.6",
"tailwindcss": "4.1.18",
"typescript": "5.9.3",
"vitest": "4.0.16"
}
}
+8889
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File
+1
View File
@@ -0,0 +1 @@
<p>about works!</p>
+29
View File
@@ -0,0 +1,29 @@
/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { type ComponentFixture, TestBed } from "@angular/core/testing";
import { describe, beforeEach, it, expect } from "vitest";
import { About } from "./about";
describe("about", () => {
let component: About;
let fixture: ComponentFixture<About>;
beforeEach(async() => {
await TestBed.configureTestingModule({
imports: [ About ],
}).
compileComponents();
fixture = TestBed.createComponent(About);
component = fixture.componentInstance;
await fixture.whenStable();
});
it("should create", () => {
expect.assertions(1);
expect(component, "did not compile").toBeTruthy();
});
});
+19
View File
@@ -0,0 +1,19 @@
/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { Component } from "@angular/core";
/**
* Renders the about page.
*/
@Component({
imports: [],
selector: "app-about",
styleUrl: "./about.css",
templateUrl: "./about.html",
})
export class About {
}
+16
View File
@@ -0,0 +1,16 @@
/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import {
type ApplicationConfig,
provideBrowserGlobalErrorListeners,
} from "@angular/core";
import { provideRouter } from "@angular/router";
// eslint-disable-next-line import/extensions -- This is not a file extension.
import { routes } from "./app.routes";
export const appConfig: ApplicationConfig = {
providers: [ provideBrowserGlobalErrorListeners(), provideRouter(routes) ],
};
View File
+6
View File
@@ -0,0 +1,6 @@
<app-nav></app-nav>
<app-disclaimer></app-disclaimer>
<main>
<router-outlet></router-outlet>
</main>
<app-footer></app-footer>
+23
View File
@@ -0,0 +1,23 @@
/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { About } from "./about/about";
import { Bulletin } from "./bulletin/bulletin";
import { Faq } from "./faq/faq";
import { Handbook } from "./handbook/handbook";
import { Home } from "./home/home";
import { Reviews } from "./reviews/reviews";
import { Staff } from "./staff/staff";
import type { Routes } from "@angular/router";
export const routes: Routes = [
{ component: Home, path: "", pathMatch: "full" },
{ component: Handbook, path: "handbook" },
{ component: About, path: "about" },
{ component: Bulletin, path: "bulletin" },
{ component: Faq, path: "faq" },
{ component: Reviews, path: "reviews" },
{ component: Staff, path: "staff" },
];
+36
View File
@@ -0,0 +1,36 @@
/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { TestBed } from "@angular/core/testing";
import { describe, beforeEach, it, expect } from "vitest";
import { App } from "./app";
describe("app", () => {
beforeEach(async() => {
await TestBed.configureTestingModule({
imports: [ App ],
}).compileComponents();
});
it("should create the app", () => {
expect.assertions(1);
const fixture = TestBed.createComponent(App);
const app = fixture.componentInstance;
expect(app, "did not compile").toBeTruthy();
});
it("should render title", async() => {
expect.assertions(1);
const fixture = TestBed.createComponent(App);
await fixture.whenStable();
const compiled = fixture.nativeElement as HTMLElement;
expect(
compiled.querySelector("h1")?.textContent,
"did not render title",
).toContain(
"Hello, lore",
);
});
});
+23
View File
@@ -0,0 +1,23 @@
/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { Component, signal } from "@angular/core";
import { RouterOutlet } from "@angular/router";
import { Disclaimer } from "./disclaimer/disclaimer";
import { Footer } from "./footer/footer";
import { Nav } from "./nav/nav";
/**
* The root component for the application.
*/
@Component({
imports: [ RouterOutlet, Footer, Nav, Disclaimer ],
selector: "app-root",
styleUrl: "./app.css",
templateUrl: "./app.html",
})
export class App {
protected readonly title = signal("lore");
}
View File
+1
View File
@@ -0,0 +1 @@
<p>bulletin works!</p>
+29
View File
@@ -0,0 +1,29 @@
/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { type ComponentFixture, TestBed } from "@angular/core/testing";
import { describe, beforeEach, it, expect } from "vitest";
import { Bulletin } from "./bulletin";
describe("bulletin", () => {
let component: Bulletin;
let fixture: ComponentFixture<Bulletin>;
beforeEach(async() => {
await TestBed.configureTestingModule({
imports: [ Bulletin ],
}).
compileComponents();
fixture = TestBed.createComponent(Bulletin);
component = fixture.componentInstance;
await fixture.whenStable();
});
it("should create", () => {
expect.assertions(1);
expect(component, "did not compile").toBeTruthy();
});
});
+19
View File
@@ -0,0 +1,19 @@
/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { Component } from "@angular/core";
/**
* Renders the bulletin page.
*/
@Component({
imports: [],
selector: "app-bulletin",
styleUrl: "./bulletin.css",
templateUrl: "./bulletin.html",
})
export class Bulletin {
}
+6
View File
@@ -0,0 +1,6 @@
#modal {
background-color: var(--color-background);
border-radius: 10px;
border: 2px solid var(--color-accent);
color: var(--color-primary);
}
+21
View File
@@ -0,0 +1,21 @@
@if (showModal()) {
<div class="fixed top-0 left-0 w-full h-full flex items-center justify-center text-center z-50">
<div id="modal" class="p-5">
<aside>
<h1 class="text-2xl font-bold">Disclaimer</h1>
<p>This website incorporates AI-generated art. Before you proceed, we wanted to make very clear:</p>
<ul class="list-disc list-inside text-left">
<li>Our company do not support the use of AI to replace human artists.</li>
<li>Our company are aware of the ethical conerns around generative AI and how training data are sourced.</li>
<li>We have a long history of supporting and promoting human artists, and have no intention of changing that.</li>
<li>However, because we currently operate at a significant loss, our budget is very limited.</li>
<li>When funds allow, we absolutely intend to replace all art on this page with human works.</li>
</ul>
<p>If you are an artist and would like to donate art, or if you have cash and would like to donate to our cause, check our <a href="https://donate.nhcarrigan.com" target="_blank">donation page</a>.</p>
<p>Thank you for understanding. Please confirm you understand our stance, and that you will not start flaming us for just trying to survive.</p>
</aside>
<button (click)="closeModal()" class="mt-5 border-r-4 border-b-4 border-l-4 border-t-2 border-accent rounded-md p-2 cursor-pointer">I understand, and I will not attack you for trying to survive.</button>
</div>
</div>
<div id="modal-overlay" class="fixed top-0 left-0 w-full h-full bg-black/75 z-40"></div>
}
+29
View File
@@ -0,0 +1,29 @@
/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { type ComponentFixture, TestBed } from "@angular/core/testing";
import { describe, beforeEach, it, expect } from "vitest";
import { Disclaimer } from "./disclaimer";
describe("disclaimer", () => {
let component: Disclaimer;
let fixture: ComponentFixture<Disclaimer>;
beforeEach(async() => {
await TestBed.configureTestingModule({
imports: [ Disclaimer ],
}).
compileComponents();
fixture = TestBed.createComponent(Disclaimer);
component = fixture.componentInstance;
await fixture.whenStable();
});
it("should create", () => {
expect.assertions(1);
expect(component, "did not compile").toBeTruthy();
});
});
+26
View File
@@ -0,0 +1,26 @@
/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { Component, signal } from "@angular/core";
/**
* Renders the disclaimer page.
*/
@Component({
imports: [],
selector: "app-disclaimer",
styleUrl: "./disclaimer.css",
templateUrl: "./disclaimer.html",
})
export class Disclaimer {
protected readonly showModal = signal<boolean>(true);
/**
* Closes the modal, should remain closed until the page is refreshed.
*/
public closeModal(): void {
this.showModal.set(false);
}
}
View File
+1
View File
@@ -0,0 +1 @@
<p>faq works!</p>
+29
View File
@@ -0,0 +1,29 @@
/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { type ComponentFixture, TestBed } from "@angular/core/testing";
import { describe, beforeEach, it, expect } from "vitest";
import { Faq } from "./faq";
describe("faq", () => {
let component: Faq;
let fixture: ComponentFixture<Faq>;
beforeEach(async() => {
await TestBed.configureTestingModule({
imports: [ Faq ],
}).
compileComponents();
fixture = TestBed.createComponent(Faq);
component = fixture.componentInstance;
await fixture.whenStable();
});
it("should create", () => {
expect.assertions(1);
expect(component, "did not compile").toBeTruthy();
});
});
+19
View File
@@ -0,0 +1,19 @@
/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { Component } from "@angular/core";
/**
* Renders the FAQ page.
*/
@Component({
imports: [],
selector: "app-faq",
styleUrl: "./faq.css",
templateUrl: "./faq.html",
})
export class Faq {
}
View File
+1
View File
@@ -0,0 +1 @@
<p>footer works!</p>
+29
View File
@@ -0,0 +1,29 @@
/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { type ComponentFixture, TestBed } from "@angular/core/testing";
import { describe, beforeEach, it, expect } from "vitest";
import { Footer } from "./footer";
describe("footer", () => {
let component: Footer;
let fixture: ComponentFixture<Footer>;
beforeEach(async() => {
await TestBed.configureTestingModule({
imports: [ Footer ],
}).
compileComponents();
fixture = TestBed.createComponent(Footer);
component = fixture.componentInstance;
await fixture.whenStable();
});
it("should create", () => {
expect.assertions(1);
expect(component, "did not compile").toBeTruthy();
});
});
+19
View File
@@ -0,0 +1,19 @@
/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { Component } from "@angular/core";
/**
* Renders the footer.
*/
@Component({
imports: [],
selector: "app-footer",
styleUrl: "./footer.css",
templateUrl: "./footer.html",
})
export class Footer {
}
View File
+1
View File
@@ -0,0 +1 @@
<p>handbook works!</p>
+29
View File
@@ -0,0 +1,29 @@
/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { type ComponentFixture, TestBed } from "@angular/core/testing";
import { describe, beforeEach, it, expect } from "vitest";
import { Handbook } from "./handbook";
describe("handbook", () => {
let component: Handbook;
let fixture: ComponentFixture<Handbook>;
beforeEach(async() => {
await TestBed.configureTestingModule({
imports: [ Handbook ],
}).
compileComponents();
fixture = TestBed.createComponent(Handbook);
component = fixture.componentInstance;
await fixture.whenStable();
});
it("should create", () => {
expect.assertions(1);
expect(component, "did not compile").toBeTruthy();
});
});
+19
View File
@@ -0,0 +1,19 @@
/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { Component } from "@angular/core";
/**
* Renders the handbook page.
*/
@Component({
imports: [],
selector: "app-handbook",
styleUrl: "./handbook.css",
templateUrl: "./handbook.html",
})
export class Handbook {
}
View File
+1
View File
@@ -0,0 +1 @@
<p>home works!</p>
+29
View File
@@ -0,0 +1,29 @@
/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { type ComponentFixture, TestBed } from "@angular/core/testing";
import { describe, beforeEach, it, expect } from "vitest";
import { Home } from "./home";
describe("home", () => {
let component: Home;
let fixture: ComponentFixture<Home>;
beforeEach(async() => {
await TestBed.configureTestingModule({
imports: [ Home ],
}).
compileComponents();
fixture = TestBed.createComponent(Home);
component = fixture.componentInstance;
await fixture.whenStable();
});
it("should create", () => {
expect.assertions(1);
expect(component, "did not compile").toBeTruthy();
});
});
+19
View File
@@ -0,0 +1,19 @@
/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { Component } from "@angular/core";
/**
* Renders the home page.
*/
@Component({
imports: [],
selector: "app-home",
styleUrl: "./home.css",
templateUrl: "./home.html",
})
export class Home {
}
View File
+1
View File
@@ -0,0 +1 @@
<p>nav works!</p>
+29
View File
@@ -0,0 +1,29 @@
/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { type ComponentFixture, TestBed } from "@angular/core/testing";
import { describe, beforeEach, it, expect } from "vitest";
import { Nav } from "./nav";
describe("nav", () => {
let component: Nav;
let fixture: ComponentFixture<Nav>;
beforeEach(async() => {
await TestBed.configureTestingModule({
imports: [ Nav ],
}).
compileComponents();
fixture = TestBed.createComponent(Nav);
component = fixture.componentInstance;
await fixture.whenStable();
});
it("should create", () => {
expect.assertions(1);
expect(component, "did not compile").toBeTruthy();
});
});
+19
View File
@@ -0,0 +1,19 @@
/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { Component } from "@angular/core";
/**
* Renders the navigation bar.
*/
@Component({
imports: [],
selector: "app-nav",
styleUrl: "./nav.css",
templateUrl: "./nav.html",
})
export class Nav {
}
View File
+1
View File
@@ -0,0 +1 @@
<p>reviews works!</p>
+29
View File
@@ -0,0 +1,29 @@
/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { type ComponentFixture, TestBed } from "@angular/core/testing";
import { describe, beforeEach, it, expect } from "vitest";
import { Reviews } from "./reviews";
describe("reviews", () => {
let component: Reviews;
let fixture: ComponentFixture<Reviews>;
beforeEach(async() => {
await TestBed.configureTestingModule({
imports: [ Reviews ],
}).
compileComponents();
fixture = TestBed.createComponent(Reviews);
component = fixture.componentInstance;
await fixture.whenStable();
});
it("should create", () => {
expect.assertions(1);
expect(component, "did not compile").toBeTruthy();
});
});
+19
View File
@@ -0,0 +1,19 @@
/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { Component } from "@angular/core";
/**
* Renders the reviews page.
*/
@Component({
imports: [],
selector: "app-reviews",
styleUrl: "./reviews.css",
templateUrl: "./reviews.html",
})
export class Reviews {
}
View File
+1
View File
@@ -0,0 +1 @@
<p>staff works!</p>
+29
View File
@@ -0,0 +1,29 @@
/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { type ComponentFixture, TestBed } from "@angular/core/testing";
import { describe, beforeEach, it, expect } from "vitest";
import { Staff } from "./staff";
describe("staff", () => {
let component: Staff;
let fixture: ComponentFixture<Staff>;
beforeEach(async() => {
await TestBed.configureTestingModule({
imports: [ Staff ],
}).
compileComponents();
fixture = TestBed.createComponent(Staff);
component = fixture.componentInstance;
await fixture.whenStable();
});
it("should create", () => {
expect.assertions(1);
expect(component, "did not compile").toBeTruthy();
});
});
+19
View File
@@ -0,0 +1,19 @@
/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { Component } from "@angular/core";
/**
* Renders the staff page.
*/
@Component({
imports: [],
selector: "app-staff",
styleUrl: "./staff.css",
templateUrl: "./staff.html",
})
export class Staff {
}
View File
+1
View File
@@ -0,0 +1 @@
<p>ticker works!</p>
+29
View File
@@ -0,0 +1,29 @@
/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { type ComponentFixture, TestBed } from "@angular/core/testing";
import { describe, beforeEach, it, expect } from "vitest";
import { Ticker } from "./ticker";
describe("ticker", () => {
let component: Ticker;
let fixture: ComponentFixture<Ticker>;
beforeEach(async() => {
await TestBed.configureTestingModule({
imports: [ Ticker ],
}).
compileComponents();
fixture = TestBed.createComponent(Ticker);
component = fixture.componentInstance;
await fixture.whenStable();
});
it("should create", () => {
expect.assertions(1);
expect(component, "did not compile").toBeTruthy();
});
});
+19
View File
@@ -0,0 +1,19 @@
/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { Component } from "@angular/core";
/**
* Renders the ticker.
*/
@Component({
imports: [],
selector: "app-ticker",
styleUrl: "./ticker.css",
templateUrl: "./ticker.html",
})
export class Ticker {
}
+11
View File
@@ -0,0 +1,11 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Lore</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<app-root></app-root>
</html>
+15
View File
@@ -0,0 +1,15 @@
/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { bootstrapApplication } from "@angular/platform-browser";
import { App } from "./app/app";
// eslint-disable-next-line import/extensions -- This is not a file extension.
import { appConfig } from "./app/app.config";
bootstrapApplication(App, appConfig).
// eslint-disable-next-line unicorn/prefer-top-level-await -- No top level await in a web app
catch((error: unknown) => {
console.error(error);
});
+57
View File
@@ -0,0 +1,57 @@
/* You can add global styles to this file, and also import other style files */
@import "tailwindcss";
:root {
--color-primary: #e0e0e0;
--color-secondary: #121212;
--color-accent: #00ff9d;
--color-ticker: #8a0000;
--color-background: #12121288;
}
body::before {
background: url(https://cdn.nhcarrigan.com/lore/misc/background.png);
background-size: cover;
background-position: center;
width: 100%;
height: 100%;
z-index: -1;
content: "";
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
opacity: 1;
pointer-events: none;
}
main {
max-width: 800px;
width: 95%;
margin: 0 auto;
background-color: var(--color-background);
color: var(--color-primary);
}
a {
color: var(--color-accent);
text-decoration: underline;
font-weight: bold;
transition: color 0.3s ease;
}
a:hover {
color: var(--color-primary);
}
button {
background-color: var(--color-accent);
color: var(--color-secondary);
transition: background-color 0.3s ease;
}
button:hover {
background-color: var(--color-primary);
}
+15
View File
@@ -0,0 +1,15 @@
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/app",
"types": []
},
"include": [
"src/**/*.ts"
],
"exclude": [
"src/**/*.spec.ts"
]
}
+33
View File
@@ -0,0 +1,33 @@
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
{
"compileOnSave": false,
"compilerOptions": {
"strict": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"skipLibCheck": true,
"isolatedModules": true,
"experimentalDecorators": true,
"importHelpers": true,
"target": "ES2022",
"module": "preserve"
},
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"strictTemplates": true
},
"files": [],
"references": [
{
"path": "./tsconfig.app.json"
},
{
"path": "./tsconfig.spec.json"
}
]
}
+15
View File
@@ -0,0 +1,15 @@
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/spec",
"types": [
"vitest/globals"
],
},
"include": [
"src/**/*.d.ts",
"src/**/*.spec.ts"
]
}