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">
|
||||||
<div class="flex-shrink-0">
|
<div class="flex-shrink-0">
|
||||||
@if (Type == AlertType.Success)
|
@if (Type == AlertType.Success)
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
<p class="pt-4 pb-2">The contact API endpoint currently:</p>
|
<p class="pt-4 pb-2">The contact API endpoint currently:</p>
|
||||||
<ul class="list-disc pl-8 pb-4">
|
<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>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>
|
<li>Sends an email directly to my inbox using the <Anchor Href="https://sendgrid.com/en-us">SendGrid</Anchor> API.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -13,48 +13,50 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mx-auto max-w-xl pt-8 pb-4">
|
@if (!isSubmitted)
|
||||||
<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)
|
|
||||||
{
|
{
|
||||||
<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)
|
@if (sendEmailSuccess)
|
||||||
{
|
{
|
||||||
<Alert Type="AlertType.Success" Title="Email sent successfully">
|
<Alert Type="AlertType.Success" Title="Email sent successfully">
|
||||||
|
|||||||
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.
|
4. Use the user's configured `sans` font-family by default.
|
||||||
5. Use the user's configured `sans` font-feature-settings 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.
|
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;
|
line-height: 1.5;
|
||||||
/* 1 */
|
/* 1 */
|
||||||
-webkit-text-size-adjust: 100%;
|
-webkit-text-size-adjust: 100%;
|
||||||
@@ -44,12 +46,14 @@ html {
|
|||||||
-o-tab-size: 4;
|
-o-tab-size: 4;
|
||||||
tab-size: 4;
|
tab-size: 4;
|
||||||
/* 3 */
|
/* 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 */
|
/* 4 */
|
||||||
font-feature-settings: normal;
|
font-feature-settings: normal;
|
||||||
/* 5 */
|
/* 5 */
|
||||||
font-variation-settings: normal;
|
font-variation-settings: normal;
|
||||||
/* 6 */
|
/* 6 */
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
|
/* 7 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -121,8 +125,10 @@ strong {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
1. Use the user's configured `mono` font family by default.
|
1. Use the user's configured `mono` font-family by default.
|
||||||
2. Correct the odd `em` font sizing in all browsers.
|
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,
|
code,
|
||||||
@@ -131,8 +137,12 @@ samp,
|
|||||||
pre {
|
pre {
|
||||||
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||||
/* 1 */
|
/* 1 */
|
||||||
font-size: 1em;
|
font-feature-settings: normal;
|
||||||
/* 2 */
|
/* 2 */
|
||||||
|
font-variation-settings: normal;
|
||||||
|
/* 3 */
|
||||||
|
font-size: 1em;
|
||||||
|
/* 4 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -563,10 +573,6 @@ video {
|
|||||||
margin-left: 0.75rem;
|
margin-left: 0.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mt-16 {
|
|
||||||
margin-top: 4rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mt-2 {
|
.mt-2 {
|
||||||
margin-top: 0.5rem;
|
margin-top: 0.5rem;
|
||||||
}
|
}
|
||||||
@@ -623,10 +629,6 @@ video {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.h-7 {
|
|
||||||
height: 1.75rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.min-h-screen {
|
.min-h-screen {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
}
|
}
|
||||||
@@ -801,11 +803,26 @@ video {
|
|||||||
padding-bottom: 2rem;
|
padding-bottom: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.px-6 {
|
||||||
|
padding-left: 1.5rem;
|
||||||
|
padding-right: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.px-8 {
|
||||||
|
padding-left: 2rem;
|
||||||
|
padding-right: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
.py-6 {
|
.py-6 {
|
||||||
padding-top: 1.5rem;
|
padding-top: 1.5rem;
|
||||||
padding-bottom: 1.5rem;
|
padding-bottom: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.py-14 {
|
||||||
|
padding-top: 3.5rem;
|
||||||
|
padding-bottom: 3.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
.pb-2 {
|
.pb-2 {
|
||||||
padding-bottom: 0.5rem;
|
padding-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
@@ -822,6 +839,10 @@ video {
|
|||||||
padding-left: 2rem;
|
padding-left: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pt-16 {
|
||||||
|
padding-top: 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
.pt-4 {
|
.pt-4 {
|
||||||
padding-top: 1rem;
|
padding-top: 1rem;
|
||||||
}
|
}
|
||||||
@@ -830,10 +851,6 @@ video {
|
|||||||
padding-top: 2rem;
|
padding-top: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pt-16 {
|
|
||||||
padding-top: 4rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-center {
|
.text-center {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
@@ -1080,17 +1097,6 @@ body::-webkit-scrollbar-thumb {
|
|||||||
background-color: rgb(31 41 55 / var(--tw-bg-opacity));
|
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) {
|
@media (min-width: 640px) {
|
||||||
.sm\:col-span-2 {
|
.sm\:col-span-2 {
|
||||||
grid-column: span 2 / span 2;
|
grid-column: span 2 / span 2;
|
||||||
@@ -1135,10 +1141,6 @@ body::-webkit-scrollbar-thumb {
|
|||||||
padding-top: 3rem;
|
padding-top: 3rem;
|
||||||
padding-bottom: 3rem;
|
padding-bottom: 3rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.md\:text-left {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 1024px) {
|
@media (min-width: 1024px) {
|
||||||
@@ -1154,3 +1156,14 @@ body::-webkit-scrollbar-thumb {
|
|||||||
padding-right: 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