diff --git a/apps/NwaifuAnime/.eslintrc.json b/apps/NwaifuAnime/.eslintrc.json
new file mode 100644
index 0000000..437641b
--- /dev/null
+++ b/apps/NwaifuAnime/.eslintrc.json
@@ -0,0 +1,33 @@
+{
+ "extends": ["../../.eslintrc.json"],
+ "ignorePatterns": ["!**/*"],
+ "overrides": [
+ {
+ "files": ["*.ts"],
+ "extends": ["plugin:@nx/angular", "plugin:@angular-eslint/template/process-inline-templates"],
+ "rules": {
+ "@angular-eslint/directive-selector": [
+ "error",
+ {
+ "type": "attribute",
+ "prefix": "app",
+ "style": "camelCase"
+ }
+ ],
+ "@angular-eslint/component-selector": [
+ "error",
+ {
+ "type": "element",
+ "prefix": "app",
+ "style": "kebab-case"
+ }
+ ]
+ }
+ },
+ {
+ "files": ["*.html"],
+ "extends": ["plugin:@nx/angular-template"],
+ "rules": {}
+ }
+ ]
+}
diff --git a/apps/NwaifuAnime/ngsw-config.json b/apps/NwaifuAnime/ngsw-config.json
new file mode 100644
index 0000000..422d480
--- /dev/null
+++ b/apps/NwaifuAnime/ngsw-config.json
@@ -0,0 +1,29 @@
+{
+ "$schema": "../../node_modules/@angular/service-worker/config/schema.json",
+ "index": "/index.html",
+ "assetGroups": [
+ {
+ "name": "app",
+ "installMode": "prefetch",
+ "resources": {
+ "files": [
+ "/favicon.ico",
+ "/index.html",
+ "/manifest.webmanifest",
+ "/*.css",
+ "/*.js"
+ ]
+ }
+ },
+ {
+ "name": "assets",
+ "installMode": "lazy",
+ "updateMode": "prefetch",
+ "resources": {
+ "files": [
+ "/**/*.(svg|cur|jpg|jpeg|png|apng|webp|avif|gif|otf|ttf|woff|woff2)"
+ ]
+ }
+ }
+ ]
+}
diff --git a/apps/NwaifuAnime/project.json b/apps/NwaifuAnime/project.json
new file mode 100644
index 0000000..8fc4abd
--- /dev/null
+++ b/apps/NwaifuAnime/project.json
@@ -0,0 +1,75 @@
+{
+ "name": "NwaifuAnime",
+ "$schema": "../../node_modules/nx/schemas/project-schema.json",
+ "projectType": "application",
+ "prefix": "app",
+ "sourceRoot": "apps/NwaifuAnime/src",
+ "tags": [],
+ "targets": {
+ "build": {
+ "executor": "@angular-devkit/build-angular:application",
+ "outputs": ["{options.outputPath}"],
+ "options": {
+ "outputPath": "dist/apps/NwaifuAnime",
+ "index": "apps/NwaifuAnime/src/index.html",
+ "browser": "apps/NwaifuAnime/src/main.ts",
+ "polyfills": ["zone.js"],
+ "tsConfig": "apps/NwaifuAnime/tsconfig.app.json",
+ "inlineStyleLanguage": "less",
+ "assets": [
+ {
+ "glob": "**/*",
+ "input": "apps/NwaifuAnime/public"
+ }
+ ],
+ "styles": ["apps/NwaifuAnime/src/styles.less"],
+ "scripts": []
+ },
+ "configurations": {
+ "production": {
+ "budgets": [
+ {
+ "type": "initial",
+ "maximumWarning": "500kb",
+ "maximumError": "1mb"
+ },
+ {
+ "type": "anyComponentStyle",
+ "maximumWarning": "2kb",
+ "maximumError": "4kb"
+ }
+ ],
+ "outputHashing": "all",
+ "serviceWorker": "apps/NwaifuAnime/ngsw-config.json"
+ },
+ "development": {
+ "optimization": false,
+ "extractLicenses": false,
+ "sourceMap": true
+ }
+ },
+ "defaultConfiguration": "production"
+ },
+ "serve": {
+ "executor": "@angular-devkit/build-angular:dev-server",
+ "configurations": {
+ "production": {
+ "buildTarget": "NwaifuAnime:build:production"
+ },
+ "development": {
+ "buildTarget": "NwaifuAnime:build:development"
+ }
+ },
+ "defaultConfiguration": "development"
+ },
+ "extract-i18n": {
+ "executor": "@angular-devkit/build-angular:extract-i18n",
+ "options": {
+ "buildTarget": "NwaifuAnime:build"
+ }
+ },
+ "lint": {
+ "executor": "@nx/eslint:lint"
+ }
+ }
+}
diff --git a/apps/NwaifuAnime/public/favicon.ico b/apps/NwaifuAnime/public/favicon.ico
new file mode 100644
index 0000000..317ebcb
Binary files /dev/null and b/apps/NwaifuAnime/public/favicon.ico differ
diff --git a/apps/NwaifuAnime/public/icons/icon-128x128.png b/apps/NwaifuAnime/public/icons/icon-128x128.png
new file mode 100644
index 0000000..5a9a2cc
Binary files /dev/null and b/apps/NwaifuAnime/public/icons/icon-128x128.png differ
diff --git a/apps/NwaifuAnime/public/icons/icon-144x144.png b/apps/NwaifuAnime/public/icons/icon-144x144.png
new file mode 100644
index 0000000..11702cd
Binary files /dev/null and b/apps/NwaifuAnime/public/icons/icon-144x144.png differ
diff --git a/apps/NwaifuAnime/public/icons/icon-152x152.png b/apps/NwaifuAnime/public/icons/icon-152x152.png
new file mode 100644
index 0000000..ff4e06b
Binary files /dev/null and b/apps/NwaifuAnime/public/icons/icon-152x152.png differ
diff --git a/apps/NwaifuAnime/public/icons/icon-192x192.png b/apps/NwaifuAnime/public/icons/icon-192x192.png
new file mode 100644
index 0000000..afd36a4
Binary files /dev/null and b/apps/NwaifuAnime/public/icons/icon-192x192.png differ
diff --git a/apps/NwaifuAnime/public/icons/icon-384x384.png b/apps/NwaifuAnime/public/icons/icon-384x384.png
new file mode 100644
index 0000000..613ac79
Binary files /dev/null and b/apps/NwaifuAnime/public/icons/icon-384x384.png differ
diff --git a/apps/NwaifuAnime/public/icons/icon-512x512.png b/apps/NwaifuAnime/public/icons/icon-512x512.png
new file mode 100644
index 0000000..7574990
Binary files /dev/null and b/apps/NwaifuAnime/public/icons/icon-512x512.png differ
diff --git a/apps/NwaifuAnime/public/icons/icon-72x72.png b/apps/NwaifuAnime/public/icons/icon-72x72.png
new file mode 100644
index 0000000..033724e
Binary files /dev/null and b/apps/NwaifuAnime/public/icons/icon-72x72.png differ
diff --git a/apps/NwaifuAnime/public/icons/icon-96x96.png b/apps/NwaifuAnime/public/icons/icon-96x96.png
new file mode 100644
index 0000000..3090dc2
Binary files /dev/null and b/apps/NwaifuAnime/public/icons/icon-96x96.png differ
diff --git a/apps/NwaifuAnime/public/manifest.webmanifest b/apps/NwaifuAnime/public/manifest.webmanifest
new file mode 100644
index 0000000..1258736
--- /dev/null
+++ b/apps/NwaifuAnime/public/manifest.webmanifest
@@ -0,0 +1,59 @@
+{
+ "name": "NwaifuAnime",
+ "short_name": "NwaifuAnime",
+ "theme_color": "#1976d2",
+ "background_color": "#fafafa",
+ "display": "standalone",
+ "scope": "./",
+ "start_url": "./",
+ "icons": [
+ {
+ "src": "icons/icon-72x72.png",
+ "sizes": "72x72",
+ "type": "image/png",
+ "purpose": "maskable any"
+ },
+ {
+ "src": "icons/icon-96x96.png",
+ "sizes": "96x96",
+ "type": "image/png",
+ "purpose": "maskable any"
+ },
+ {
+ "src": "icons/icon-128x128.png",
+ "sizes": "128x128",
+ "type": "image/png",
+ "purpose": "maskable any"
+ },
+ {
+ "src": "icons/icon-144x144.png",
+ "sizes": "144x144",
+ "type": "image/png",
+ "purpose": "maskable any"
+ },
+ {
+ "src": "icons/icon-152x152.png",
+ "sizes": "152x152",
+ "type": "image/png",
+ "purpose": "maskable any"
+ },
+ {
+ "src": "icons/icon-192x192.png",
+ "sizes": "192x192",
+ "type": "image/png",
+ "purpose": "maskable any"
+ },
+ {
+ "src": "icons/icon-384x384.png",
+ "sizes": "384x384",
+ "type": "image/png",
+ "purpose": "maskable any"
+ },
+ {
+ "src": "icons/icon-512x512.png",
+ "sizes": "512x512",
+ "type": "image/png",
+ "purpose": "maskable any"
+ }
+ ]
+}
diff --git a/apps/NwaifuAnime/src/app/app.component.html b/apps/NwaifuAnime/src/app/app.component.html
new file mode 100644
index 0000000..e419ca1
--- /dev/null
+++ b/apps/NwaifuAnime/src/app/app.component.html
@@ -0,0 +1,11 @@
+@if (serviceWorkerEnabled) {
+ @if (hasUpdate) {
+
Update available
+
+ } @else {
+ Update not available
+ }
+}
+
+
+
diff --git a/apps/NwaifuAnime/src/app/app.component.less b/apps/NwaifuAnime/src/app/app.component.less
new file mode 100644
index 0000000..e69de29
diff --git a/apps/NwaifuAnime/src/app/app.component.ts b/apps/NwaifuAnime/src/app/app.component.ts
new file mode 100644
index 0000000..e8c9471
--- /dev/null
+++ b/apps/NwaifuAnime/src/app/app.component.ts
@@ -0,0 +1,33 @@
+import { Component } from "@angular/core";
+import { RouterModule } from "@angular/router";
+import { AppService } from "./app.service";
+import { HeaderComponent } from "./components/header/header.component";
+
+@Component({
+ standalone: true,
+ imports: [RouterModule, HeaderComponent],
+ selector: "app-root",
+ templateUrl: "./app.component.html",
+ styleUrl: "./app.component.less",
+ providers: [AppService],
+})
+export class AppComponent {
+ title = "NwaifuAnime";
+ constructor(private sw: AppService) {}
+
+ get hasUpdate() {
+ return this.sw.isUpdateAvailable;
+ }
+
+ update() {
+ this.sw.update();
+ }
+
+ get serviceWorkerEnabled() {
+ return this.sw.serviceWorkerEnabled;
+ }
+
+ onSearch(text: string) {
+ console.log(text);
+ }
+}
diff --git a/apps/NwaifuAnime/src/app/app.config.ts b/apps/NwaifuAnime/src/app/app.config.ts
new file mode 100644
index 0000000..f7d7b52
--- /dev/null
+++ b/apps/NwaifuAnime/src/app/app.config.ts
@@ -0,0 +1,11 @@
+import { ApplicationConfig, provideZoneChangeDetection, isDevMode } from "@angular/core";
+import { provideRouter } from "@angular/router";
+import { appRoutes } from "./app.routes";
+import { provideServiceWorker } from '@angular/service-worker';
+
+export const appConfig: ApplicationConfig = {
+ providers: [provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(appRoutes), provideServiceWorker('ngsw-worker.js', {
+ enabled: !isDevMode(),
+ registrationStrategy: 'registerWhenStable:30000'
+ })],
+};
diff --git a/apps/NwaifuAnime/src/app/app.routes.ts b/apps/NwaifuAnime/src/app/app.routes.ts
new file mode 100644
index 0000000..814f55a
--- /dev/null
+++ b/apps/NwaifuAnime/src/app/app.routes.ts
@@ -0,0 +1,9 @@
+import { Route } from "@angular/router";
+import { HomeComponent } from "./components/home/home.component";
+
+export const appRoutes: Route[] = [
+ {
+ path: "",
+ component: HomeComponent,
+ },
+];
diff --git a/apps/NwaifuAnime/src/app/app.service.ts b/apps/NwaifuAnime/src/app/app.service.ts
new file mode 100644
index 0000000..c855ee1
--- /dev/null
+++ b/apps/NwaifuAnime/src/app/app.service.ts
@@ -0,0 +1,40 @@
+import { Injectable } from "@angular/core";
+import { SwUpdate } from "@angular/service-worker";
+
+@Injectable({ providedIn: "root" })
+export class AppService {
+ private hasUpdate = false;
+ constructor(private sw: SwUpdate) {
+ if (this.sw.isEnabled) {
+ console.log("service init");
+ this.sw.checkForUpdate();
+
+ this.sw.versionUpdates.subscribe((ev) => {
+ if (ev.type == "VERSION_DETECTED") {
+ console.log("update detected");
+ this.hasUpdate = true;
+ } else {
+ console.log("no update");
+ }
+ });
+ }
+ }
+
+ get isUpdateAvailable() {
+ return this.hasUpdate;
+ }
+
+ get serviceWorkerEnabled() {
+ return this.sw.isEnabled;
+ }
+
+ update() {
+ this.sw.activateUpdate().then((res) => {
+ if (res) {
+ console.log("updated");
+ this.hasUpdate = false;
+ window.location.reload();
+ }
+ });
+ }
+}
diff --git a/apps/NwaifuAnime/src/app/components/header/header.component.html b/apps/NwaifuAnime/src/app/components/header/header.component.html
new file mode 100644
index 0000000..b81e4c6
--- /dev/null
+++ b/apps/NwaifuAnime/src/app/components/header/header.component.html
@@ -0,0 +1,23 @@
+
diff --git a/apps/NwaifuAnime/src/app/components/header/header.component.less b/apps/NwaifuAnime/src/app/components/header/header.component.less
new file mode 100644
index 0000000..ba4612c
--- /dev/null
+++ b/apps/NwaifuAnime/src/app/components/header/header.component.less
@@ -0,0 +1,3 @@
+.header {
+ transition: height 0.3s;
+}
diff --git a/apps/NwaifuAnime/src/app/components/header/header.component.ts b/apps/NwaifuAnime/src/app/components/header/header.component.ts
new file mode 100644
index 0000000..feb5ad5
--- /dev/null
+++ b/apps/NwaifuAnime/src/app/components/header/header.component.ts
@@ -0,0 +1,33 @@
+import { CommonModule } from "@angular/common";
+import { Component, ElementRef, EventEmitter, Output, ViewChild } from "@angular/core";
+
+@Component({
+ selector: "app-header",
+ templateUrl: "./header.component.html",
+ styleUrls: ["./header.component.less"],
+ standalone: true,
+ imports: [CommonModule],
+})
+export class HeaderComponent {
+ @Output() searchEvent: EventEmitter = new EventEmitter();
+ @ViewChild("searchInput") searchInput: ElementRef | null = null;
+ menuOpened = false;
+ changeMenu() {
+ this.menuOpened = !this.menuOpened;
+ }
+
+ get menuBtnClass(): string {
+ return `lni ${this.menuOpened ? "lni-close" : "lni-menu"} text-white`;
+ }
+
+ get searchBarClass(): string {
+ return `search-bar bg-slate-300 md:w-[50%] w-full md:m-0 ms-2 me-2 max-h-6 md:flex justify-start flex-row items-center rounded-md ${this.menuOpened ? "flex" : "hidden"}`;
+ }
+
+ search() {
+ if (this.searchInput) {
+ const text = this.searchInput.nativeElement.value;
+ this.searchEvent.emit(text);
+ }
+ }
+}
diff --git a/apps/NwaifuAnime/src/app/components/home/home.component.html b/apps/NwaifuAnime/src/app/components/home/home.component.html
new file mode 100644
index 0000000..d0c9d2f
--- /dev/null
+++ b/apps/NwaifuAnime/src/app/components/home/home.component.html
@@ -0,0 +1 @@
+It's home component
diff --git a/apps/NwaifuAnime/src/app/components/home/home.component.less b/apps/NwaifuAnime/src/app/components/home/home.component.less
new file mode 100644
index 0000000..e69de29
diff --git a/apps/NwaifuAnime/src/app/components/home/home.component.ts b/apps/NwaifuAnime/src/app/components/home/home.component.ts
new file mode 100644
index 0000000..15aa64b
--- /dev/null
+++ b/apps/NwaifuAnime/src/app/components/home/home.component.ts
@@ -0,0 +1,11 @@
+import { CommonModule } from "@angular/common";
+import { Component } from "@angular/core";
+
+@Component({
+ standalone: true,
+ selector: "app-home",
+ templateUrl: "./home.component.html",
+ styleUrls: ["./home.component.less"],
+ imports: [CommonModule],
+})
+export class HomeComponent {}
diff --git a/apps/NwaifuAnime/src/index.html b/apps/NwaifuAnime/src/index.html
new file mode 100644
index 0000000..d0044c5
--- /dev/null
+++ b/apps/NwaifuAnime/src/index.html
@@ -0,0 +1,17 @@
+
+
+
+
+ NwaifuAnime
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/NwaifuAnime/src/main.ts b/apps/NwaifuAnime/src/main.ts
new file mode 100644
index 0000000..9318a44
--- /dev/null
+++ b/apps/NwaifuAnime/src/main.ts
@@ -0,0 +1,5 @@
+import { bootstrapApplication } from "@angular/platform-browser";
+import { appConfig } from "./app/app.config";
+import { AppComponent } from "./app/app.component";
+
+bootstrapApplication(AppComponent, appConfig).catch((err) => console.error(err));
diff --git a/apps/NwaifuAnime/src/styles.less b/apps/NwaifuAnime/src/styles.less
new file mode 100644
index 0000000..b5c61c9
--- /dev/null
+++ b/apps/NwaifuAnime/src/styles.less
@@ -0,0 +1,3 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
diff --git a/apps/NwaifuAnime/tailwind.config.js b/apps/NwaifuAnime/tailwind.config.js
new file mode 100644
index 0000000..65f2fec
--- /dev/null
+++ b/apps/NwaifuAnime/tailwind.config.js
@@ -0,0 +1,14 @@
+const { createGlobPatternsForDependencies } = require("@nx/angular/tailwind");
+const { join } = require("path");
+
+/** @type {import('tailwindcss').Config} */
+module.exports = {
+ content: [
+ join(__dirname, "src/**/!(*.stories|*.spec).{ts,html}"),
+ ...createGlobPatternsForDependencies(__dirname),
+ ],
+ theme: {
+ extend: {},
+ },
+ plugins: [],
+};
diff --git a/apps/NwaifuAnime/tsconfig.app.json b/apps/NwaifuAnime/tsconfig.app.json
new file mode 100644
index 0000000..fff4a41
--- /dev/null
+++ b/apps/NwaifuAnime/tsconfig.app.json
@@ -0,0 +1,10 @@
+{
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ "outDir": "../../dist/out-tsc",
+ "types": []
+ },
+ "files": ["src/main.ts"],
+ "include": ["src/**/*.d.ts"],
+ "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"]
+}
diff --git a/apps/NwaifuAnime/tsconfig.editor.json b/apps/NwaifuAnime/tsconfig.editor.json
new file mode 100644
index 0000000..a8ac182
--- /dev/null
+++ b/apps/NwaifuAnime/tsconfig.editor.json
@@ -0,0 +1,6 @@
+{
+ "extends": "./tsconfig.json",
+ "include": ["src/**/*.ts"],
+ "compilerOptions": {},
+ "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"]
+}
diff --git a/apps/NwaifuAnime/tsconfig.json b/apps/NwaifuAnime/tsconfig.json
new file mode 100644
index 0000000..cd7f311
--- /dev/null
+++ b/apps/NwaifuAnime/tsconfig.json
@@ -0,0 +1,30 @@
+{
+ "compilerOptions": {
+ "target": "es2022",
+ "useDefineForClassFields": false,
+ "esModuleInterop": true,
+ "forceConsistentCasingInFileNames": true,
+ "strict": true,
+ "noImplicitOverride": true,
+ "noPropertyAccessFromIndexSignature": true,
+ "noImplicitReturns": true,
+ "noFallthroughCasesInSwitch": true
+ },
+ "files": [],
+ "include": [],
+ "references": [
+ {
+ "path": "./tsconfig.editor.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ }
+ ],
+ "extends": "../../tsconfig.base.json",
+ "angularCompilerOptions": {
+ "enableI18nLegacyMessageIdFormat": false,
+ "strictInjectionParameters": true,
+ "strictInputAccessModifiers": true,
+ "strictTemplates": true
+ }
+}
\ No newline at end of file
diff --git a/bun.lockb b/bun.lockb
index 806ccec..8fc81be 100755
Binary files a/bun.lockb and b/bun.lockb differ
diff --git a/package.json b/package.json
index 2483f1b..926802c 100644
--- a/package.json
+++ b/package.json
@@ -19,6 +19,7 @@
"@angular/platform-browser": "18.0.3",
"@angular/platform-browser-dynamic": "18.0.3",
"@angular/router": "18.0.3",
+ "@angular/service-worker": "18.0.3",
"@fortawesome/angular-fontawesome": "0.14.1",
"@fortawesome/fontawesome-svg-core": "^6.4.2",
"@fortawesome/free-brands-svg-icons": "^6.4.2",
diff --git a/tsconfig.base.json b/tsconfig.base.json
index 6b2eacc..d9fb16d 100644
--- a/tsconfig.base.json
+++ b/tsconfig.base.json
@@ -13,9 +13,7 @@
"skipLibCheck": true,
"skipDefaultLibCheck": true,
"paths": {
- "@nwaifu-ui": [
- "nwaifu-ui/src/index.ts"
- ]
+ "@nwaifu-ui": ["nwaifu-ui/src/index.ts"]
},
"baseUrl": ".",
"rootDir": "."