Added paths and some standard code used in different projects
This commit is contained in:
committed by
Erik Tiekstra
parent
e2114e79b9
commit
03ba526798
@@ -0,0 +1,24 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { ExtraOptions, RouterModule, Routes } from '@angular/router';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
data: { title: 'FA Mina sidor' },
|
||||
loadChildren: () => import('./pages/start/start.module').then(m => m.StartModule),
|
||||
},
|
||||
{
|
||||
path: '**',
|
||||
data: { title: 'Sidan hittas inte' },
|
||||
loadChildren: () => import('./pages/page-not-found/page-not-found.module').then(m => m.PageNotFoundModule),
|
||||
},
|
||||
];
|
||||
const options: ExtraOptions = {
|
||||
useHash: false,
|
||||
};
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forRoot(routes, options)],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class AppRoutingModule {}
|
||||
@@ -1,111 +1,11 @@
|
||||
<header class="flex">
|
||||
<img
|
||||
alt="Nx logo"
|
||||
width="75"
|
||||
src="https://nx.dev/assets/images/nx-logo-white.svg"
|
||||
/>
|
||||
<h1>Welcome to {{ title }}!</h1>
|
||||
</header>
|
||||
<main>
|
||||
<h2>Resources & Tools</h2>
|
||||
<p>Thank you for using and showing some ♥ for Nx.</p>
|
||||
<div class="flex github-star-container">
|
||||
<a
|
||||
href="https://github.com/nrwl/nx"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
If you like Nx, please give it a star:
|
||||
<div class="github-star-badge">
|
||||
<svg
|
||||
class="material-icons"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path d="M0 0h24v24H0z" fill="none" />
|
||||
<path
|
||||
d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"
|
||||
/>
|
||||
</svg>
|
||||
Star
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<p>Here are some links to help you get started.</p>
|
||||
<ul class="resources">
|
||||
<li class="col-span-2">
|
||||
<a class="resource flex" href="https://nxplaybook.com/p/nx-workspaces">
|
||||
Nx video course
|
||||
</a>
|
||||
</li>
|
||||
<li class="col-span-2">
|
||||
<a
|
||||
class="resource flex"
|
||||
href="https://nx.dev/latest/angular/getting-started/getting-started"
|
||||
>
|
||||
Nx video tutorial
|
||||
</a>
|
||||
</li>
|
||||
<li class="col-span-2">
|
||||
<a
|
||||
class="resource flex"
|
||||
href="https://nx.dev/latest/angular/tutorial/01-create-application"
|
||||
>
|
||||
Interactive tutorial
|
||||
</a>
|
||||
</li>
|
||||
<li class="col-span-2">
|
||||
<a class="resource flex" href="https://nx.app/">
|
||||
<svg
|
||||
width="36"
|
||||
height="36"
|
||||
viewBox="0 0 120 120"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M120 15V30C103.44 30 90 43.44 90 60C90 76.56 76.56 90 60 90C43.44 90 30 103.44 30 120H15C6.72 120 0 113.28 0 105V15C0 6.72 6.72 0 15 0H105C113.28 0 120 6.72 120 15Z"
|
||||
fill="#0E2039"
|
||||
/>
|
||||
<path
|
||||
d="M120 30V105C120 113.28 113.28 120 105 120H30C30 103.44 43.44 90 60 90C76.56 90 90 76.56 90 60C90 43.44 103.44 30 120 30Z"
|
||||
fill="white"
|
||||
/>
|
||||
</svg>
|
||||
<span class="gutter-left">Nx Cloud</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h2>Next Steps</h2>
|
||||
<p>Here are some things you can do with Nx.</p>
|
||||
<details open>
|
||||
<summary>Add UI library</summary>
|
||||
<pre>
|
||||
# Generate UI lib
|
||||
ng g @nrwl/angular:lib ui
|
||||
<div [ngClass]="appClass">
|
||||
<dafa-skip-to-content mainContentId="dafa-main-content"></dafa-skip-to-content>
|
||||
|
||||
# Add a component
|
||||
ng g @nrwl/angular:component xyz --project ui</pre
|
||||
>
|
||||
</details>
|
||||
<details>
|
||||
<summary>View dependency graph</summary>
|
||||
<pre>nx dep-graph</pre>
|
||||
</details>
|
||||
<details>
|
||||
<summary>Run affected commands</summary>
|
||||
<pre>
|
||||
# see what's been affected by changes
|
||||
ng affected:dep-graph
|
||||
<header class="dafa__header">
|
||||
<dafa-navigation></dafa-navigation>
|
||||
</header>
|
||||
|
||||
# run tests for current changes
|
||||
ng affected:test
|
||||
|
||||
# run e2e tests for current changes
|
||||
ng affected:e2e
|
||||
</pre
|
||||
>
|
||||
</details>
|
||||
</main>
|
||||
<main id="dafa-main-content" class="dafa__main">
|
||||
<router-outlet></router-outlet>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
/*
|
||||
* Remove template code below
|
||||
*/
|
||||
:host {
|
||||
display: block;
|
||||
font-family: sans-serif;
|
||||
min-width: 300px;
|
||||
max-width: 600px;
|
||||
margin: 50px auto;
|
||||
}
|
||||
|
||||
.gutter-left {
|
||||
margin-left: 9px;
|
||||
}
|
||||
|
||||
.col-span-2 {
|
||||
grid-column: span 2;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
header {
|
||||
background-color: #143055;
|
||||
color: white;
|
||||
padding: 5px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
main {
|
||||
padding: 0 36px;
|
||||
}
|
||||
|
||||
p {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
margin-left: 18px;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
margin: 40px 0 10px 0;
|
||||
}
|
||||
|
||||
.resources {
|
||||
text-align: center;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
display: grid;
|
||||
grid-gap: 9px;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
|
||||
.resource {
|
||||
color: #0094ba;
|
||||
height: 36px;
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
border: 1px solid rgba(0, 0, 0, 0.12);
|
||||
border-radius: 4px;
|
||||
padding: 3px 9px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.resource:hover {
|
||||
background-color: rgba(68, 138, 255, 0.04);
|
||||
}
|
||||
|
||||
pre {
|
||||
padding: 9px;
|
||||
border-radius: 4px;
|
||||
background-color: black;
|
||||
color: #eee;
|
||||
}
|
||||
|
||||
details {
|
||||
border-radius: 4px;
|
||||
color: #333;
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
border: 1px solid rgba(0, 0, 0, 0.12);
|
||||
padding: 3px 9px;
|
||||
margin-bottom: 9px;
|
||||
}
|
||||
|
||||
summary {
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
}
|
||||
|
||||
.github-star-container {
|
||||
margin-top: 12px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.github-star-container a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-decoration: none;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.github-star-badge {
|
||||
color: #24292e;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 12px;
|
||||
padding: 3px 10px;
|
||||
border: 1px solid rgba(27, 31, 35, 0.2);
|
||||
border-radius: 3px;
|
||||
background-image: linear-gradient(-180deg, #fafbfc, #eff3f6 90%);
|
||||
margin-left: 4px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.github-star-badge:hover {
|
||||
background-image: linear-gradient(-180deg, #f0f3f6, #e6ebf1 90%);
|
||||
border-color: rgba(27, 31, 35, 0.35);
|
||||
background-position: -0.5em;
|
||||
}
|
||||
.github-star-badge .material-icons {
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
@@ -13,19 +13,4 @@ describe('AppComponent', () => {
|
||||
const app = fixture.componentInstance;
|
||||
expect(app).toBeTruthy();
|
||||
});
|
||||
|
||||
it(`should have as title 'dafa-web'`, () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.componentInstance;
|
||||
expect(app.title).toEqual('dafa-web');
|
||||
});
|
||||
|
||||
it('should render title', () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
fixture.detectChanges();
|
||||
const compiled = fixture.nativeElement;
|
||||
expect(compiled.querySelector('h1').textContent).toContain(
|
||||
'Welcome to dafa-web!'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,10 +1,30 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { NavigationEnd, Router } from '@angular/router';
|
||||
import { filter } from 'rxjs/operators';
|
||||
import { UnsubscribeDirective } from './directives/unsubscribe.directive';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
selector: 'dafa-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class AppComponent {
|
||||
title = 'dafa-web';
|
||||
export class AppComponent extends UnsubscribeDirective {
|
||||
path = '';
|
||||
|
||||
constructor(private router: Router) {
|
||||
super();
|
||||
super.unsubscribeOnDestroy(
|
||||
this.router.events.pipe(filter(event => event instanceof NavigationEnd)).subscribe(() => {
|
||||
const url = this.router.url;
|
||||
this.path = url.split('/')[1].split('?')[0] || '';
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
get appClass(): string {
|
||||
let defaultClass = `dafa dafa--${this.path.length ? this.path : 'home'}`;
|
||||
|
||||
return defaultClass;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { AppComponent } from './app.component';
|
||||
import { NavigationModule } from './components/navigation/navigation.module';
|
||||
import { SkipToContentModule } from './components/skip-to-content/skip-to-content.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [AppComponent],
|
||||
imports: [BrowserModule],
|
||||
imports: [BrowserModule, HttpClientModule, AppRoutingModule, SkipToContentModule, NavigationModule],
|
||||
providers: [],
|
||||
bootstrap: [AppComponent],
|
||||
})
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<div class="navigation">
|
||||
<div class="navigation__logo-wrapper">
|
||||
<a id="logo-heading" [routerLink]="['/']">
|
||||
<img src="assets/logo/fa-mina-sidor-dark.svg" class="navigation__logo" alt="" />
|
||||
<span class="af__a11y-sr-only">Till startsidan för FA Mina sidor</span>
|
||||
</a>
|
||||
</div>
|
||||
<ul class="navigation__list dafa__hide-on-print">
|
||||
<li class="navigation__item">
|
||||
<a
|
||||
class="navigation__link"
|
||||
[routerLink]="['/']"
|
||||
[routerLinkActive]="['navigation__link--active']"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
>
|
||||
<span class="navigation__text">Startsida</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -0,0 +1,116 @@
|
||||
@import 'mixins/list';
|
||||
@import 'variables/border-radius';
|
||||
@import 'variables/breakpoints';
|
||||
@import 'variables/colors';
|
||||
@import 'variables/gutters';
|
||||
@import 'variables/typography';
|
||||
|
||||
$navigation-height: 2.5rem;
|
||||
$navigation-height-large: 4rem;
|
||||
|
||||
.navigation {
|
||||
background-color: white;
|
||||
border-bottom: 1px solid $af__color-background-gray;
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 $af__gutter-m;
|
||||
|
||||
@media (max-width: $af__breakpoint-s-below) {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
&__logo-wrapper {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&__logo {
|
||||
height: $navigation-height / 2;
|
||||
vertical-align: middle;
|
||||
|
||||
@media (min-width: $af__breakpoint-m) {
|
||||
height: $navigation-height-large / 2;
|
||||
}
|
||||
}
|
||||
|
||||
&__list {
|
||||
@include dafa__reset-list;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
&__item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-left: 1px solid $af__color-background-gray;
|
||||
|
||||
&--no-link {
|
||||
padding: 0 $af__gutter-m;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-right: 1px solid $af__color-background-gray;
|
||||
}
|
||||
}
|
||||
|
||||
&__link,
|
||||
&__no-link {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: $af__font-size-xs;
|
||||
color: $af__color-text;
|
||||
width: 7rem;
|
||||
height: $navigation-height;
|
||||
font-weight: $af__font-weight-normal;
|
||||
text-decoration: none;
|
||||
|
||||
@media (min-width: $af__breakpoint-m) {
|
||||
height: $navigation-height-large;
|
||||
}
|
||||
}
|
||||
|
||||
&__link {
|
||||
&:hover {
|
||||
background-color: $af__color-background-gray;
|
||||
}
|
||||
|
||||
&--active {
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
height: 5px;
|
||||
background-color: $af__color-primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__text {
|
||||
margin-top: $af__gutter-xxs;
|
||||
}
|
||||
|
||||
&__news {
|
||||
display: flex;
|
||||
gap: $af__gutter-xs;
|
||||
padding: $af__gutter-xs $af__gutter-s;
|
||||
background-color: $af__color-complementary-alt;
|
||||
color: $af__color-text-light;
|
||||
border-radius: $af__border-radius;
|
||||
|
||||
&:hover {
|
||||
background-color: darken($af__color-complementary-alt, 10%);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
import { NavigationComponent } from './navigation.component';
|
||||
|
||||
describe('NavigationComponent', () => {
|
||||
let component: NavigationComponent;
|
||||
let fixture: ComponentFixture<NavigationComponent>;
|
||||
|
||||
beforeEach(
|
||||
waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [NavigationComponent],
|
||||
}).compileComponents();
|
||||
})
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(NavigationComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { IconType } from '@dafa-enums/icon-type.enum';
|
||||
|
||||
@Component({
|
||||
selector: 'dafa-navigation',
|
||||
templateUrl: './navigation.component.html',
|
||||
styleUrls: ['./navigation.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class NavigationComponent {
|
||||
iconType = IconType;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { NavigationComponent } from './navigation.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [NavigationComponent],
|
||||
imports: [CommonModule, RouterModule],
|
||||
exports: [NavigationComponent],
|
||||
})
|
||||
export class NavigationModule {}
|
||||
@@ -0,0 +1,9 @@
|
||||
@import 'variables/gutters';
|
||||
|
||||
@media print {
|
||||
.navigation {
|
||||
border-bottom-width: 0;
|
||||
padding: $af__gutter-m 0;
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<a [attr.href]="skipLinkPath" class="skip-to-content">Gå till sidans innehåll</a>
|
||||
@@ -0,0 +1,31 @@
|
||||
@import 'variables/border-radius';
|
||||
@import 'variables/colors';
|
||||
@import 'variables/gutters';
|
||||
|
||||
.skip-to-content {
|
||||
position: absolute;
|
||||
top: -1000px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 0;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
z-index: 1000;
|
||||
text-align: center;
|
||||
padding: $af__gutter-xs $af__gutter-m;
|
||||
display: block;
|
||||
background-color: $dafa__color-pink;
|
||||
color: $af__color-text-light;
|
||||
|
||||
&:focus {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: auto;
|
||||
height: auto;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
import { SkipToContentComponent } from './skip-to-content.component';
|
||||
|
||||
|
||||
describe('SkipToContentComponent', () => {
|
||||
let component: SkipToContentComponent;
|
||||
let fixture: ComponentFixture<SkipToContentComponent>;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [SkipToContentComponent],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SkipToContentComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input } from '@angular/core';
|
||||
import { NavigationEnd, Router } from '@angular/router';
|
||||
import { UnsubscribeDirective } from '@dafa-directives/unsubscribe.directive';
|
||||
import { filter } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'dafa-skip-to-content',
|
||||
templateUrl: './skip-to-content.component.html',
|
||||
styleUrls: ['./skip-to-content.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class SkipToContentComponent extends UnsubscribeDirective {
|
||||
@Input() mainContentId: string;
|
||||
skipLinkPath: string;
|
||||
|
||||
constructor(private router: Router, private changeDetectorRef: ChangeDetectorRef) {
|
||||
super();
|
||||
super.unsubscribeOnDestroy(
|
||||
this.router.events.pipe(filter((event: any) => event instanceof NavigationEnd)).subscribe(({ url }) => {
|
||||
const mainContentId = `#${this.mainContentId}`;
|
||||
// Check if the current URL already includes the mainContentId.
|
||||
const existsInUrl: boolean = url.substring(url.length - mainContentId.length, url.length) === mainContentId;
|
||||
|
||||
this.skipLinkPath = existsInUrl ? url : `${url}${mainContentId}`;
|
||||
this.changeDetectorRef.markForCheck();
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { SkipToContentComponent } from './skip-to-content.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [SkipToContentComponent],
|
||||
imports: [CommonModule],
|
||||
exports: [SkipToContentComponent],
|
||||
})
|
||||
export class SkipToContentModule {}
|
||||
@@ -0,0 +1,6 @@
|
||||
export enum IconSize {
|
||||
S = 's',
|
||||
M = 'm',
|
||||
L = 'l',
|
||||
XL = 'xl',
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export enum IconType {
|
||||
HOME = 'home',
|
||||
USER = 'user',
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { Directive, OnDestroy } from '@angular/core';
|
||||
import { Subscription } from 'rxjs';
|
||||
|
||||
@Directive()
|
||||
export class UnsubscribeDirective implements OnDestroy {
|
||||
private subscriptions: Subscription[] = [];
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.subscriptions.forEach(sub => sub.unsubscribe());
|
||||
}
|
||||
|
||||
unsubscribeOnDestroy(...sub: Subscription[]): void {
|
||||
this.subscriptions.push(...sub);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<digi-ng-typography-base [afCompressed]="true">
|
||||
<section class="page-not-found">
|
||||
<h1 class="heading">Oj då! Vi kan inte hitta sidan.</h1>
|
||||
<p>Det kan bero på att länken du använder är felaktig eller att sidan inte längre finns.</p>
|
||||
<a class="dafa__link dafa__link--with-icon" routerLink="/">
|
||||
<digi-ng-icon-arrow-left class="dafa__digi-ng-icon" aria-hidden="true"></digi-ng-icon-arrow-left>
|
||||
Gå tillbaka till startsidan
|
||||
</a>
|
||||
</section>
|
||||
</digi-ng-typography-base>
|
||||
@@ -0,0 +1,4 @@
|
||||
.page-not-found {
|
||||
text-align: center;
|
||||
padding: 5rem;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
import { PageNotFoundComponent } from './page-not-found.component';
|
||||
|
||||
|
||||
describe('PageNotFoundComponent', () => {
|
||||
let component: PageNotFoundComponent;
|
||||
let fixture: ComponentFixture<PageNotFoundComponent>;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ PageNotFoundComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(PageNotFoundComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'dafa-page-not-found',
|
||||
templateUrl: './page-not-found.component.html',
|
||||
styleUrls: ['./page-not-found.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class PageNotFoundComponent {}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { DigiNgIconArrowLeftModule } from '@af/digi-ng/_icon/icon-arrow-left';
|
||||
import { DigiNgTypographyBaseModule } from '@af/digi-ng/_typography/typography-base';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { PageNotFoundComponent } from './page-not-found.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [PageNotFoundComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
RouterModule.forChild([{ path: '', component: PageNotFoundComponent }]),
|
||||
DigiNgTypographyBaseModule,
|
||||
DigiNgIconArrowLeftModule,
|
||||
],
|
||||
})
|
||||
export class PageNotFoundModule {}
|
||||
@@ -0,0 +1,3 @@
|
||||
<digi-ng-typography-base>
|
||||
<section class="start">Start funkar!</section>
|
||||
</digi-ng-typography-base>
|
||||
@@ -0,0 +1,101 @@
|
||||
@import 'variables/breakpoints';
|
||||
@import 'variables/colors';
|
||||
@import 'variables/gutters';
|
||||
@import 'variables/typography';
|
||||
@import 'mixins/ie11';
|
||||
@import 'mixins/typography';
|
||||
|
||||
.start {
|
||||
&__header {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
margin: $af__gutter-goliath 0;
|
||||
}
|
||||
|
||||
&__heading {
|
||||
position: absolute;
|
||||
margin: 0;
|
||||
bottom: $af__gutter-xxl;
|
||||
left: -$af__gutter-m;
|
||||
background-color: $af__color-primary;
|
||||
color: $af__color-text-light;
|
||||
padding: $af__gutter-m $af__gutter-xxl;
|
||||
}
|
||||
|
||||
&__intro {
|
||||
max-width: 700px;
|
||||
}
|
||||
|
||||
&__subheading {
|
||||
font-size: $af__font-size-h1 !important;
|
||||
margin: $af__gutter-xxl 0 !important;
|
||||
@include dafa__typography-ornament;
|
||||
}
|
||||
|
||||
&__background-image {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
object-fit: cover;
|
||||
object-position: center 33%;
|
||||
|
||||
@media (min-width: $af__breakpoint-m) {
|
||||
height: 250px;
|
||||
}
|
||||
|
||||
@media (min-width: $af__breakpoint-l) {
|
||||
height: 290px;
|
||||
}
|
||||
|
||||
@media (min-width: $af__breakpoint-xl) {
|
||||
height: 320px;
|
||||
}
|
||||
}
|
||||
|
||||
&__cta-wrapper {
|
||||
background-color: $af__color-background-alt-tertiary;
|
||||
margin: $af__gutter-xxl 0;
|
||||
padding: $af__gutter-xxl;
|
||||
}
|
||||
|
||||
&__cta {
|
||||
display: flex;
|
||||
gap: $af__gutter-xl;
|
||||
}
|
||||
|
||||
&__puff {
|
||||
width: calc(100% / 3);
|
||||
|
||||
@include ie11 {
|
||||
&:not(:first-child) {
|
||||
margin-left: $af__gutter-xl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__footer {
|
||||
margin-top: $af__gutter-goliath;
|
||||
background-color: $af__color-background-light-gray;
|
||||
padding: $af__gutter-xxl 0 $af__gutter-goliath;
|
||||
}
|
||||
|
||||
&__footer-heading {
|
||||
margin-top: 0 !important;
|
||||
margin-bottom: $af__gutter-l !important;
|
||||
}
|
||||
|
||||
&__card-wrapper {
|
||||
display: flex;
|
||||
align-content: stretch;
|
||||
gap: $af__gutter-xxl;
|
||||
}
|
||||
|
||||
&__card {
|
||||
max-width: 400px;
|
||||
flex-basis: 100%;
|
||||
}
|
||||
|
||||
&__card-link {
|
||||
display: inline-block;
|
||||
margin-top: $af__gutter-l;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
import { StartComponent } from './start.component';
|
||||
|
||||
describe('StartComponent', () => {
|
||||
let component: StartComponent;
|
||||
let fixture: ComponentFixture<StartComponent>;
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [StartComponent],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(StartComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,11 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'dafa-start',
|
||||
templateUrl: './start.component.html',
|
||||
styleUrls: ['./start.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class StartComponent {
|
||||
constructor() {}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { DigiNgTypographyBaseModule } from '@af/digi-ng/_typography/typography-base';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { StartComponent } from './start.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [StartComponent],
|
||||
imports: [CommonModule, RouterModule.forChild([{ path: '', component: StartComponent }]), DigiNgTypographyBaseModule],
|
||||
})
|
||||
export class StartModule {}
|
||||
Reference in New Issue
Block a user