mirror of
https://github.com/prurigro/hypothetical.git
synced 2024-11-21 23:52:31 -05:00
Implement contact form functionality
This commit is contained in:
parent
2fc22e6c9b
commit
392ffaf572
18 changed files with 304 additions and 47 deletions
|
@ -4,7 +4,7 @@ SITE_DESC=A website template
|
||||||
APP_ENV=local
|
APP_ENV=local
|
||||||
APP_DEBUG=true
|
APP_DEBUG=true
|
||||||
APP_KEY=random_string
|
APP_KEY=random_string
|
||||||
APP_URL=http://localhost
|
APP_URL=http://template.hypothetic.al
|
||||||
|
|
||||||
DB_HOST=localhost
|
DB_HOST=localhost
|
||||||
DB_DATABASE=hypothetical
|
DB_DATABASE=hypothetical
|
||||||
|
@ -17,9 +17,12 @@ CACHE_DRIVER=file
|
||||||
SESSION_DRIVER=file
|
SESSION_DRIVER=file
|
||||||
QUEUE_DRIVER=sync
|
QUEUE_DRIVER=sync
|
||||||
|
|
||||||
|
MAIL_SENDTO=null
|
||||||
|
|
||||||
MAIL_DRIVER=smtp
|
MAIL_DRIVER=smtp
|
||||||
MAIL_HOST=null
|
MAIL_HOST=null
|
||||||
MAIL_PORT=587
|
MAIL_PORT=587
|
||||||
|
MAIL_ADDRESS=null
|
||||||
MAIL_USERNAME=null
|
MAIL_USERNAME=null
|
||||||
MAIL_PASSWORD=null
|
MAIL_PASSWORD=null
|
||||||
MAIL_ENCRYPTION=null
|
MAIL_ENCRYPTION=tls
|
||||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -3,6 +3,5 @@
|
||||||
/bower_components
|
/bower_components
|
||||||
/public/build
|
/public/build
|
||||||
/public/css
|
/public/css
|
||||||
/public/fonts
|
|
||||||
/public/js
|
/public/js
|
||||||
.env
|
.env
|
||||||
|
|
39
app/Http/Controllers/ContactController.php
Normal file
39
app/Http/Controllers/ContactController.php
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
<?php namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Mail;
|
||||||
|
use App\Models\Contact;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class ContactController extends Controller
|
||||||
|
{
|
||||||
|
public function postContactSubmit(Request $request)
|
||||||
|
{
|
||||||
|
$this->validate($request, [
|
||||||
|
'name' => 'required',
|
||||||
|
'email' => 'required|email',
|
||||||
|
'message' => 'required'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$contact = new Contact;
|
||||||
|
|
||||||
|
$name = $request['name'];
|
||||||
|
$email = $request['email'];
|
||||||
|
$message = $request['message'];
|
||||||
|
|
||||||
|
$contact->name = $name;
|
||||||
|
$contact->email = $email;
|
||||||
|
$contact->message = $message;
|
||||||
|
$contact->save();
|
||||||
|
|
||||||
|
// Send the email if this is the production environment
|
||||||
|
if (env('MAIL_SENDTO') != null) {
|
||||||
|
Mail::send('email.contact', [ 'contact' => $contact ], function ($mail) use ($contact) {
|
||||||
|
$mail->from(env('MAIL_ADDRESS'), env('SITE_NAME'))
|
||||||
|
->to(env('MAIL_SENDTO'))
|
||||||
|
->subject('Contact form submission');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'success';
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,6 +10,12 @@ Route::get('/', function () {
|
||||||
return view('website.home');
|
return view('website.home');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Route::get('/contact', function() {
|
||||||
|
return view('website.contact');
|
||||||
|
});
|
||||||
|
|
||||||
|
Route::post('/contact-submit', 'ContactController@postContactSubmit');
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Content Management Routes
|
| Content Management Routes
|
||||||
|
|
11
app/Models/Contact.php
Normal file
11
app/Models/Contact.php
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class Contact extends Model
|
||||||
|
{
|
||||||
|
// the contact table
|
||||||
|
protected $table = 'contact';
|
||||||
|
}
|
33
database/migrations/2015_12_14_200624_add_contact_table.php
Normal file
33
database/migrations/2015_12_14_200624_add_contact_table.php
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class AddContactTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('contact', function(Blueprint $table) {
|
||||||
|
$table->increments('id');
|
||||||
|
$table->string('name');
|
||||||
|
$table->string('email');
|
||||||
|
$table->text('message');
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::drop('contact');
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,6 +18,7 @@ elixir.config.autoprefix = {
|
||||||
// javascript files in resources/assets/js/
|
// javascript files in resources/assets/js/
|
||||||
var jsLocal = [
|
var jsLocal = [
|
||||||
'site-vars.js',
|
'site-vars.js',
|
||||||
|
'contact.js',
|
||||||
'app.js'
|
'app.js'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -1 +1,6 @@
|
||||||
console.log('app.js has been run');
|
// run once the document is ready
|
||||||
|
$(document).ready(function() {
|
||||||
|
// initialize the contact form
|
||||||
|
if ($('#contact-form').length)
|
||||||
|
contactFormInit();
|
||||||
|
});
|
||||||
|
|
57
resources/assets/js/contact.js
Normal file
57
resources/assets/js/contact.js
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
// contact page functionality
|
||||||
|
function contactFormInit() {
|
||||||
|
var $form = $('#contact-form'),
|
||||||
|
$notify = $('#notification'),
|
||||||
|
contact = {},
|
||||||
|
submitting = false;
|
||||||
|
|
||||||
|
var getContactData = function() {
|
||||||
|
contact = {
|
||||||
|
name: $('#name').val(),
|
||||||
|
email: $('#email').val(),
|
||||||
|
message: $('#message').val(),
|
||||||
|
_token: $('#token').val()
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
$('#submit').on('click', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
if (!submitting) {
|
||||||
|
submitting = true;
|
||||||
|
getContactData();
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
url: '/contact-submit',
|
||||||
|
data: contact
|
||||||
|
}).always(function(response) {
|
||||||
|
$form.find('.error').removeClass('error');
|
||||||
|
$notify.removeClass('visible');
|
||||||
|
|
||||||
|
if (response === 'success') {
|
||||||
|
$notify.text('Thanks for your message!').addClass('success').addClass('visible');
|
||||||
|
} else {
|
||||||
|
var responseJSON = response.responseJSON,
|
||||||
|
errors = 0;
|
||||||
|
|
||||||
|
// add the error class to fields that haven't been filled out
|
||||||
|
for (var prop in responseJSON) {
|
||||||
|
if (responseJSON.hasOwnProperty(prop)) {
|
||||||
|
$('#' + prop).addClass('error');
|
||||||
|
errors++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errors > 0) {
|
||||||
|
$notify.find('span').text(errors);
|
||||||
|
$notify.addClass('visible');
|
||||||
|
}
|
||||||
|
|
||||||
|
// re-enable submitting
|
||||||
|
submitting = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
1
resources/assets/less/app.less
vendored
1
resources/assets/less/app.less
vendored
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
// Supplementary
|
// Supplementary
|
||||||
@import "elements/**";
|
@import "elements/**";
|
||||||
|
@import "pages/**";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
|
||||||
|
|
5
resources/assets/less/var.less
vendored
5
resources/assets/less/var.less
vendored
|
@ -5,7 +5,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Colours
|
// Colours
|
||||||
@c_text: #111; // text
|
@c_text: #111; // text
|
||||||
@c_text_light: #fff; // light text
|
@c_text_light: #fff; // light text
|
||||||
@c_base: #0088cc; // base
|
@c_base: #0088cc; // base
|
||||||
@c_accent: #f5f5f5; // accent
|
@c_accent: #f5f5f5; // accent
|
||||||
|
@c_error: #ff0000; // error
|
||||||
|
|
49
resources/assets/less/website/contact.less
vendored
Normal file
49
resources/assets/less/website/contact.less
vendored
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
#contact-form {
|
||||||
|
margin-top: 35px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
input, textarea {
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
padding: 5px 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
background-color: rgba(255, 255, 255, 0.8);
|
||||||
|
border: 2px solid fade(@c_text, 25%);
|
||||||
|
transition: border 100ms;
|
||||||
|
&:focus { border: 2px solid fade(@c_base, 60%); }
|
||||||
|
&.error { border: 2px solid @c_error; }
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
resize: none;
|
||||||
|
height: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#submit {
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
color: @c_text_light;
|
||||||
|
background-color: lighten(@c_base, 5%);
|
||||||
|
transition: background-color 100ms;
|
||||||
|
&:hover { background-color: @c_base; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#notification {
|
||||||
|
margin: 0px auto 15px auto;
|
||||||
|
padding: 5px 10px;
|
||||||
|
color: @c_text_light;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 14px;
|
||||||
|
opacity: 0;
|
||||||
|
background-color: lighten(@c_error, 15%);
|
||||||
|
transition: opacity 100ms;
|
||||||
|
&.visible { opacity: 1; }
|
||||||
|
span { font-weight: bold; }
|
||||||
|
|
||||||
|
&.success {
|
||||||
|
background-color: transparent;
|
||||||
|
color: @c_text;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,11 @@
|
||||||
@extends('base')
|
@extends('base')
|
||||||
|
|
||||||
@section('page-content')
|
@section('page-content')
|
||||||
<div class="container auth-container">
|
<div class="container auth-container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-6 col-xs-push-3">
|
<div class="col-xs-12 col-md-6 col-md-offset-3">
|
||||||
@yield('auth-form')
|
@yield('auth-form')
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
@endsection
|
@endsection
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
@extends('auth')
|
@extends('auth')
|
||||||
|
|
||||||
@section('auth-form')
|
@section('auth-form')
|
||||||
<form method="POST" action="/auth/login">
|
<form method="POST" action="/auth/login">
|
||||||
{!! csrf_field() !!}
|
{!! csrf_field() !!}
|
||||||
|
|
||||||
<div class="form-field">
|
<div class="form-field">
|
||||||
<label for="email">Email</label>
|
<label for="email">Email</label>
|
||||||
<div class="input"><input type="email" name="email" value="{{ old('email') }}" /></div>
|
<div class="input"><input type="email" name="email" value="{{ old('email') }}" /></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-field">
|
<div class="form-field">
|
||||||
<label for="password">Password</label>
|
<label for="password">Password</label>
|
||||||
<div class="input"><input type="password" name="password" id="password" /></div>
|
<div class="input"><input type="password" name="password" id="password" /></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-field">
|
<div class="form-field">
|
||||||
<label for="remember">Remember Me</label>
|
<label for="remember">Remember Me</label>
|
||||||
<input type="checkbox" name="remember" />
|
<input type="checkbox" name="remember" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="submit">Login</button>
|
<button type="submit">Login</button>
|
||||||
</form>
|
</form>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
|
@ -1,29 +1,29 @@
|
||||||
@extends('auth')
|
@extends('auth')
|
||||||
|
|
||||||
@section('auth-form')
|
@section('auth-form')
|
||||||
<form method="POST" action="/auth/register">
|
<form method="POST" action="/auth/register">
|
||||||
{!! csrf_field() !!}
|
{!! csrf_field() !!}
|
||||||
|
|
||||||
<div class="form-field">
|
<div class="form-field">
|
||||||
<label for="name">Name</label>
|
<label for="name">Name</label>
|
||||||
<div class="input"><input type="text" name="name" value="{{ old('name') }}" /></div>
|
<div class="input"><input type="text" name="name" value="{{ old('name') }}" /></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-field">
|
<div class="form-field">
|
||||||
<label for="email">Email</label>
|
<label for="email">Email</label>
|
||||||
<div class="input"><input type="email" name="email" value="{{ old('email') }}" /></div>
|
<div class="input"><input type="email" name="email" value="{{ old('email') }}" /></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-field">
|
<div class="form-field">
|
||||||
<label for="password">Password</label>
|
<label for="password">Password</label>
|
||||||
<div class="input"><input type="password" name="password" id="password" /></div>
|
<div class="input"><input type="password" name="password" id="password" /></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-field">
|
<div class="form-field">
|
||||||
<label for="password_confirmation">Confirm</label>
|
<label for="password_confirmation">Confirm</label>
|
||||||
<div class="input"><input type="password" name="password_confirmation" id="password_confirmation" /></div>
|
<div class="input"><input type="password" name="password_confirmation" id="password_confirmation" /></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="submit">Register</button>
|
<button type="submit">Register</button>
|
||||||
</form>
|
</form>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
11
resources/views/contact.blade.php
Normal file
11
resources/views/contact.blade.php
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p>Name: {{ $contact['name'] }}</p>
|
||||||
|
<p>Email: {{ $contact['email'] }}</p>
|
||||||
|
<p>{{ $contact['message'] }}</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
11
resources/views/email/contact.blade.php
Normal file
11
resources/views/email/contact.blade.php
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p><strong>Name:</strong> {{ $contact['name'] }}</p>
|
||||||
|
<p><strong>Email:</strong> {{ $contact['email'] }}</p>
|
||||||
|
<p>{{ $contact['message'] }}</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
30
resources/views/website/contact.blade.php
Normal file
30
resources/views/website/contact.blade.php
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
@extends('public')
|
||||||
|
|
||||||
|
@section('page-content')
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-12">
|
||||||
|
<h1>Contact</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-12 col-md-8 col-md-push-2">
|
||||||
|
<div id="contact-form">
|
||||||
|
<form action="#" method="POST" accept-charset="UTF-8">
|
||||||
|
<input type="hidden" name="_token" id="token" value="{{ csrf_token() }}" />
|
||||||
|
<input type="text" name="name" id="name" placeholder="Name" /><br />
|
||||||
|
<input type="text" name="email" id="email" placeholder="Email" /><br />
|
||||||
|
<textarea name="message" id="message" placeholder="Message"></textarea>
|
||||||
|
|
||||||
|
<input id="submit" type="submit" value="Submit" />
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div id="notification"><strong>Error:</strong> There were problems with the <span>0</span> fields highlighted above</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@endsection
|
Loading…
Reference in a new issue