Initial commit

This commit is contained in:
2026-01-09 10:19:18 +01:00
commit 8fcc63e323
25 changed files with 11357 additions and 0 deletions

17
.editorconfig Normal file
View File

@@ -0,0 +1,17 @@
# Editor configuration, see https://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
[*.ts]
quote_type = single
ij_typescript_use_double_quotes = false
[*.md]
max_line_length = off
trim_trailing_whitespace = false

45
.gitignore vendored Normal file
View File

@@ -0,0 +1,45 @@
# 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
.env

4
.vscode/extensions.json vendored Normal file
View File

@@ -0,0 +1,4 @@
{
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846
"recommendations": ["angular.ng-template"]
}

20
.vscode/launch.json vendored Normal file
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"
}
]
}

42
.vscode/tasks.json vendored Normal file
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": "Changes detected"
},
"endsPattern": {
"regexp": "bundle generation (complete|failed)"
}
}
}
},
{
"type": "npm",
"script": "test",
"isBackground": true,
"problemMatcher": {
"owner": "typescript",
"pattern": "$tsc",
"background": {
"activeOnStart": true,
"beginsPattern": {
"regexp": "Changes detected"
},
"endsPattern": {
"regexp": "bundle generation (complete|failed)"
}
}
}
}
]
}

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 Iurii Mednikov <iurii.mednikov@mednikov.dev>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

82
angular.json Normal file
View File

@@ -0,0 +1,82 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"cli": {
"packageManager": "npm"
},
"newProjectRoot": "projects",
"projects": {
"social-app": {
"projectType": "application",
"schematics": {},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "@ngx-env/builder:application",
"options": {
"browser": "src/main.ts",
"tsConfig": "tsconfig.app.json",
"assets": [
{
"glob": "**/*",
"input": "public"
}
],
"styles": [
"src/material-theme.scss",
"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,
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.development.ts"
}
]
}
},
"defaultConfiguration": "production"
},
"serve": {
"builder": "@ngx-env/builder:dev-server",
"configurations": {
"production": {
"buildTarget": "social-app:build:production"
},
"development": {
"buildTarget": "social-app:build:development"
}
},
"defaultConfiguration": "development",
"options": {}
},
"test": {
"builder": "@ngx-env/builder:unit-test",
"options": {}
}
}
}
}
}

10846
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

51
package.json Normal file
View File

@@ -0,0 +1,51 @@
{
"name": "social-app",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test"
},
"prettier": {
"printWidth": 100,
"singleQuote": true,
"overrides": [
{
"files": "*.html",
"options": {
"parser": "angular"
}
}
]
},
"private": true,
"packageManager": "npm@11.7.0",
"dependencies": {
"@angular/cdk": "^21.0.6",
"@angular/common": "^21.0.0",
"@angular/compiler": "^21.0.0",
"@angular/core": "^21.0.0",
"@angular/forms": "^21.0.0",
"@angular/material": "^21.0.6",
"@angular/platform-browser": "^21.0.0",
"@angular/router": "^21.0.0",
"@ngrx/signals": "^21.0.1",
"@ngrx/store": "^21.0.1",
"bulma": "^1.0.4",
"keycloak-angular": "^21.0.0",
"keycloak-js": "^26.2.2",
"rxjs": "~7.8.0",
"tslib": "^2.3.0"
},
"devDependencies": {
"@angular/build": "^21.0.4",
"@angular/cli": "^21.0.4",
"@angular/compiler-cli": "^21.0.0",
"@ngx-env/builder": "^21.0.1",
"jsdom": "^27.1.0",
"typescript": "~5.9.2",
"vitest": "^4.0.8"
}
}

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

50
src/app/app.config.ts Normal file
View File

@@ -0,0 +1,50 @@
import { ApplicationConfig, provideBrowserGlobalErrorListeners } from '@angular/core';
import {provideRouter, withComponentInputBinding} from '@angular/router';
import {provideHttpClient, withInterceptors} from '@angular/common/http';
import { provideStore } from '@ngrx/store';
import {
AutoRefreshTokenService, provideKeycloak, UserActivityService, withAutoRefreshToken,
INCLUDE_BEARER_TOKEN_INTERCEPTOR_CONFIG, IncludeBearerTokenCondition, includeBearerTokenInterceptor,
createInterceptorCondition
} from 'keycloak-angular';
import {environment} from '../environments/environment';
import { routes } from './app.routes';
const devUrlCondition = createInterceptorCondition<IncludeBearerTokenCondition>({
urlPattern: /^(http:\/\/localhost:8000)(\/.*)?$/i,
bearerPrefix: 'Bearer'
});
export const appConfig: ApplicationConfig = {
providers: [
provideKeycloak({
config: {
clientId: environment.keycloakClient,
realm: environment.keycloakRealm,
url: environment.keycloakUrl
},
initOptions: {
onLoad: 'login-required'
},
features: [
withAutoRefreshToken({
onInactivityTimeout: 'login',
sessionTimeout: 60000
})
],
providers: [AutoRefreshTokenService, UserActivityService]
}),
{
provide: INCLUDE_BEARER_TOKEN_INTERCEPTOR_CONFIG,
useValue: [devUrlCondition,]
},
provideBrowserGlobalErrorListeners(),
provideRouter(routes, withComponentInputBinding()),
provideHttpClient(withInterceptors([includeBearerTokenInterceptor])),
provideStore()
]
};

0
src/app/app.css Normal file
View File

5
src/app/app.html Normal file
View File

@@ -0,0 +1,5 @@
<div class="section">
<div class="container">
<router-outlet />
</div>
</div>

3
src/app/app.routes.ts Normal file
View File

@@ -0,0 +1,3 @@
import { Routes } from '@angular/router';
export const routes: Routes = [];

11
src/app/app.ts Normal file
View File

@@ -0,0 +1,11 @@
import { Component, signal } from '@angular/core';
import { RouterOutlet } from '@angular/router';
@Component({
selector: 'app-root',
imports: [RouterOutlet],
templateUrl: './app.html',
styleUrl: './app.css'
})
export class App {
}

27
src/env.d.ts vendored Normal file
View File

@@ -0,0 +1,27 @@
// Define the type of the environment variables.
declare interface Env {
readonly NODE_ENV: string;
// Replace the following with your own environment variables.
// Example: NGX_VERSION: string;
[key: string]: any;
}
// Choose how to access the environment variables.
// Remove the unused options.
// 1. Use import.meta.env.YOUR_ENV_VAR in your code. (conventional)
declare interface ImportMeta {
readonly env: Env;
}
// 2. Use _NGX_ENV_.YOUR_ENV_VAR in your code. (customizable)
// You can modify the name of the variable in angular.json.
// ngxEnv: {
// define: '_NGX_ENV_',
// }
declare const _NGX_ENV_: Env;
// 3. Use process.env.YOUR_ENV_VAR in your code. (deprecated)
declare namespace NodeJS {
export interface ProcessEnv extends Env {}
}

View File

@@ -0,0 +1,6 @@
export const environment = {
production: false,
keycloakUrl: import.meta.env['NG_APP_KEYCLOAK_URL'],
keycloakClient: import.meta.env['NG_APP_KEYCLOAK_CLIENT'],
keycloakRealm: import.meta.env['NG_APP_KEYCLOAK_REALM']
};

View File

@@ -0,0 +1,6 @@
export const environment = {
production: true,
keycloakUrl: import.meta.env['NG_APP_KEYCLOAK_URL'],
keycloakClient: import.meta.env['NG_APP_KEYCLOAK_CLIENT'],
keycloakRealm: import.meta.env['NG_APP_KEYCLOAK_REALM']
};

15
src/index.html Normal file
View File

@@ -0,0 +1,15 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Social App</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</head>
<body class="has-navbar-fixed-top">
<app-root></app-root>
</body>
</html>

5
src/main.ts Normal file
View File

@@ -0,0 +1,5 @@
import { bootstrapApplication } from '@angular/platform-browser';
import { appConfig } from './app/app.config';
import { App } from './app/app';
bootstrapApplication(App, appConfig).catch((err) => console.error(err));

37
src/material-theme.scss Normal file
View File

@@ -0,0 +1,37 @@
// Include theming for Angular Material with `mat.theme()`.
// This Sass mixin will define CSS variables that are used for styling Angular Material
// components according to the Material 3 design spec.
// Learn more about theming and how to use it for your application's
// custom components at https://material.angular.dev/guide/theming
@use '@angular/material' as mat;
html {
height: 100%;
@include mat.theme((
color: (
primary: mat.$azure-palette,
tertiary: mat.$blue-palette,
),
typography: Roboto,
density: 0,
));
}
body {
// Default the application to a light color theme. This can be changed to
// `dark` to enable the dark color theme, or to `light dark` to defer to the
// user's system settings.
color-scheme: light;
// Set a default background, font and text colors for the application using
// Angular Material's system-level CSS variables. Learn more about these
// variables at https://material.angular.dev/guide/system-variables
background-color: var(--mat-sys-surface);
color: var(--mat-sys-on-surface);
font: var(--mat-sys-body-medium);
// Reset the user agent margin.
margin: 0;
height: 100%;
}

1
src/styles.css Normal file
View File

@@ -0,0 +1 @@
@import 'bulma/css/versions/bulma-no-dark-mode.css';

15
tsconfig.app.json Normal file
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
tsconfig.json Normal file
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
tsconfig.spec.json Normal file
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"
]
}