feat: challenge 45 React in Angular

Add new challenge: React in Angular.
This commit is contained in:
Wandrille
2024-02-09 09:25:05 +01:00
parent 77ead59094
commit 0f4f14c351
27 changed files with 485 additions and 37 deletions

View File

@@ -0,0 +1,62 @@
import { Component, signal } from '@angular/core';
import { PostComponent } from './react/post.component';
type Post = { title: string; description: string };
@Component({
standalone: true,
imports: [PostComponent],
selector: 'app-root',
template: `
<div class="flex flex-col gap-2 p-12">
<div class="flex gap-2">
@for (post of posts; track post.title) {
<div class="rounded-lg bg-gray-100 p-4">
<app-post
(selectPost)="selectPost(post)"
[post]="post"
[isSelected]="post.title === selectedPost()?.title"></app-post>
</div>
}
</div>
<div class="flex flex-col gap-2 border p-4">
<span class="text-xs font-medium">Selected Post:</span>
<span class="text-lg text-blue-700">
{{ selectedPost()?.title ?? '-' }}
</span>
</div>
</div>
`,
styles: [''],
})
export class AppComponent {
readonly posts = [
{
title: 'A Deep Dive into Angular',
description:
"Explore Angular's core features, its evolution, and best practices in development for creating dynamic, efficient web applications in our comprehensive guide.",
pictureLink:
'https://images.unsplash.com/photo-1471958680802-1345a694ba6d',
},
{
title: 'The Perfect Combination',
description:
'Unveil the power of combining Angular & React in web development, maximizing efficiency and flexibility for building scalable, sophisticated applications.',
pictureLink:
'https://images.unsplash.com/photo-1518717202715-9fa9d099f58a',
},
{
title: 'Taking Angular to the Next Level',
description:
"Discover how integrating React with Angular elevates web development, blending Angular's structure with React's UI prowess for advanced applications.",
pictureLink:
'https://images.unsplash.com/photo-1532103050105-860af53bc6aa',
},
];
readonly selectedPost = signal<Post | null>(null);
selectPost(post: Post) {
this.selectedPost.set(post);
}
}

View File

@@ -0,0 +1,5 @@
import { ApplicationConfig } from '@angular/core';
export const appConfig: ApplicationConfig = {
providers: [],
};

View File

@@ -0,0 +1,27 @@
// import React from 'react';
export default function ReactPost(props: {
title?: string,
description?: string,
pictureLink?: string,
selected?: boolean,
handleClick: () => void
}) {
return (
<div className={props.selected ? 'bg-blue-100' : 'bg-white'}>
<div className="max-w-sm rounded overflow-hidden shadow-lg">
<img className="w-full h-32 object-cover" src={props.pictureLink} alt={props.title}></img>
<div className="px-6 py-4 flex flex-col gap-2">
<div className="font-bold text-xl mb-2">{props.title}</div>
<p className="text-gray-700 text-base">
{props.description}
</p>
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
onClick={props.handleClick}>
Select
</button>
</div>
</div>
</div>
);
}

View File

@@ -0,0 +1,17 @@
import { Component, EventEmitter, input, Output } from '@angular/core';
type Post = { title: string; description: string; pictureLink: string };
@Component({
standalone: true,
selector: 'app-post',
template: `
<div></div>
`,
styles: [''],
})
export class PostComponent {
post = input<Post | undefined>(undefined);
isSelected = input<boolean>(false);
@Output() selectPost = new EventEmitter<void>();
}