Created
December 5, 2020 23:21
-
-
Save daugaard47/d462eccc2891afb0895ae2bb86f50ba3 to your computer and use it in GitHub Desktop.
Honey Livewire
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div> | |
@section('title', 'Contact Us') | |
<div class="relative bg-white"> | |
<div class="lg:absolute lg:inset-0"> | |
<div class="lg:absolute lg:inset-y-0 lg:right-0 lg:w-1/2"> | |
<img class="h-98 w-full object-cover lg:absolute lg:h-full" | |
src="https://www.incimages.com/uploaded_files/image/1920x1080/getty_962467272_361075.jpg" | |
alt=""/> | |
</div> | |
</div> | |
<div class="relative pt-12 pb-16 px-4 sm:pt-16 sm:px-6 lg:px-8 lg:max-w-7xl lg:mx-auto lg:grid lg:grid-cols-2"> | |
<div class="lg:pr-8"> | |
<div class="max-w-md mx-auto sm:max-w-lg lg:mx-0"> | |
<h2 class="text-3xl leading-9 font-extrabold tracking-tight sm:text-4xl sm:leading-10"> | |
Let's work together | |
</h2> | |
<p class="mt-4 text-lg leading-7 text-gray-500 sm:mt-3"> | |
We’d love to hear from you! Send us a message using the form opposite, or email us. We’d love to | |
hear from you! Send us a message using the form opposite, or email us. | |
</p> | |
@if(Session::has('success')) | |
<!--Success Message Code Here--> | |
@endif | |
@if(Session::has('error')) | |
<!--Error Message Code Here--> | |
@endif | |
<form wire:submit.prevent="submitContactForm" | |
class="mt-9 grid grid-cols-1 gap-6 sm:grid-cols-2 sm:gap-8"> | |
<div> | |
<label for="first_name" class="block text-sm font-medium leading-5 text-gray-700"> | |
First name | |
</label> | |
<div class="mt-1 relative rounded-md shadow-sm"> | |
<x-jet-input wire:model.lazy="first_name" type="text" id="first_name" | |
class="block mt-1 w-full mb-4"/> | |
</div> | |
@error('first_name') | |
<p class="mt-2 text-sm text-red-500">{{ $message}}</p> | |
@enderror | |
</div> | |
<div> | |
<label for="last_name" class="block text-sm font-medium leading-5 text-gray-700"> | |
Last name | |
</label> | |
<div class="mt-1 relative rounded-md shadow-sm"> | |
<x-jet-input wire:model.lazy="last_name" type="text" id="last_name" | |
class="block mt-1 w-full mb-4"/> | |
</div> | |
@error('last_name') | |
<p class="mt-2 text-sm text-red-500">{{ $message}}</p> | |
@enderror | |
</div> | |
<div class="sm:col-span-2"> | |
<label for="email" class="block text-sm font-medium leading-5 text-gray-700"> | |
</label> | |
<div class="mt-1 relative rounded-md shadow-sm"> | |
<x-jet-input wire:model.lazy="email" type="email" id="email" | |
class="block mt-1 w-full mb-4"/> | |
</div> | |
@error('email') | |
<p class="mt-2 text-sm text-red-500">{{ $message}}</p> | |
@enderror | |
</div> | |
<div class="sm:col-span-2"> | |
<div class="flex justify-between"> | |
<label for="phone" | |
class="block text-sm font-medium leading-5 text-gray-700"> | |
Phone | |
</label> | |
<span class="text-sm leading-5 text-gray-500">Optional</span> | |
</div> | |
<div class="mt-1 relative rounded-md shadow-sm"> | |
<x-jet-input wire:model.lazy="phone" type="text" id="phone" | |
class="block mt-1 w-full mb-4"/> | |
</div> | |
@error('phone') | |
<p class="mt-2 text-sm text-red-500">{{ $message}}</p> | |
@enderror | |
</div> | |
<div class="sm:col-span-2"> | |
<div class="flex justify-between"> | |
<label for="message" class="block text-sm font-medium leading-5 text-gray-700"> | |
How can we help you? | |
</label> | |
<span class="text-sm leading-5 text-gray-500">Max. 500 characters</span> | |
</div> | |
<div class="mt-1 relative rounded-md shadow-sm"> | |
<textarea wire:model.lazy="form_message" rows="4" id="form_message" | |
class="block mt-1 w-full mb-4 focus:ring-cc-orange-200 focus:border-cc-orange-200 sm:text-sm border-gray-300 shadow-sm rounded-md"></textarea> | |
</div> | |
@error('form_message') | |
<p class="mt-2 text-sm text-red-500">{{ $message}}</p> | |
@enderror | |
</div> | |
<div class="sm:col-span-2"> | |
<label for="referred_by" class="block text-sm font-medium leading-5 text-gray-700"> | |
How did you hear about us? | |
</label> | |
<div class="mt-1 relative rounded-md shadow-sm"> | |
<x-jet-input wire:model.lazy="referred_by" type="text" id="referred_by" | |
class="block mt-1 w-full mb-4"/> | |
</div> | |
@error('referred_by') | |
<p class="mt-2 text-sm text-red-500">{{ $message}}</p> | |
@enderror | |
</div> | |
<!-- HONEYPOT START--> | |
<x-honey/> | |
<x-honey-recaptcha/> | |
{{--<x-honey recaptcha="contact_form"/>--}} | |
<!--HONEYPOT END--> | |
<div class="text-right sm:col-span-2"> | |
<span class="inline-flex rounded-md shadow-sm"> | |
<button type="submit" wire:target="submitContactForm" wire:loading.attr="disabled" | |
wire:loading.class="bg-orange-400 cursor-wait" | |
wire:loading.class.remove="bg-orange-600 hover:bg-orange-500" | |
class="inline-flex items-center justify-center py-2 px-3 border border-transparent text-sm leading-5 font-medium rounded-md text-white bg-orange-600 hover:bg-orange-500 focus:outline-none focus:border-orange-700 focus:ring-orange active:bg-orange-700 transition duration-150 ease-in-out"> | |
<svg wire:target="submitContactForm" wire:loading | |
class="w-4 h-4 mr-2 stroke-current text-orange-100" | |
viewBox="0 0 44 44" xmlns="http://www.w3.org/2000/svg" stroke="#fff"> | |
<g fill="none" fill-rule="evenodd" stroke-width="2"> | |
<circle cx="22" cy="22" r="1"> | |
<animate attributeName="r" | |
begin="0s" dur="1.8s" | |
values="1; 20" | |
calcMode="spline" | |
keyTimes="0; 1" | |
keySplines="0.165, 0.84, 0.44, 1" | |
repeatCount="indefinite"/> | |
<animate attributeName="stroke-opacity" | |
begin="0s" dur="1.8s" | |
values="1; 0" | |
calcMode="spline" | |
keyTimes="0; 1" | |
keySplines="0.3, 0.61, 0.355, 1" | |
repeatCount="indefinite"/> | |
</circle> | |
<circle cx="22" cy="22" r="1"> | |
<animate attributeName="r" | |
begin="-0.9s" dur="1.8s" | |
values="1; 20" | |
calcMode="spline" | |
keyTimes="0; 1" | |
keySplines="0.165, 0.84, 0.44, 1" | |
repeatCount="indefinite"/> | |
<animate attributeName="stroke-opacity" | |
begin="-0.9s" dur="1.8s" | |
values="1; 0" | |
calcMode="spline" | |
keyTimes="0; 1" | |
keySplines="0.3, 0.61, 0.355, 1" | |
repeatCount="indefinite"/> | |
</circle> | |
</g> | |
</svg> | |
Submit | |
</button> | |
</span> | |
</div> | |
</form> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Http\Livewire\Contact; | |
use Livewire\Component; | |
use Lukeraymonddowning\Honey\Traits\WithHoney; | |
use Lukeraymonddowning\Honey\Traits\WithRecaptcha; | |
class ContactForm extends Component | |
{ | |
use WithHoney; | |
use WithRecaptcha; | |
public $first_name; | |
public $last_name; | |
public $email; | |
public $phone; | |
public $form_message; | |
public $referred_by; | |
public $message; | |
public function render() | |
{ | |
return view('livewire.contact.contact-form'); | |
} | |
public function submitContactForm() | |
{ | |
$data = $this->validate([ | |
'first_name' => 'required', | |
'last_name' => 'required', | |
'email' => 'required|email', | |
'phone' => 'nullable|min:7|max:15', | |
'form_message' => 'required|min:5|max:500', | |
'referred_by' => 'nullable|min:2|max:50' | |
]); | |
if ($this->recaptchaPasses() == true && $this->honeyPasses() == true) { | |
session()->flash('success', 'Form submitted!'); | |
// dd('pass'); | |
$this->reset(['first_name','last_name','email','phone','form_message','referred_by']); | |
} else { | |
session()->flash('error', 'Form not submitted!'); | |
// dd('fail'); | |
$this->reset(['first_name','last_name','email','phone','form_message','referred_by']); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Lukeraymonddowning\Honey\Checks\AlpineInputFilledCheck; | |
use Lukeraymonddowning\Honey\Checks\MinimumTimePassedCheck; | |
use Lukeraymonddowning\Honey\Checks\PresentButEmptyCheck; | |
use Lukeraymonddowning\Honey\Checks\UserIsBlockedSpammerCheck; | |
use Lukeraymonddowning\Honey\Features; | |
use Lukeraymonddowning\Honey\InputNameSelectors\StaticInputNameSelector; | |
return [ | |
/** | |
* -------------------------------------------------------------------------- | |
* Features | |
* -------------------------------------------------------------------------- | |
* | |
* Here you can enable or disable different features that Honey provides. | |
* You should read the documentation for a more detailed look at each | |
* feature offered and the steps required to get it set up. | |
*/ | |
'features' => [ | |
Features::spammerIpTracking(), | |
Features::blockSpammersGlobally(), | |
// Features::neverGonnaGiveYouUp(), | |
], | |
/** | |
* -------------------------------------------------------------------------- | |
* Environments | |
* -------------------------------------------------------------------------- | |
* | |
* You probably don't want to run Honey all the time, especially in tests and such. | |
* Here you can select the specific environments that Honey should run in. We've | |
* enabled `local` for you to test, but you might want to comment it out for | |
* day to day use. | |
*/ | |
'environments' => [ | |
'production', | |
'local' | |
], | |
/** | |
* -------------------------------------------------------------------------- | |
* Checks | |
* -------------------------------------------------------------------------- | |
* | |
* These checks will be performed as part of the honey spam test. If one of | |
* them returns false, the request is regarded as being spam and should | |
* be ignored. You can disabled anything you don't need. | |
* | |
* @see \Lukeraymonddowning\Honey\Checks\Check | |
*/ | |
'checks' => [ | |
UserIsBlockedSpammerCheck::class, | |
PresentButEmptyCheck::class, | |
MinimumTimePassedCheck::class, | |
AlpineInputFilledCheck::class, | |
], | |
/** | |
* -------------------------------------------------------------------------- | |
* Minimum time passed | |
* -------------------------------------------------------------------------- | |
* | |
* Here you can alter how long, in seconds, must have passed between | |
* a form loading and the request coming back in if you have either | |
* `MinimumTimePassedCheck` or `AlpineInputFilledCheck` enabled. | |
*/ | |
'minimum_time_passed' => 3, | |
/** | |
* -------------------------------------------------------------------------- | |
* Spammer blocking | |
* -------------------------------------------------------------------------- | |
* | |
* If you have the 'spammerIpTracking' feature enabled, Honey | |
* will automatically track and block repeat spammers from | |
* your application. You must have a db connection. | |
*/ | |
'spammer_blocking' => [ | |
/** | |
* The db table name that should be used to track spammers | |
*/ | |
'table_name' => 'spammers', | |
/** | |
* The number of times a request from an ip address can be classed | |
* as spam before they are added to the block list. | |
*/ | |
'maximum_attempts' => 5 | |
], | |
/** | |
* -------------------------------------------------------------------------- | |
* Input name selectors | |
* -------------------------------------------------------------------------- | |
* | |
* The input names, ids and, when using the Livewire stack, | |
* model bindings, are decided on by the driver selected | |
* here. | |
*/ | |
'input_name_selectors' => [ | |
'default' => 'static', | |
'drivers' => [ | |
/** | |
* The static driver uses the defined input names. | |
* As the name implies, the values don't change. | |
*/ | |
'static' => [ | |
'class' => StaticInputNameSelector::class, | |
'names' => [ | |
'present_but_empty' => 'honey_present', | |
'time_of_page_load' => 'honey_time', | |
'alpine_input' => 'honey_alpine', | |
'recaptcha_input' => 'honey_recaptcha_token' | |
] | |
], | |
] | |
], | |
/** | |
* -------------------------------------------------------------------------- | |
* Input values | |
* -------------------------------------------------------------------------- | |
* | |
* The honeypot inputs in Honey can be configured to provide | |
* different values. Not all inputs support this feature. | |
*/ | |
'input_values' => [ | |
'alpine' => Lukeraymonddowning\Honey\InputValues\AlpineInputValue::class, | |
'time_of_page_load' => Lukeraymonddowning\Honey\InputValues\TimeOfPageLoadValue::class, | |
], | |
/** | |
* -------------------------------------------------------------------------- | |
* Recaptcha | |
* -------------------------------------------------------------------------- | |
* | |
* If you decide to use Honey's Google Recaptcha integration, you | |
* can configure it by editing the values here or in your .env | |
* file. | |
*/ | |
'recaptcha' => [ | |
'site_key' => env("RECAPTCHA_SITE_KEY"), | |
'secret_key' => env("RECAPTCHA_SECRET_KEY"), | |
/** | |
* Recaptcha returns a score between 0 and 1 when checking a | |
* token. 0 is most definitely a bot, 1 is definitely a | |
* user. This informs the recaptcha middleware of | |
* minimum score a user can get to pass. | |
*/ | |
'minimum_score' => env("RECAPTCHA_MINIMUM_SCORE", 0.5), | |
/** | |
* The Recaptcha input will request a token on page load. As | |
* Recaptcha tokens only last for 2 minutes, the input | |
* refreshes based on this timeout (in milliseconds). | |
*/ | |
'token_refresh_interval' => 60000, | |
] | |
]; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment