Merge pull request #11 from bdfin/hide-contact-form-on-submit
Replace contact form with alert on submission
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
<div class="p-4">
|
||||
<div class="border-0 px-8 py-6 bg-black shadow ring-1 ring-inset ring-gray-300">
|
||||
<div class="flex">
|
||||
<div class="flex-shrink-0">
|
||||
@if (Type == AlertType.Success)
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
<p class="pt-4 pb-2">The contact API endpoint currently:</p>
|
||||
<ul class="list-disc pl-8 pb-4">
|
||||
<li>Validates a <Anchor Href="https://www.google.com/recaptcha/about/">Google Recaptcha</Anchor> token to protect against fraudulent submissions.</li>
|
||||
<li>Validates a <Anchor Href="https://www.google.com/recaptcha/about/">Google reCAPTCHA</Anchor> token to protect against fraudulent submissions.</li>
|
||||
<li>Builds a HTML email from the information provided in the form.</li>
|
||||
<li>Sends an email directly to my inbox using the <Anchor Href="https://sendgrid.com/en-us">SendGrid</Anchor> API.</li>
|
||||
</ul>
|
||||
|
||||
@@ -7,54 +7,56 @@
|
||||
|
||||
<div class="text-center">
|
||||
<h1 class="text-4xl">Contact</h1>
|
||||
|
||||
|
||||
<p class="text-lg mt-8">
|
||||
If you think I can help with your project or you'd just like to talk tech, send me a message!
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="mx-auto max-w-xl pt-8 pb-4">
|
||||
<EditForm Model="contactInput" OnValidSubmit="HandleValidSubmit">
|
||||
<DataAnnotationsValidator/>
|
||||
|
||||
<div class="grid grid-cols-1 gap-x-8 gap-y-6 sm:grid-cols-2">
|
||||
<div class="sm:col-span-2">
|
||||
<label for="name" class="block font-semibold leading-6">Name</label>
|
||||
<div class="mt-2.5">
|
||||
<InputText id="name" @bind-Value="contactInput.Name" class="block w-full text-lg border-0 px-3.5 py-2 bg-black shadow ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-gray-600" autocomplete="given-name"/>
|
||||
<ValidationMessage For="() => contactInput.Name" class="text-red-600"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sm:col-span-2">
|
||||
<label for="email" class="block font-semibold leading-6">Email</label>
|
||||
<div class="mt-2.5">
|
||||
<InputText id="email" @bind-Value="contactInput.Email" class="block w-full text-lg border-0 px-3.5 py-2 bg-black shadow ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-gray-600" autocomplete="email"/>
|
||||
<ValidationMessage For="() => contactInput.Email" class="text-red-600"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sm:col-span-2">
|
||||
<label for="message" class="block font-semibold leading-6">Message</label>
|
||||
<div class="mt-2.5">
|
||||
<InputTextArea id="message" @bind-Value="contactInput.Message" rows="4" class="block w-full text-lg border-0 px-3.5 py-2 bg-black shadow ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-gray-600"/>
|
||||
<ValidationMessage For="() => contactInput.Message" class="text-red-600"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<small>This site is protected by reCAPTCHA and the Google <Anchor Href="https://policies.google.com/privacy" Target="_blank">Privacy Policy</Anchor> and <Anchor Href="https://policies.google.com/terms" Target="_blank">Terms of Service</Anchor> apply.</small>
|
||||
</div>
|
||||
<div class="mt-4 flex items-center justify-center">
|
||||
<Button Type="submit" IsLoading="@isSubmitting">
|
||||
<i class="fa-solid fa-paper-plane"></i> Send
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
</EditForm>
|
||||
</div>
|
||||
|
||||
@if (isSubmitted)
|
||||
@if (!isSubmitted)
|
||||
{
|
||||
<div class="m-auto max-w-xl">
|
||||
<div class="mx-auto max-w-xl pt-8 pb-4">
|
||||
<EditForm Model="contactInput" OnValidSubmit="HandleValidSubmit">
|
||||
<DataAnnotationsValidator/>
|
||||
|
||||
<div class="grid grid-cols-1 gap-x-8 gap-y-6 sm:grid-cols-2">
|
||||
<div class="sm:col-span-2">
|
||||
<label for="name" class="block font-semibold leading-6">Name</label>
|
||||
<div class="mt-2.5">
|
||||
<InputText id="name" @bind-Value="contactInput.Name" class="block w-full text-lg border-0 px-3.5 py-2 bg-black shadow ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-gray-600" autocomplete="given-name"/>
|
||||
<ValidationMessage For="() => contactInput.Name" class="text-red-600"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sm:col-span-2">
|
||||
<label for="email" class="block font-semibold leading-6">Email</label>
|
||||
<div class="mt-2.5">
|
||||
<InputText id="email" @bind-Value="contactInput.Email" class="block w-full text-lg border-0 px-3.5 py-2 bg-black shadow ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-gray-600" autocomplete="email"/>
|
||||
<ValidationMessage For="() => contactInput.Email" class="text-red-600"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sm:col-span-2">
|
||||
<label for="message" class="block font-semibold leading-6">Message</label>
|
||||
<div class="mt-2.5">
|
||||
<InputTextArea id="message" @bind-Value="contactInput.Message" rows="4" class="block w-full text-lg border-0 px-3.5 py-2 bg-black shadow ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-gray-600"/>
|
||||
<ValidationMessage For="() => contactInput.Message" class="text-red-600"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<small>This site is protected by reCAPTCHA and the Google <Anchor Href="https://policies.google.com/privacy" Target="_blank">Privacy Policy</Anchor> and <Anchor Href="https://policies.google.com/terms" Target="_blank">Terms of Service</Anchor> apply.</small>
|
||||
</div>
|
||||
<div class="mt-4 flex items-center justify-center">
|
||||
<Button Type="submit" IsLoading="@isSubmitting">
|
||||
<i class="fa-solid fa-paper-plane"></i> Send
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
</EditForm>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="m-auto max-w-xl py-14">
|
||||
@if (sendEmailSuccess)
|
||||
{
|
||||
<Alert Type="AlertType.Success" Title="Email sent successfully">
|
||||
@@ -95,7 +97,7 @@
|
||||
private async Task HandleValidSubmit()
|
||||
{
|
||||
isSubmitting = true;
|
||||
|
||||
|
||||
var recaptchaResponse = await JSRuntime.InvokeAsync<string>("executeRecaptcha");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(recaptchaResponse))
|
||||
@@ -114,7 +116,7 @@
|
||||
|
||||
sendEmailSuccess = response.IsSuccessStatusCode;
|
||||
}
|
||||
|
||||
|
||||
isSubmitting = false;
|
||||
isSubmitted = true;
|
||||
}
|
||||
|
||||
1812
BeauFindlay/src/BeauFindlay.Client/package-lock.json
generated
Normal file
1812
BeauFindlay/src/BeauFindlay.Client/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
12
BeauFindlay/src/BeauFindlay.Client/package.json
Normal file
12
BeauFindlay/src/BeauFindlay.Client/package.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"autoprefixer": "^10.4.18",
|
||||
"postcss": "^8.4.35",
|
||||
"postcss-cli": "^11.0.0",
|
||||
"tailwindcss": "^3.4.1"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "echo Skipping build",
|
||||
"build:azure": "echo Skipping Azure-specific build"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
! tailwindcss v3.3.3 | MIT License | https://tailwindcss.com
|
||||
! tailwindcss v3.4.1 | MIT License | https://tailwindcss.com
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -32,9 +32,11 @@
|
||||
4. Use the user's configured `sans` font-family by default.
|
||||
5. Use the user's configured `sans` font-feature-settings by default.
|
||||
6. Use the user's configured `sans` font-variation-settings by default.
|
||||
7. Disable tap highlights on iOS
|
||||
*/
|
||||
|
||||
html {
|
||||
html,
|
||||
:host {
|
||||
line-height: 1.5;
|
||||
/* 1 */
|
||||
-webkit-text-size-adjust: 100%;
|
||||
@@ -44,12 +46,14 @@ html {
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
/* 3 */
|
||||
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
/* 4 */
|
||||
font-feature-settings: normal;
|
||||
/* 5 */
|
||||
font-variation-settings: normal;
|
||||
/* 6 */
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
/* 7 */
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -121,8 +125,10 @@ strong {
|
||||
}
|
||||
|
||||
/*
|
||||
1. Use the user's configured `mono` font family by default.
|
||||
2. Correct the odd `em` font sizing in all browsers.
|
||||
1. Use the user's configured `mono` font-family by default.
|
||||
2. Use the user's configured `mono` font-feature-settings by default.
|
||||
3. Use the user's configured `mono` font-variation-settings by default.
|
||||
4. Correct the odd `em` font sizing in all browsers.
|
||||
*/
|
||||
|
||||
code,
|
||||
@@ -131,8 +137,12 @@ samp,
|
||||
pre {
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
/* 1 */
|
||||
font-size: 1em;
|
||||
font-feature-settings: normal;
|
||||
/* 2 */
|
||||
font-variation-settings: normal;
|
||||
/* 3 */
|
||||
font-size: 1em;
|
||||
/* 4 */
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -563,10 +573,6 @@ video {
|
||||
margin-left: 0.75rem;
|
||||
}
|
||||
|
||||
.mt-16 {
|
||||
margin-top: 4rem;
|
||||
}
|
||||
|
||||
.mt-2 {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
@@ -623,10 +629,6 @@ video {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.h-7 {
|
||||
height: 1.75rem;
|
||||
}
|
||||
|
||||
.min-h-screen {
|
||||
min-height: 100vh;
|
||||
}
|
||||
@@ -801,11 +803,26 @@ video {
|
||||
padding-bottom: 2rem;
|
||||
}
|
||||
|
||||
.px-6 {
|
||||
padding-left: 1.5rem;
|
||||
padding-right: 1.5rem;
|
||||
}
|
||||
|
||||
.px-8 {
|
||||
padding-left: 2rem;
|
||||
padding-right: 2rem;
|
||||
}
|
||||
|
||||
.py-6 {
|
||||
padding-top: 1.5rem;
|
||||
padding-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.py-14 {
|
||||
padding-top: 3.5rem;
|
||||
padding-bottom: 3.5rem;
|
||||
}
|
||||
|
||||
.pb-2 {
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
@@ -822,6 +839,10 @@ video {
|
||||
padding-left: 2rem;
|
||||
}
|
||||
|
||||
.pt-16 {
|
||||
padding-top: 4rem;
|
||||
}
|
||||
|
||||
.pt-4 {
|
||||
padding-top: 1rem;
|
||||
}
|
||||
@@ -830,10 +851,6 @@ video {
|
||||
padding-top: 2rem;
|
||||
}
|
||||
|
||||
.pt-16 {
|
||||
padding-top: 4rem;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
@@ -1080,17 +1097,6 @@ body::-webkit-scrollbar-thumb {
|
||||
background-color: rgb(31 41 55 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.dark\:fill-gray-300 {
|
||||
fill: #d1d5db;
|
||||
}
|
||||
|
||||
.dark\:text-gray-600 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(75 85 99 / var(--tw-text-opacity));
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.sm\:col-span-2 {
|
||||
grid-column: span 2 / span 2;
|
||||
@@ -1135,10 +1141,6 @@ body::-webkit-scrollbar-thumb {
|
||||
padding-top: 3rem;
|
||||
padding-bottom: 3rem;
|
||||
}
|
||||
|
||||
.md\:text-left {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
@@ -1153,4 +1155,15 @@ body::-webkit-scrollbar-thumb {
|
||||
padding-left: 8rem;
|
||||
padding-right: 8rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.dark\:fill-gray-300 {
|
||||
fill: #d1d5db;
|
||||
}
|
||||
|
||||
.dark\:text-gray-600 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(75 85 99 / var(--tw-text-opacity));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user