This commit is contained in:
@@ -6,6 +6,7 @@ import { LoggedInGuard } from './shared/guards/logged-in.guard';
|
||||
import { CreatePostComponent } from './routes/post/create-post/create-post.component';
|
||||
import { UpdatePostComponent } from './routes/post/update-post/update-post.component';
|
||||
import { AccountComponent } from './routes/dashboard/account/account.component';
|
||||
import { SecretPostComponent } from './routes/post/secret-post/secret-post.component';
|
||||
|
||||
export const routes: Routes = [
|
||||
{ path: '', component: HomeComponent },
|
||||
@@ -13,6 +14,7 @@ export const routes: Routes = [
|
||||
path: 'post',
|
||||
children: [
|
||||
{ path: 'new', component: CreatePostComponent },
|
||||
{ path: 'secret/:secret', component: SecretPostComponent },
|
||||
{ path: ':id/edit', component: UpdatePostComponent },
|
||||
{
|
||||
path: ':id',
|
||||
|
||||
@@ -1,4 +1,16 @@
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-5">
|
||||
<div class="flex justify-between">
|
||||
<label>Private:</label>
|
||||
<input
|
||||
type="checkbox"
|
||||
[ngModel]="data().private"
|
||||
(ngModelChange)="private = $event"
|
||||
class="p-1 border-2 rounded-md col-span-2"
|
||||
/>
|
||||
</div>
|
||||
<p>
|
||||
{{ data().private ? "this post is private" : "this post is public" }}
|
||||
</p>
|
||||
<div class="grid grid-cols-3">
|
||||
<label>Title:</label>
|
||||
<input
|
||||
|
||||
@@ -22,9 +22,18 @@ export class PostEditorComponent {
|
||||
title: '',
|
||||
tldr: '',
|
||||
content: '',
|
||||
private: false,
|
||||
});
|
||||
@Output('postChange') dataChange = new EventEmitter<Post>();
|
||||
|
||||
constructor() {
|
||||
effect(() => {
|
||||
if (this.data().private === null) {
|
||||
this.private = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
set title(val: string) {
|
||||
this.data.update((d) => ({ ...d, title: val }));
|
||||
}
|
||||
@@ -36,4 +45,7 @@ export class PostEditorComponent {
|
||||
set content(val: string) {
|
||||
this.data.update((d) => ({ ...d, content: val }));
|
||||
}
|
||||
set private(val: boolean) {
|
||||
this.data.update((d) => ({ ...d, private: val }));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<section class="grid grid-cols-1 gap-5 m-5">
|
||||
<article
|
||||
*ngFor="let post of posts()"
|
||||
class="p-5 grid grid-cols-5 grid-rows-3 items-start rounded-s bg-white drop-shadow-md hover:drop-shadow-lg"
|
||||
class="p-5 grid grid-cols-5 grid-rows-3 items-start rounded-s bg-white drop-shadow-md hover:drop-shadow-lg gap-5"
|
||||
>
|
||||
<h3 class="text-xl col-span-4">{{ post.title }}</h3>
|
||||
<p class="col-start-1 col-span-4 row-start-2 row-span-2">
|
||||
@@ -31,5 +31,14 @@
|
||||
>
|
||||
Delete
|
||||
</app-button>
|
||||
@if (post.secret !== undefined) {
|
||||
<app-button
|
||||
(click)="getPath(post.secret)"
|
||||
class="col-start-5 row-start-2"
|
||||
color="yellow"
|
||||
>
|
||||
Copy Link
|
||||
</app-button>
|
||||
}
|
||||
</article>
|
||||
</section>
|
||||
|
||||
@@ -17,4 +17,8 @@ export class DashboardComponent {
|
||||
delete(id: number) {
|
||||
this.postsService.deletePost(id);
|
||||
}
|
||||
getPath(secret: string) {
|
||||
const url = document.URL.replaceAll('/dashboard', '');
|
||||
navigator.clipboard.writeText(`${url}/post/secret/${secret}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Component, inject, Input } from '@angular/core';
|
||||
import { PostsService } from '../../shared/services/posts.service';
|
||||
import { JsonPipe, NgIf } from '@angular/common';
|
||||
import { MarkdownComponent } from '../../components/markdown/markdown.component';
|
||||
|
||||
@Component({
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<h2 class="text-3xl">{{ post()?.title }}</h2>
|
||||
<p class="mb-5 italic text-sm">TL;DR; {{ post()?.tldr }}</p>
|
||||
|
||||
<app-markdown
|
||||
class="todo"
|
||||
[markdown]="post()?.content || 'this post is empty'"
|
||||
/>
|
||||
28
web/src/app/routes/post/secret-post/secret-post.component.ts
Normal file
28
web/src/app/routes/post/secret-post/secret-post.component.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import {
|
||||
Component,
|
||||
inject,
|
||||
Input,
|
||||
OnInit,
|
||||
signal,
|
||||
WritableSignal,
|
||||
} from '@angular/core';
|
||||
import { PostsService } from '../../../shared/services/posts.service';
|
||||
import { Post } from '../../../shared/interfaces/post';
|
||||
import { MarkdownComponent } from '../../../components/markdown/markdown.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-secret-post',
|
||||
imports: [MarkdownComponent],
|
||||
templateUrl: './secret-post.component.html',
|
||||
})
|
||||
export class SecretPostComponent implements OnInit {
|
||||
@Input() secret!: string;
|
||||
private postsService = inject(PostsService);
|
||||
post: WritableSignal<Post | undefined> = signal(undefined);
|
||||
|
||||
ngOnInit(): void {
|
||||
this.postsService.getPostBySecret(this.secret).subscribe((post) => {
|
||||
this.post.set(post);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,8 @@ export interface Post {
|
||||
title: string;
|
||||
tldr: string;
|
||||
content: string;
|
||||
private?: boolean;
|
||||
secret?: string;
|
||||
}
|
||||
|
||||
export interface Comment {
|
||||
|
||||
@@ -35,6 +35,9 @@ export class PostsService {
|
||||
getPost(id: number): Signal<Post | undefined> {
|
||||
return computed(() => this.posts().get(id));
|
||||
}
|
||||
getPostBySecret(secret: string) {
|
||||
return this.http.get<Post>(`${environment.apiRoot}/posts/secret/${secret}`);
|
||||
}
|
||||
|
||||
deletePost(id: number) {
|
||||
this.http.delete(`${environment.apiRoot}/posts/${id}`).subscribe(() => {
|
||||
|
||||
Reference in New Issue
Block a user