Skip to content

Commit

Permalink
add home screen
Browse files Browse the repository at this point in the history
  • Loading branch information
gustavoquinalha committed Jul 17, 2024
1 parent f21eebe commit cf25290
Show file tree
Hide file tree
Showing 22 changed files with 655 additions and 305 deletions.
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 0 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,7 @@
"@angular/platform-browser": "^17.3.11",
"@angular/platform-browser-dynamic": "^17.3.11",
"@angular/router": "^17.3.11",
"highlight.js": "^11.9.0",
"ng-github-button": "^18.0.0",
"ngx-highlight-js": "^18.0.0",
"ngx-highlightjs": "^12.0.0",
"rxjs": "~7.5.0",
"tslib": "^2.3.0",
"zone.js": "~0.14.7"
Expand All @@ -30,7 +27,6 @@
"@angular-devkit/build-angular": "^17.3.8",
"@angular/cli": "~17.3.8",
"@angular/compiler-cli": "^17.3.11",
"@types/highlight.js": "^10.1.0",
"@types/jasmine": "~4.3.0",
"@types/json-schema": "^7.0.15",
"autoprefixer": "^10.4.19",
Expand Down
16 changes: 16 additions & 0 deletions src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './pages/home/home.component';
import { CreateComponent } from './pages/create/create.component';

const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'create/:urlName', component: CreateComponent },
{ path: '**', redirectTo: '/' }
];

@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
100 changes: 1 addition & 99 deletions src/app/app.component.html
Original file line number Diff line number Diff line change
@@ -1,99 +1 @@
<app-menu (onFetchValue)="setFetchValue($event)" />

<div class="w-full flex flex-col md:flex-row bg-zinc-950">
<div
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"
>
<form [formGroup]="form" class="p-4 md:p-8 w-full">
<div class="w-full max-w-xs text-center mx-auto">
<h1 class="mb-4 md:mb-8 text-sm leading-4 text-white">
Just type the data and generate the meta tags for your website
</h1>
</div>
<div class="w-full grid grid-cols-1 flex-col gap-8">
<div
class="relative flex flex-col gap-1"
*ngFor="let field of metatagsList"
>
<ng-container *ngIf="field.type === 'text' || field.type === 'color'">
<label [for]="field.name" class="leading-4 text-xs text-white">{{
field.label
}}</label>

<div
*ngIf="field.name === 'image' && form?.get('image')"
class="w-full aspect-[1.91/1] rounded bg-zinc-800 border border-zinc-800 overflow-hidden max-w-64"
>
<img *ngIf="form?.get('image')?.value" [src]="form.get('image')?.value" class="aspect-[1.91/1] max-w-64" width="100%" alt="" />
</div>

<div class="relative w-full">
<input
[type]="field.type"
[id]="field.name"
[name]="field.name"
[placeholder]="field.label"
[formControlName]="field.name"
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"
/>
<ng-container class="" *ngIf="field.name === 'color'">
<input
type="color"
[id]="field.name"
[name]="field.name"
[placeholder]="field.label"
[formControlName]="field.name"
(change)="changeColor($event)"
class="appearance-none w-6 min-w-6 h-6 rounded overflow-hidden absolute bottom-1 right-1 bg-transparent"
/>
</ng-container>
<ng-container class="" *ngIf="field.name === 'favicon'">
<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">
<img *ngIf="form?.get('favicon')?.value" [src]="form.get('favicon')?.value" width="100%" alt="Favicon" class="w-5 min-w-5 h-5" />
</div>
</ng-container>
</div>
<span class="text-xs text-zinc-500 leading-4 mt-1">{{
field.description
}}</span>
</ng-container>

<ng-container *ngIf="field.type === 'select'">
<label [for]="field.name" class="leading-4 text-xs text-white">{{
field.label
}}</label>
<select
[id]="field.name"
[formControlName]="field.name"
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"
>
<option
*ngFor="let option of field.options"
[value]="option.value"
>
{{ option.value }}
</option>
</select>
<span class="text-xs text-zinc-500 leading-4 mt-1">{{
field.description
}}</span>
</ng-container>
</div>
</div>
</form>

<app-footer />
</div>

<div
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"
>
<app-code-result [code]="code" class="h-full" />
</div>

<div
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"
>
<app-preview [content]="form.value" />
</div>
</div>
<router-outlet></router-outlet>
122 changes: 0 additions & 122 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { Component } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { returnCode } from './utils/code';


@Component({
Expand All @@ -9,124 +7,4 @@ import { returnCode } from './utils/code';
styleUrls: ['./app.component.scss']
})
export class AppComponent {
metatagsList = [
{
name: 'charset', type: 'select', description: 'Specifies the character encoding for the HTML document, ensuring proper display of text.', label: 'Charset', options: [
{ value: "UTF-8", },
{ value: "ISO-8859-1", },
{ value: "ISO-8859-2", },
{ value: "ISO-8859-3", },
{ value: "ISO-8859-4", },
{ value: "ISO-8859-5", },
{ value: "ISO-8859-6", },
{ value: "ISO-8859-7", },
{ value: "ISO-8859-8", },
{ value: "ISO-8859-9", },
{ value: "ISO-8859-10", },
{ value: "ISO-8859-11", },
{ value: "ISO-8859-13", },
{ value: "ISO-8859-14", },
{ value: "ISO-8859-15", },
{ value: "ISO-8859-16", },
{ value: "Windows-1250", },
{ value: "Windows-1251", },
{ value: "Windows-1252", },
{ value: "Windows-1253", },
{ value: "Windows-1254", },
{ value: "Windows-1255", },
{ value: "Windows-1256", },
{ value: "Windows-1257", },
{ value: "Windows-1258", },
{ value: "KOI8-R", },
{ value: "KOI8-U", },
{ value: "GB18030", },
{ value: "Big5", },
{ value: "Shift_JIS", },
{ value: "EUC-JP", },
{ value: "EUC-KR", },
],
},
{ name: 'viewport', type: 'text', description: 'Controls the layout and scaling of a webpage on different devices, improving responsiveness and user experience.', label: 'Viewport' },
{ name: 'name', type: 'text', description: 'Defines the name of the page.', label: 'Site name' },
{ 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' },
{ 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' },
{ 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' },
{ 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' },
{ 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' },
{ name: 'favicon', type: 'text', description: 'Specifies the favicon, enhancing website recognition in browsers and bookmarks.', label: 'Favicon' },
{ 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' },
{ name: 'author', type: 'text', description: 'Specifies the author of the webpage, providing attribution for content creation and ownership.', label: 'Author' },
{
name: 'robots', type: 'select', description: 'Controls how search engines index and display content, influencing webpage visibility and accessibility in search results.', label: 'Robots', options: [
{ value: 'index, follow' },
{ value: 'index, nofollow' },
{ value: 'noindex, follow' },
{ value: 'noindex, nofollow' },
]
},
{
name: 'googlebot', type: 'select', description: 'Controls how search engines index and display content, influencing webpage visibility and accessibility in search results.', label: 'Googlebot', options: [
{ value: 'index, follow' },
{ value: 'index, nofollow' },
{ value: 'noindex, follow' },
{ value: 'noindex, nofollow' },
]
},
{ name: 'sitemap', type: 'text', description: '', label: 'URL site map' },
{ name: 'locale', type: 'text', description: 'Defines the language and region of a webpage, aiding in content and regional settings adaptation.', label: 'Locale' },
{ name: 'site', type: 'text', description: 'The Twitter “@username” the card should be attributed to.', label: 'Site' },
];

code? = returnCode(null);

form: FormGroup;

constructor(private fb: FormBuilder) {
this.form = this.fb.group({});
this.metatagsList.forEach(field => {
if (field.type === 'select' && field.options) {
this.form.addControl(field.name, this.fb.control(field.options[0].value));
} else if (field.name === 'viewport') {
this.form.addControl(field.name, this.fb.control('width=device-width, initial-scale=1'));
} else {
this.form.addControl(field.name, this.fb.control(''));
}
});

this.onChanges();
}

onChanges(): void {
this.form.valueChanges.subscribe(_val => {
console.log('this.form.value', this.form.value);
this.code = returnCode(this.form.value);
});
}

setFetchValue(data: any) {
this.form.patchValue({
charset: data.charset ?? '',
viewport: data.viewport ?? '',
name: data.name ?? '',
title: data.title ?? '',
description: data.description ?? '',
canonical: data.canonicalURL ?? '',
image: data.imageURL ?? '',
imageAlt: data.imageAltText ?? '',
favicon: data.favicon ?? '',
color: data.themeColor ?? '',
author: data.pageAuthor ?? '',
robots: data.robots ?? '',
googlebot: data.googlebot ?? '',
sitemap: data.sitemap ?? '',
locale: data.locale ?? '',
site: data.pageSite ?? '',
});
}

changeColor(value: any) {
this.form.patchValue({
color: value.target.value
})
}
}
23 changes: 8 additions & 15 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@ import { NgModule } from '@angular/core';
import { provideHttpClient } from '@angular/common/http';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { HighlightModule, HIGHLIGHT_OPTIONS } from 'ngx-highlightjs';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { GithubButtonModule } from 'ng-github-button';
import { CodeResultComponent } from "./components/code-result/code-result.component";
import { PreviewComponent } from './components/preview/preview.component';
import { MenuComponent } from './components/menu/menu.component';
import { FooterComponent } from './components/footer/footer.component';
import { LoadingComponent } from './components/loading/loading.component';
import { HomeComponent } from './pages/home/home.component';
import { CreateComponent } from './pages/create/create.component';
import { AppRoutingModule } from './app-routing.module';

@NgModule({
declarations: [
Expand All @@ -18,28 +20,19 @@ import { LoadingComponent } from './components/loading/loading.component';
PreviewComponent,
MenuComponent,
FooterComponent,
LoadingComponent
LoadingComponent,
HomeComponent,
CreateComponent
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule,
HighlightModule,
ReactiveFormsModule,
GithubButtonModule,
],
providers: [
provideHttpClient(),
{
provide: HIGHLIGHT_OPTIONS,
useValue: {
coreLibraryLoader: () => import('highlight.js/lib/core'),
languages: {
xml: () => import('highlight.js/lib/languages/xml'),
javascript: () => import('highlight.js/lib/languages/javascript'),
typescript: () => import('highlight.js/lib/languages/typescript'),
}
}
}
provideHttpClient()
],
bootstrap: [AppComponent]
})
Expand Down
12 changes: 8 additions & 4 deletions src/app/components/code-result/code-result.component.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
<div class="relative h-full">
<div class="absolute top-2 right-2 md:right-6 flex justify-center items-center z-10">
<div
class="absolute top-2 right-2 md:right-6 flex justify-center items-center z-10"
>
<button
(click)="copy()"
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">
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"
>
Copy
</button>
</div>
<pre class="w-full h-full appearance-none !m-0 !p-0 flex relative">
<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>
<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">
{{code}}
</code>
</pre>

</div>
10 changes: 5 additions & 5 deletions src/app/components/footer/footer.component.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<div
class="hidden md:flex text-left w-full py-4 px-4 md:px-10 border-t border-zinc-800 sticky top-full"
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"
>
<div class="text-zinc-400 md:text-xs leading-4">
©2024 •
<div class="text-zinc-400 text-center text-xs leading-4 w-full mx-auto">
SeoTopper ©2024 •
<a
href="https://github.com/gustavoquinalha"
href="https://gustavoquinalha.github.io/"
target="_blank"
class="text-zinc-400 hover:text-white hover:underline underline-offset-1"
>Gustavo Quinalha</a
Expand All @@ -14,7 +14,7 @@
href="https://github.com/userjapa"
target="_blank"
class="text-zinc-400 hover:text-white hover:underline underline-offset-1"
>Japa</a
>UserJapa</a
>
— All rights reserved.
</div>
Expand Down
Loading

0 comments on commit cf25290

Please sign in to comment.