Skip to content

Commit cf25290

Browse files
add home screen
1 parent f21eebe commit cf25290

22 files changed

+655
-305
lines changed

package-lock.json

+4-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

-4
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,7 @@
1818
"@angular/platform-browser": "^17.3.11",
1919
"@angular/platform-browser-dynamic": "^17.3.11",
2020
"@angular/router": "^17.3.11",
21-
"highlight.js": "^11.9.0",
2221
"ng-github-button": "^18.0.0",
23-
"ngx-highlight-js": "^18.0.0",
24-
"ngx-highlightjs": "^12.0.0",
2522
"rxjs": "~7.5.0",
2623
"tslib": "^2.3.0",
2724
"zone.js": "~0.14.7"
@@ -30,7 +27,6 @@
3027
"@angular-devkit/build-angular": "^17.3.8",
3128
"@angular/cli": "~17.3.8",
3229
"@angular/compiler-cli": "^17.3.11",
33-
"@types/highlight.js": "^10.1.0",
3430
"@types/jasmine": "~4.3.0",
3531
"@types/json-schema": "^7.0.15",
3632
"autoprefixer": "^10.4.19",

src/app/app-routing.module.ts

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { NgModule } from '@angular/core';
2+
import { RouterModule, Routes } from '@angular/router';
3+
import { HomeComponent } from './pages/home/home.component';
4+
import { CreateComponent } from './pages/create/create.component';
5+
6+
const routes: Routes = [
7+
{ path: '', component: HomeComponent },
8+
{ path: 'create/:urlName', component: CreateComponent },
9+
{ path: '**', redirectTo: '/' }
10+
];
11+
12+
@NgModule({
13+
imports: [RouterModule.forRoot(routes)],
14+
exports: [RouterModule]
15+
})
16+
export class AppRoutingModule { }

src/app/app.component.html

+1-99
Original file line numberDiff line numberDiff line change
@@ -1,99 +1 @@
1-
<app-menu (onFetchValue)="setFetchValue($event)" />
2-
3-
<div class="w-full flex flex-col md:flex-row bg-zinc-950">
4-
<div
5-
class="resize-none md:resize-x w-full md:w-[33.3333%] flex-grow mx-auto flex flex-col h-full md:h-[calc(100vh-56px)] overflow-x-hidden overflow-y-auto md:overflow-y-scroll border-r border-zinc-800"
6-
>
7-
<form [formGroup]="form" class="p-4 md:p-8 w-full">
8-
<div class="w-full max-w-xs text-center mx-auto">
9-
<h1 class="mb-4 md:mb-8 text-sm leading-4 text-white">
10-
Just type the data and generate the meta tags for your website
11-
</h1>
12-
</div>
13-
<div class="w-full grid grid-cols-1 flex-col gap-8">
14-
<div
15-
class="relative flex flex-col gap-1"
16-
*ngFor="let field of metatagsList"
17-
>
18-
<ng-container *ngIf="field.type === 'text' || field.type === 'color'">
19-
<label [for]="field.name" class="leading-4 text-xs text-white">{{
20-
field.label
21-
}}</label>
22-
23-
<div
24-
*ngIf="field.name === 'image' && form?.get('image')"
25-
class="w-full aspect-[1.91/1] rounded bg-zinc-800 border border-zinc-800 overflow-hidden max-w-64"
26-
>
27-
<img *ngIf="form?.get('image')?.value" [src]="form.get('image')?.value" class="aspect-[1.91/1] max-w-64" width="100%" alt="" />
28-
</div>
29-
30-
<div class="relative w-full">
31-
<input
32-
[type]="field.type"
33-
[id]="field.name"
34-
[name]="field.name"
35-
[placeholder]="field.label"
36-
[formControlName]="field.name"
37-
class="h-8 text-xs w-full bg-zinc-900 rounded border placeholder:text-zinc-500 border-zinc-800 focus:border-zinc-500 focus:ring-2 focus:ring-white outline-none text-white py-1 px-3 leading-8 transition-colors duration-200 ease-in-out"
38-
/>
39-
<ng-container class="" *ngIf="field.name === 'color'">
40-
<input
41-
type="color"
42-
[id]="field.name"
43-
[name]="field.name"
44-
[placeholder]="field.label"
45-
[formControlName]="field.name"
46-
(change)="changeColor($event)"
47-
class="appearance-none w-6 min-w-6 h-6 rounded overflow-hidden absolute bottom-1 right-1 bg-transparent"
48-
/>
49-
</ng-container>
50-
<ng-container class="" *ngIf="field.name === 'favicon'">
51-
<div class="w-5 min-w-5 h-5 rounded-full absolute top-1.5 right-1.5 bg-zinc-800 border border-zinc-800 overflow-hidden">
52-
<img *ngIf="form?.get('favicon')?.value" [src]="form.get('favicon')?.value" width="100%" alt="Favicon" class="w-5 min-w-5 h-5" />
53-
</div>
54-
</ng-container>
55-
</div>
56-
<span class="text-xs text-zinc-500 leading-4 mt-1">{{
57-
field.description
58-
}}</span>
59-
</ng-container>
60-
61-
<ng-container *ngIf="field.type === 'select'">
62-
<label [for]="field.name" class="leading-4 text-xs text-white">{{
63-
field.label
64-
}}</label>
65-
<select
66-
[id]="field.name"
67-
[formControlName]="field.name"
68-
class="h-8 text-xs w-full bg-zinc-900 rounded border border-zinc-800 focus:border-zinc-500 focus:ring-2 focus:ring-white outline-none text-white py-1 px-3 leading-8 transition-colors duration-200 ease-in-out"
69-
>
70-
<option
71-
*ngFor="let option of field.options"
72-
[value]="option.value"
73-
>
74-
{{ option.value }}
75-
</option>
76-
</select>
77-
<span class="text-xs text-zinc-500 leading-4 mt-1">{{
78-
field.description
79-
}}</span>
80-
</ng-container>
81-
</div>
82-
</div>
83-
</form>
84-
85-
<app-footer />
86-
</div>
87-
88-
<div
89-
class="resize-none md:resize-x w-full md:w-[33.3333%] flex-grow mx-auto flex flex-col h-full md:h-[calc(100vh-56px)] overflow-hidden border-r border-zinc-800 p-4 md:p-0"
90-
>
91-
<app-code-result [code]="code" class="h-full" />
92-
</div>
93-
94-
<div
95-
class="w-full md:w-[33.3333%] flex-grow overflow-auto h-full md:h-[calc(100vh-56px)] bg-zinc-950 overflow-y-auto md:overflow-y-scroll overflow-x-hidden p-4 md:p-8"
96-
>
97-
<app-preview [content]="form.value" />
98-
</div>
99-
</div>
1+
<router-outlet></router-outlet>

src/app/app.component.ts

-122
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
import { Component } from '@angular/core';
2-
import { FormBuilder, FormGroup } from '@angular/forms';
3-
import { returnCode } from './utils/code';
42

53

64
@Component({
@@ -9,124 +7,4 @@ import { returnCode } from './utils/code';
97
styleUrls: ['./app.component.scss']
108
})
119
export class AppComponent {
12-
metatagsList = [
13-
{
14-
name: 'charset', type: 'select', description: 'Specifies the character encoding for the HTML document, ensuring proper display of text.', label: 'Charset', options: [
15-
{ value: "UTF-8", },
16-
{ value: "ISO-8859-1", },
17-
{ value: "ISO-8859-2", },
18-
{ value: "ISO-8859-3", },
19-
{ value: "ISO-8859-4", },
20-
{ value: "ISO-8859-5", },
21-
{ value: "ISO-8859-6", },
22-
{ value: "ISO-8859-7", },
23-
{ value: "ISO-8859-8", },
24-
{ value: "ISO-8859-9", },
25-
{ value: "ISO-8859-10", },
26-
{ value: "ISO-8859-11", },
27-
{ value: "ISO-8859-13", },
28-
{ value: "ISO-8859-14", },
29-
{ value: "ISO-8859-15", },
30-
{ value: "ISO-8859-16", },
31-
{ value: "Windows-1250", },
32-
{ value: "Windows-1251", },
33-
{ value: "Windows-1252", },
34-
{ value: "Windows-1253", },
35-
{ value: "Windows-1254", },
36-
{ value: "Windows-1255", },
37-
{ value: "Windows-1256", },
38-
{ value: "Windows-1257", },
39-
{ value: "Windows-1258", },
40-
{ value: "KOI8-R", },
41-
{ value: "KOI8-U", },
42-
{ value: "GB18030", },
43-
{ value: "Big5", },
44-
{ value: "Shift_JIS", },
45-
{ value: "EUC-JP", },
46-
{ value: "EUC-KR", },
47-
],
48-
},
49-
{ name: 'viewport', type: 'text', description: 'Controls the layout and scaling of a webpage on different devices, improving responsiveness and user experience.', label: 'Viewport' },
50-
{ name: 'name', type: 'text', description: 'Defines the name of the page.', label: 'Site name' },
51-
{ name: 'title', type: 'text', description: 'Defines the title of the HTML document, displaying text in the browser tab and aiding in search engine optimization (SEO).', label: 'Title' },
52-
{ name: 'description', type: 'text', description: 'Provides a concise summary of the webpages content, often used by search engines to display in search results, enhancing click-through rates.', label: 'Description' },
53-
{ name: 'canonical', type: 'text', description: 'Specifies the preferred URL for a webpage, consolidating search engine ranking signals and avoiding duplicate content issues.', label: 'Canonical URL' },
54-
{ name: 'image', type: 'text', description: `Specifies the image displayed when sharing the webpage on platforms like Facebook, enhancing visual appeal. Og:images should have an aspect ratio of 1.91:1. This means that the width should be 1.9 X the height to avoid cropping issues. Your image shouldn't be larger than 8MB. Image size should be 1200 X 630 pixels (px).`, label: 'Image URL' },
55-
{ name: 'imageAlt', type: 'text', description: 'Provides alternative text for the image specified in og:image, improving accessibility and SEO when shared on platforms supporting Open Graph.', label: 'Image alt text' },
56-
{ name: 'favicon', type: 'text', description: 'Specifies the favicon, enhancing website recognition in browsers and bookmarks.', label: 'Favicon' },
57-
{ name: 'color', type: 'text', description: 'Defines the color theme for the browsers UI elements when a webpage is viewed on mobile devices, enhancing user experience and brand consistency.', label: 'Theme color' },
58-
{ name: 'author', type: 'text', description: 'Specifies the author of the webpage, providing attribution for content creation and ownership.', label: 'Author' },
59-
{
60-
name: 'robots', type: 'select', description: 'Controls how search engines index and display content, influencing webpage visibility and accessibility in search results.', label: 'Robots', options: [
61-
{ value: 'index, follow' },
62-
{ value: 'index, nofollow' },
63-
{ value: 'noindex, follow' },
64-
{ value: 'noindex, nofollow' },
65-
]
66-
},
67-
{
68-
name: 'googlebot', type: 'select', description: 'Controls how search engines index and display content, influencing webpage visibility and accessibility in search results.', label: 'Googlebot', options: [
69-
{ value: 'index, follow' },
70-
{ value: 'index, nofollow' },
71-
{ value: 'noindex, follow' },
72-
{ value: 'noindex, nofollow' },
73-
]
74-
},
75-
{ name: 'sitemap', type: 'text', description: '', label: 'URL site map' },
76-
{ name: 'locale', type: 'text', description: 'Defines the language and region of a webpage, aiding in content and regional settings adaptation.', label: 'Locale' },
77-
{ name: 'site', type: 'text', description: 'The Twitter “@username” the card should be attributed to.', label: 'Site' },
78-
];
79-
80-
code? = returnCode(null);
81-
82-
form: FormGroup;
83-
84-
constructor(private fb: FormBuilder) {
85-
this.form = this.fb.group({});
86-
this.metatagsList.forEach(field => {
87-
if (field.type === 'select' && field.options) {
88-
this.form.addControl(field.name, this.fb.control(field.options[0].value));
89-
} else if (field.name === 'viewport') {
90-
this.form.addControl(field.name, this.fb.control('width=device-width, initial-scale=1'));
91-
} else {
92-
this.form.addControl(field.name, this.fb.control(''));
93-
}
94-
});
95-
96-
this.onChanges();
97-
}
98-
99-
onChanges(): void {
100-
this.form.valueChanges.subscribe(_val => {
101-
console.log('this.form.value', this.form.value);
102-
this.code = returnCode(this.form.value);
103-
});
104-
}
105-
106-
setFetchValue(data: any) {
107-
this.form.patchValue({
108-
charset: data.charset ?? '',
109-
viewport: data.viewport ?? '',
110-
name: data.name ?? '',
111-
title: data.title ?? '',
112-
description: data.description ?? '',
113-
canonical: data.canonicalURL ?? '',
114-
image: data.imageURL ?? '',
115-
imageAlt: data.imageAltText ?? '',
116-
favicon: data.favicon ?? '',
117-
color: data.themeColor ?? '',
118-
author: data.pageAuthor ?? '',
119-
robots: data.robots ?? '',
120-
googlebot: data.googlebot ?? '',
121-
sitemap: data.sitemap ?? '',
122-
locale: data.locale ?? '',
123-
site: data.pageSite ?? '',
124-
});
125-
}
126-
127-
changeColor(value: any) {
128-
this.form.patchValue({
129-
color: value.target.value
130-
})
131-
}
13210
}

src/app/app.module.ts

+8-15
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@ import { NgModule } from '@angular/core';
22
import { provideHttpClient } from '@angular/common/http';
33
import { BrowserModule } from '@angular/platform-browser';
44
import { AppComponent } from './app.component';
5-
import { HighlightModule, HIGHLIGHT_OPTIONS } from 'ngx-highlightjs';
65
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
76
import { GithubButtonModule } from 'ng-github-button';
87
import { CodeResultComponent } from "./components/code-result/code-result.component";
98
import { PreviewComponent } from './components/preview/preview.component';
109
import { MenuComponent } from './components/menu/menu.component';
1110
import { FooterComponent } from './components/footer/footer.component';
1211
import { LoadingComponent } from './components/loading/loading.component';
12+
import { HomeComponent } from './pages/home/home.component';
13+
import { CreateComponent } from './pages/create/create.component';
14+
import { AppRoutingModule } from './app-routing.module';
1315

1416
@NgModule({
1517
declarations: [
@@ -18,28 +20,19 @@ import { LoadingComponent } from './components/loading/loading.component';
1820
PreviewComponent,
1921
MenuComponent,
2022
FooterComponent,
21-
LoadingComponent
23+
LoadingComponent,
24+
HomeComponent,
25+
CreateComponent
2226
],
2327
imports: [
2428
BrowserModule,
29+
AppRoutingModule,
2530
FormsModule,
26-
HighlightModule,
2731
ReactiveFormsModule,
2832
GithubButtonModule,
2933
],
3034
providers: [
31-
provideHttpClient(),
32-
{
33-
provide: HIGHLIGHT_OPTIONS,
34-
useValue: {
35-
coreLibraryLoader: () => import('highlight.js/lib/core'),
36-
languages: {
37-
xml: () => import('highlight.js/lib/languages/xml'),
38-
javascript: () => import('highlight.js/lib/languages/javascript'),
39-
typescript: () => import('highlight.js/lib/languages/typescript'),
40-
}
41-
}
42-
}
35+
provideHttpClient()
4336
],
4437
bootstrap: [AppComponent]
4538
})
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
<div class="relative h-full">
2-
<div class="absolute top-2 right-2 md:right-6 flex justify-center items-center z-10">
2+
<div
3+
class="absolute top-2 right-2 md:right-6 flex justify-center items-center z-10"
4+
>
35
<button
46
(click)="copy()"
5-
class="h-6 bg-zinc-800 hover:bg-zinc-700 text-white hover:text-zinc-50 rounded text-xs px-2 py-2 flex justify-center items-center">
7+
class="h-6 bg-zinc-800 hover:bg-zinc-700 text-white hover:text-zinc-50 rounded text-xs px-2 py-2 flex justify-center items-center"
8+
>
69
Copy
710
</button>
811
</div>
912
<pre class="w-full h-full appearance-none !m-0 !p-0 flex relative">
10-
<code class="w-full h-full appearance-none !m-0 !p-4 !bg-zinc-900 md:!bg-zinc-950 rounded md:rounded-none text-xs overflow-x-auto overflow-y-auto md:overflow-y-scroll" [highlight]="code" [language]="'html'"></code>
13+
<code class="w-full h-full appearance-none !m-0 !p-4 !bg-zinc-900 md:!bg-zinc-950 rounded md:rounded-none text-xs overflow-x-auto overflow-y-auto md:overflow-y-scroll">
14+
{{code}}
15+
</code>
1116
</pre>
12-
1317
</div>

src/app/components/footer/footer.component.html

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
<div
2-
class="hidden md:flex text-left w-full py-4 px-4 md:px-10 border-t border-zinc-800 sticky top-full"
2+
class="flex text-left w-full max-w-screen-sm md:max-w-screen-md lg:max-w-screen-lg xl:max-w-screen-xl mx-auto p-8 md:px-10 border-t border-zinc-800"
33
>
4-
<div class="text-zinc-400 md:text-xs leading-4">
5-
©2024 •
4+
<div class="text-zinc-400 text-center text-xs leading-4 w-full mx-auto">
5+
SeoTopper ©2024 •
66
<a
7-
href="https://github.com/gustavoquinalha"
7+
href="https://gustavoquinalha.github.io/"
88
target="_blank"
99
class="text-zinc-400 hover:text-white hover:underline underline-offset-1"
1010
>Gustavo Quinalha</a
@@ -14,7 +14,7 @@
1414
href="https://github.com/userjapa"
1515
target="_blank"
1616
class="text-zinc-400 hover:text-white hover:underline underline-offset-1"
17-
>Japa</a
17+
>UserJapa</a
1818
>
1919
— All rights reserved.
2020
</div>

0 commit comments

Comments
 (0)