Merge branch 'master' into Dev_PHP-Payments

Merging master into PHP-Payments branch.
This commit is contained in:
blkmutt 2014-03-21 08:17:51 -04:00
commit 11c6cff7ca
42 changed files with 1325 additions and 736 deletions

View File

@ -65,4 +65,5 @@ Configure config/database.php and then initialize the database
* [mozilla/pdf.js](https://github.com/mozilla/pdf.js) - PDF Reader in JavaScript
* [nnnick/Chart.js](https://github.com/nnnick/Chart.js) - Simple HTML5 Charts using the <canvas> tag
* [josscrowcroft/accounting.js](https://github.com/josscrowcroft/accounting.js) - A lightweight JavaScript library for number, money and currency formatting
* [jashkenas/underscore](https://github.com/jashkenas/underscore) - JavaScript's utility _ belt
* [jashkenas/underscore](https://github.com/jashkenas/underscore) - JavaScript's utility _ belt
* [caouecs/Laravel4-long](https://github.com/caouecs/Laravel4-lang) - List of languages for Laravel4

View File

@ -48,7 +48,7 @@
////////////////////////////////////////////////////////////////////
// Where Former should look for translations
'translate_from' => 'validation.attributes',
'translate_from' => 'texts',
// An array of attributes to automatically translate
'translatable' => array(

View File

@ -86,7 +86,8 @@ class AccountController extends \BaseController {
'timezones' => Timezone::remember(DEFAULT_QUERY_CACHE)->orderBy('location')->get(),
'dateFormats' => DateFormat::remember(DEFAULT_QUERY_CACHE)->get(),
'datetimeFormats' => DatetimeFormat::remember(DEFAULT_QUERY_CACHE)->get(),
'currencies' => Currency::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(),
'currencies' => Currency::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(),
'languages' => Language::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(),
];
return View::make('accounts.details', $data);
@ -514,7 +515,8 @@ class AccountController extends \BaseController {
$account->timezone_id = Input::get('timezone_id') ? Input::get('timezone_id') : null;
$account->date_format_id = Input::get('date_format_id') ? Input::get('date_format_id') : null;
$account->datetime_format_id = Input::get('datetime_format_id') ? Input::get('datetime_format_id') : null;
$account->currency_id = Input::get('currency_id') ? Input::get('currency_id') : 1;
$account->currency_id = Input::get('currency_id') ? Input::get('currency_id') : 1; // US Dollar
$account->language_id = Input::get('language_id') ? Input::get('language_id') : 1; // English
$account->save();
$user = Auth::user();

View File

@ -16,22 +16,22 @@ class HomeController extends BaseController {
public function showWelcome()
{
return View::make('splash');
return View::make('public.splash');
}
public function showAboutUs()
{
return View::make('about_us');
return View::make('public.about_us');
}
public function showContactUs()
{
return View::make('contact_us');
return View::make('public.contact_us');
}
public function showTerms()
{
return View::make('terms');
return View::make('public.terms');
}
public function doContactUs()
@ -46,7 +46,7 @@ class HomeController extends BaseController {
'text' => $message
];
$this->mailer->sendTo('contact@invoiceninja.com', 'contact@invoiceninja.com', 'Invoice Ninja Feedback', 'contact', $data);
$this->mailer->sendTo(CONTACT_EMAIL, CONTACT_EMAIL, 'Invoice Ninja Feedback', 'contact', $data);
Session::flash('message', 'Successfully sent message');
return Redirect::to('/contact');

View File

@ -180,7 +180,15 @@ class PaymentController extends \BaseController
$account = $invitation->invoice->client->account;
if ($account->isGatewayConfigured(GATEWAY_PAYPAL_EXPRESS))
{
return self::do_payment($invitationKey, false);
if (Session::has('error'))
{
Session::reflash();
return Redirect::to('view/' . $invitationKey);
}
else
{
return self::do_payment($invitationKey, false);
}
}
$invitation = Invitation::with('contact', 'invoice.client')->where('invitation_key', '=', $invitationKey)->firstOrFail();
@ -291,7 +299,7 @@ class PaymentController extends \BaseController
$invoice = $invitation->invoice;
$accountGateway = $invoice->client->account->account_gateways[0];
$payment = Payment::createNew();
$payment = Payment::createNew($invitation);
$payment->invitation_id = $invitation->id;
$payment->account_gateway_id = $accountGateway->id;
$payment->invoice_id = $invoice->id;
@ -334,7 +342,7 @@ class PaymentController extends \BaseController
$invoice->invoice_status_id = INVOICE_STATUS_PAID;
$invoice->save();
Event::fire('invoice.paid', $payment);
Session::flash('message', 'Successfully applied payment');

View File

@ -249,10 +249,13 @@ class UserController extends BaseController {
*/
public function logout()
{
if (!Auth::user()->registered)
if (Auth::check())
{
$account = Auth::user()->account;
$account->forceDelete();
if (!Auth::user()->registered)
{
$account = Auth::user()->account;
$account->forceDelete();
}
}
Confide::logout();

View File

@ -0,0 +1,56 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddLanguageSupport extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('languages', function($table)
{
$table->increments('id');
$table->string('name');
$table->string('locale');
});
DB::table('languages')->insert(['name' => 'English', 'locale' => 'en']);
DB::table('languages')->insert(['name' => 'Italian', 'locale' => 'it']);
DB::table('languages')->insert(['name' => 'German', 'locale' => 'de']);
DB::table('languages')->insert(['name' => 'French', 'locale' => 'fr']);
Schema::table('accounts', function($table)
{
$table->unsignedInteger('language_id')->default(1);
});
DB::table('accounts')->update(['language_id' => 1]);
Schema::table('accounts', function($table)
{
$table->foreign('language_id')->references('id')->on('languages');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('accounts', function($table)
{
$table->dropForeign('accounts_language_id_foreign');
$table->dropColumn('language_id');
});
Schema::drop('languages');
}
}

View File

@ -5,21 +5,7 @@ class UserTableSeeder extends Seeder
public function run()
{
//DB::table('users')->delete();
/*
$account = Account::create(array(
'name' => 'Acme Inc',
));
$user = User::create(array(
'account_id' => $account->id,
'first_name' => 'Hillel',
'last_name' => 'Coren',
'email' => 'hillelcoren@gmail.com',
'password' => Hash::make('1234'),
));
*/
}
}

View File

@ -20,6 +20,11 @@ App::before(function($request)
return Redirect::secure(Request::getRequestUri());
}
}
if (Auth::check())
{
App::setLocale(Auth::user()->getLocale());
}
});

View File

@ -0,0 +1,20 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Pagination Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used by the paginator library to build
| the simple pagination links. You are free to change them to anything
| you want to customize your views to better match your application.
|
*/
'previous' => '&laquo; zurück',
'next' => 'weiter &raquo;',
);

24
app/lang/de/reminders.php Normal file
View File

@ -0,0 +1,24 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Password Reminder Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are the default lines which match reasons
| that are given by the password broker for a password update attempt
| has failed, such as for an invalid token or invalid new password.
|
*/
"password" => "Passwörter müssen 6 Zeichen lang sein und korrekt bestätigt werden.",
"user" => "Wir konnten leider keinen Nutzer mit dieser E-Mail Adresse finden.",
"token" => "Der Passwort-Wiederherstellungs-Schlüssel ist ungültig.",
"sent" => "Passworterinnerung wurde gesendet!",
);

104
app/lang/de/validation.php Normal file
View File

@ -0,0 +1,104 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Validation Language Lines
|--------------------------------------------------------------------------
|
| The following language lines contain the default error messages used by
| the validator class. Some of these rules have multiple versions such
| such as the size rules. Feel free to tweak each of these messages.
|
*/
"accepted" => ":attribute muss akzeptiert werden.",
"active_url" => ":attribute ist keine gültige Internet-Adresse.",
"after" => ":attribute muss ein Datum nach dem :date sein.",
"alpha" => ":attribute darf nur aus Buchstaben bestehen.",
"alpha_dash" => ":attribute darf nur aus Buchstaben, Zahlen, Binde- und Unterstrichen bestehen. Umlaute (ä, ö, ü) und Eszett (ß) sind nicht erlaubt.",
"alpha_num" => ":attribute darf nur aus Buchstaben und Zahlen bestehen.",
"array" => ":attribute muss ein Array sein.",
"before" => ":attribute muss ein Datum vor dem :date sein.",
"between" => array(
"numeric" => ":attribute muss zwischen :min & :max liegen.",
"file" => ":attribute muss zwischen :min & :max Kilobytes groß sein.",
"string" => ":attribute muss zwischen :min & :max Zeichen lang sein.",
"array" => ":attribute muss zwischen :min & :max Elemente haben."
),
"confirmed" => ":attribute stimmt nicht mit der Bestätigung überein.",
"date" => ":attribute muss ein gültiges Datum sein.",
"date_format" => ":attribute entspricht nicht dem gültigen Format für :format.",
"different" => ":attribute und :other müssen sich unterscheiden.",
"digits" => ":attribute muss :digits Stellen haben.",
"digits_between" => ":attribute muss zwischen :min und :max Stellen haben.",
"email" => ":attribute Format ist ungültig.",
"exists" => "Der gewählte Wert für :attribute ist ungültig.",
"image" => ":attribute muss ein Bild sein.",
"in" => "Der gewählte Wert für :attribute ist ungültig.",
"integer" => ":attribute muss eine ganze Zahl sein.",
"ip" => ":attribute muss eine gültige IP-Adresse sein.",
"max" => array(
"numeric" => ":attribute darf maximal :max sein.",
"file" => ":attribute darf maximal :max Kilobytes groß sein.",
"string" => ":attribute darf maximal :max Zeichen haben.",
"array" => ":attribute darf nicht mehr als :max Elemente haben."
),
"mimes" => ":attribute muss den Dateityp :values haben.",
"min" => array(
"numeric" => ":attribute muss mindestens :min sein.",
"file" => ":attribute muss mindestens :min Kilobytes groß sein.",
"string" => ":attribute muss mindestens :min Zeichen lang sein.",
"array" => ":attribute muss mindestens :min Elemente haben."
),
"not_in" => "Der gewählte Wert für :attribute ist ungültig.",
"numeric" => ":attribute muss eine Zahl sein.",
"regex" => ":attribute Format ist ungültig.",
"required" => ":attribute muss ausgefüllt sein.",
"required_if" => ":attribute muss ausgefüllt sein wenn :other :value ist.",
"required_with" => ":attribute muss angegeben werden wenn :values ausgefüllt wurde.",
"required_with_all" => "The :attribute field is required when :values is present.",
"required_without" => ":attribute muss angegeben werden wenn :values nicht ausgefüllt wurde.",
"required_without_all" => ":attribute muss angegeben werden wenn keines der Felder :values ausgefüllt wurde.",
"same" => ":attribute und :other müssen übereinstimmen.",
"size" => array(
"numeric" => ":attribute muss gleich :size sein.",
"file" => ":attribute muss :size Kilobyte groß sein.",
"string" => ":attribute muss :size Zeichen lang sein.",
"array" => ":attribute muss genau :size Elemente haben."
),
"unique" => ":attribute ist schon vergeben.",
"url" => "Das Format von :attribute ist ungültig.",
/*
|--------------------------------------------------------------------------
| Custom Validation Language Lines
|--------------------------------------------------------------------------
|
| Here you may specify custom validation messages for attributes using the
| convention "attribute.rule" to name the lines. This makes it quick to
| specify a specific custom language line for a given attribute rule.
|
*/
'custom' => array(
'attribute-name' => array(
'rule-name' => 'custom-message',
),
),
/*
|--------------------------------------------------------------------------
| Custom Validation Attributes
|--------------------------------------------------------------------------
|
| The following language lines are used to swap attribute place-holders
| with something more reader friendly such as E-Mail Address instead
| of "email". This simply helps us make messages a little cleaner.
|
*/
'attributes' => array(),
);

28
app/lang/en/texts.php Normal file
View File

@ -0,0 +1,28 @@
<?php
return array(
'organization' => 'Organization',
'name' => 'Name',
'website' => 'Website',
'work_phone' => 'Phone',
'address' => 'Address',
'address1' => 'Street',
'address2' => 'Apt/Suite',
'city' => 'City',
'state' => 'State/Province',
'postal_code' => 'Postal Code',
'country_id' => 'Country',
'contacts' => 'Contacts',
'first_name' => 'First Name',
'last_name' => 'Last Name',
'phone' => 'Phone',
'email' => 'Email',
'additional_info' => 'Additional Info',
'payment_terms' => 'Payment Terms',
'currency_id' => 'Currency',
'size_id' => 'Size',
'industry_id' => 'Industry',
'private_notes' => 'Private Notes',
);

View File

@ -0,0 +1,20 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Pagination Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used by the paginator library to build
| the simple pagination links. You are free to change them to anything
| you want to customize your views to better match your application.
|
*/
'previous' => '&laquo; Précédent',
'next' => 'Suivant &raquo;',
);

24
app/lang/fr/reminders.php Normal file
View File

@ -0,0 +1,24 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Password Reminder Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are the default lines which match reasons
| that are given by the password broker for a password update attempt
| has failed, such as for an invalid token or invalid new password.
|
*/
"password" => "Les mots de passe doivent avoir au moins six caractères et doivent être identiques.",
"user" => "Nous ne pouvons trouver cet utilisateur avec cette adresse e-mail.",
"token" => "Ce jeton de réinitialisation du mot de passe n'est pas valide.",
"sent" => "Rappel du mot de passe envoyé !",
);

134
app/lang/fr/validation.php Normal file
View File

@ -0,0 +1,134 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Validation Language Lines
|--------------------------------------------------------------------------
|
| The following language lines contain the default error messages used by
| the validator class. Some of these rules have multiple versions such
| such as the size rules. Feel free to tweak each of these messages.
|
*/
"accepted" => "Le champ :attribute doit être accepté.",
"active_url" => "Le champ :attribute n'est pas une URL valide.",
"after" => "Le champ :attribute doit être une date postérieure au :date.",
"alpha" => "Le champ :attribute doit seulement contenir des lettres.",
"alpha_dash" => "Le champ :attribute doit seulement contenir des lettres, des chiffres et des tirets.",
"alpha_num" => "Le champ :attribute doit seulement contenir des chiffres et des lettres.",
"array" => "Le champ :attribute doit être un tableau.",
"before" => "Le champ :attribute doit être une date antérieure au :date.",
"between" => array(
"numeric" => "La valeur de :attribute doit être comprise entre :min et :max.",
"file" => "Le fichier :attribute doit avoir une taille entre :min et :max kilobytes.",
"string" => "Le texte :attribute doit avoir entre :min et :max caractères.",
"array" => "Le champ :attribute doit avoir entre :min et :max éléments."
),
"confirmed" => "Le champ de confirmation :attribute ne correspond pas.",
"date" => "Le champ :attribute n'est pas une date valide.",
"date_format" => "Le champ :attribute ne correspond pas au format :format.",
"different" => "Les champs :attribute et :other doivent être différents.",
"digits" => "Le champ :attribute doit avoir :digits chiffres.",
"digits_between" => "Le champ :attribute doit avoir entre :min and :max chiffres.",
"email" => "Le champ :attribute doit être une adresse email valide.",
"exists" => "Le champ :attribute sélectionné est invalide.",
"image" => "Le champ :attribute doit être une image.",
"in" => "Le champ :attribute est invalide.",
"integer" => "Le champ :attribute doit être un entier.",
"ip" => "Le champ :attribute doit être une adresse IP valide.",
"max" => array(
"numeric" => "La valeur de :attribute ne peut être supérieure à :max.",
"file" => "Le fichier :attribute ne peut être plus gros que :max kilobytes.",
"string" => "Le texte de :attribute ne peut contenir plus de :max caractères.",
"array" => "Le champ :attribute ne peut avoir plus de :max éléments.",
),
"mimes" => "Le champ :attribute doit être un fichier de type : :values.",
"min" => array(
"numeric" => "La valeur de :attribute doit être supérieure à :min.",
"file" => "Le fichier :attribute doit être plus que gros que :min kilobytes.",
"string" => "Le texte :attribute doit contenir au moins :min caractères.",
"array" => "Le champ :attribute doit avoir au moins :min éléments."
),
"not_in" => "Le champ :attribute sélectionné n'est pas valide.",
"numeric" => "Le champ :attribute doit contenir un nombre.",
"regex" => "Le format du champ :attribute est invalide.",
"required" => "Le champ :attribute est obligatoire.",
"required_if" => "Le champ :attribute est obligatoire quand la valeur de :other est :value.",
"required_with" => "Le champ :attribute est obligatoire quand :values est présent.",
"required_with_all" => "Le champ :attribute est obligatoire quand :values est présent.",
"required_without" => "Le champ :attribute est obligatoire quand :values n'est pas présent.",
"required_without_all" => "Le champ :attribute est requis quand aucun de :values n'est présent.",
"same" => "Les champs :attribute et :other doivent être identiques.",
"size" => array(
"numeric" => "La valeur de :attribute doit être :size.",
"file" => "La taille du fichier de :attribute doit être de :size kilobytes.",
"string" => "Le texte de :attribute doit contenir :size caractères.",
"array" => "Le champ :attribute doit contenir :size éléments."
),
"unique" => "La valeur du champ :attribute est déjà utilisée.",
"url" => "Le format de l'URL de :attribute n'est pas valide.",
/*
|--------------------------------------------------------------------------
| Custom Validation Language Lines
|--------------------------------------------------------------------------
|
| Here you may specify custom validation messages for attributes using the
| convention "attribute.rule" to name the lines. This makes it quick to
| specify a specific custom language line for a given attribute rule.
|
*/
'custom' => array(
'attribute-name' => array(
'rule-name' => 'custom-message',
),
),
/*
|--------------------------------------------------------------------------
| Custom Validation Attributes
|--------------------------------------------------------------------------
|
| The following language lines are used to swap attribute place-holders
| with something more reader friendly such as E-Mail Address instead
| of "email". This simply helps us make messages a little cleaner.
|
*/
'attributes' => array(
"name" => "Nom",
"username" => "Pseudo",
"email" => "E-mail",
"first_name" => "Prénom",
"last_name" => "Nom",
"password" => "Mot de passe",
"password_confirmation" => "Confirmation du mot de passe",
"city" => "Ville",
"country" => "Pays",
"address" => "Adresse",
"phone" => "Téléphone",
"mobile" => "Portable",
"age" => "Age",
"sex" => "Sexe",
"gender" => "Genre",
"day" => "Jour",
"month" => "Mois",
"year" => "Année",
"hour" => "Heure",
"minute" => "Minute",
"second" => "Seconde",
"title" => "Titre",
"content" => "Contenu",
"description" => "Description",
"excerpt" => "Extrait",
"date" => "Date",
"time" => "Heure",
"available" => "Disponible",
"size" => "Taille"
),
);

View File

@ -0,0 +1,20 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Pagination Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used by the paginator library to build
| the simple pagination links. You are free to change them to anything
| you want to customize your views to better match your application.
|
*/
'previous' => '&laquo; Precedente',
'next' => 'Successivo &raquo;',
);

24
app/lang/it/reminders.php Normal file
View File

@ -0,0 +1,24 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Password Reminder Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are the default lines which match reasons
| that are given by the password broker for a password update attempt
| has failed, such as for an invalid token or invalid new password.
|
*/
"password" => "Le password devono essere di almeno 6 caratteri e devono coincidere.",
"user" => "Non esiste un utente associato a questo indirizzo e-mail.",
"token" => "Questo token per la reimpostazione della password non è valido.",
"sent" => "Promemoria della password inviato!",
);

103
app/lang/it/validation.php Normal file
View File

@ -0,0 +1,103 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Validation Language Lines
|--------------------------------------------------------------------------
|
| The following language lines contain the default error messages used by
| the validator class. Some of these rules have multiple versions such
| such as the size rules. Feel free to tweak each of these messages.
|
*/
"accepted" => ":attribute deve essere accettato.",
"active_url" => ":attribute non è un URL valido.",
"after" => ":attribute deve essere una data successiva al :date.",
"alpha" => ":attribute può contenere solo lettere.",
"alpha_dash" => ":attribute può contenere solo lettere, numeri e trattini.",
"alpha_num" => ":attribute può contenere solo lettere e numeri.",
"array" => ":attribute deve essere un array.",
"before" => ":attribute deve essere una data precedente al :date.",
"between" => array(
"numeric" => ":attribute deve trovarsi tra :min - :max.",
"file" => ":attribute deve trovarsi tra :min - :max kilobytes.",
"string" => ":attribute deve trovarsi tra :min - :max caratteri.",
"array" => ":attribute deve avere tra :min - :max elementi."
),
"confirmed" => "Il campo di conferma per :attribute non coincide.",
"date" => ":attribute non è una data valida.",
"date_format" => ":attribute non coincide con il formato :format.",
"different" => ":attribute e :other devono essere differenti.",
"digits" => ":attribute deve essere di :digits cifre.",
"digits_between" => ":attribute deve essere tra :min e :max cifre.",
"email" => ":attribute non è valido.",
"exists" => ":attribute selezionato/a non è valido.",
"image" => ":attribute deve essere un'immagine.",
"in" => ":attribute selezionato non è valido.",
"integer" => ":attribute deve essere intero.",
"ip" => ":attribute deve essere un indirizzo IP valido.",
"max" => array(
"numeric" => ":attribute deve essere minore di :max.",
"file" => ":attribute non deve essere più grande di :max kilobytes.",
"string" => ":attribute non può contenere più di :max caratteri.",
"array" => ":attribute non può avere più di :max elementi."
),
"mimes" => ":attribute deve essere del tipo: :values.",
"min" => array(
"numeric" => ":attribute deve valere almeno :min.",
"file" => ":attribute deve essere più grande di :min kilobytes.",
"string" => ":attribute deve contenere almeno :min caratteri.",
"array" => ":attribute deve avere almeno :min elementi."
),
"not_in" => "Il valore selezionato per :attribute non è valido.",
"numeric" => ":attribute deve essere un numero.",
"regex" => "Il formato del campo :attribute non è valido.",
"required" => ":attribute è richiesto.",
"required_if" => "Il campo :attribute è richiesto quando :other è :value.",
"required_with" => "Il campo :attribute è richiesto quando :values è presente.",
"required_with_all" => "The :attribute field is required when :values is present.",
"required_without" => "Il campo :attribute è richiesto quando :values non è presente.",
"required_without_all" => "The :attribute field is required when none of :values are present.",
"same" => ":attribute e :other devono coincidere.",
"size" => array(
"numeric" => ":attribute deve valere :size.",
"file" => ":attribute deve essere grande :size kilobytes.",
"string" => ":attribute deve contenere :size caratteri.",
"array" => ":attribute deve contenere :size elementi."
),
"unique" => ":attribute è stato già utilizzato.",
"url" => ":attribute deve essere un URL.",
/*
|--------------------------------------------------------------------------
| Custom Validation Language Lines
|--------------------------------------------------------------------------
|
| Here you may specify custom validation messages for attributes using the
| convention "attribute.rule" to name the lines. This makes it quick to
| specify a specific custom language line for a given attribute rule.
|
*/
'custom' => array(
'attribute-name' => array(
'rule-name' => 'custom-message',
),
),
/*
|--------------------------------------------------------------------------
| Custom Validation Attributes
|--------------------------------------------------------------------------
|
| The following language lines are used to swap attribute place-holders
| with something more reader friendly such as E-Mail Address instead
| of "email". This simply helps us make messages a little cleaner.
|
*/
'attributes' => array(),
);

View File

@ -0,0 +1,20 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Pagination Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used by the paginator library to build
| the simple pagination links. You are free to change them to anything
| you want to customize your views to better match your application.
|
*/
'previous' => '&laquo; Anterior',
'next' => 'Próximo &raquo;',
);

View File

@ -0,0 +1,24 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Password Reminder Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are the default lines which match reasons
| that are given by the password broker for a password update attempt
| has failed, such as for an invalid token or invalid new password.
|
*/
"password" => "Senhas devem possuir no mínimo seis caracteres e devem ser iguais.",
"user" => "Não achamos um usuário com o endereço de e-mail informado.",
"token" => "Este token de redefinição de senha é inválido.",
"sent" => "Lmebrete de senha enviado!",
);

28
app/lang/pt_BR/texts.php Normal file
View File

@ -0,0 +1,28 @@
<?php
return array(
'organization' => 'Organização',
'name' => 'Nome',
'website' => 'Website',
'work_phone' => 'Telefone',
'address' => 'Endereço',
'address1' => 'Rua',
'address2' => 'Bloco/apto',
'city' => 'Cidade',
'state' => 'Estado',
'postal_code' => 'CEP',
'country_id' => 'País',
'contacts' => 'Contatos',
'first_name' => 'Primeiro Nome',
'last_name' => 'Último Nome',
'phone' => 'Telefone',
'email' => 'Email',
'additional_info' => 'Informações Adicionais',
'payment_terms' => 'Termos de Pagamento',
'currency_id' => 'Moeda',
'size_id' => 'Tamanho',
'industry_id' => 'Empresa',
'private_notes' => 'Notas Privadas',
);

View File

@ -0,0 +1,102 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Validation Language Lines
|--------------------------------------------------------------------------
|
| The following language lines contain the default error messages used by
| the validator class. Some of these rules have multiple versions such
| such as the size rules. Feel free to tweak each of these messages.
|
*/
"accepted" => ":attribute deve ser aceito.",
"active_url" => ":attribute não é uma URL válida.",
"after" => ":attribute deve ser uma data maior que :date.",
"alpha" => ":attribute deve conter apenas letras.",
"alpha_dash" => ":attribute pode conter apenas letras, número e traços",
"alpha_num" => ":attribute pode conter apenas letras e números.",
"array" => ":attribute deve ser um array.",
"before" => ":attribute deve ser uma data anterior a :date.",
"between" => array(
"numeric" => ":attribute deve ser entre :min - :max.",
"file" => ":attribute deve ser entre :min - :max kilobytes.",
"string" => ":attribute deve ser entre :min - :max caracteres.",
"array" => ":attribute deve conter entre :min - :max itens.",
),
"confirmed" => ":attribute confirmação não correponde.",
"date" => ":attribute não é uma data válida.",
"date_format" => ":attribute não satisfaz o formato :format.",
"different" => ":attribute e :other devem ser diferentes.",
"digits" => ":attribute deve conter :digits dígitos.",
"digits_between" => ":attribute deve conter entre :min e :max dígitos.",
"email" => ":attribute está em um formato inválido.",
"exists" => "A opção selecionada :attribute é inválida.",
"image" => ":attribute deve ser uma imagem.",
"in" => "A opção selecionada :attribute é inválida.",
"integer" => ":attribute deve ser um número inteiro.",
"ip" => ":attribute deve ser um endereço IP válido.",
"max" => array(
"numeric" => ":attribute não pode ser maior que :max.",
"file" => ":attribute não pode ser maior que :max kilobytes.",
"string" => ":attribute não pode ser maior que :max caracteres.",
"array" => ":attribute não pode conter mais que :max itens.",
),
"mimes" => ":attribute deve ser um arquivo do tipo: :values.",
"min" => array(
"numeric" => ":attribute não deve ser menor que :min.",
"file" => ":attribute deve ter no mínimo :min kilobytes.",
"string" => ":attribute deve conter no mínimo :min caracteres.",
"array" => ":attribute deve conter ao menos :min itens.",
),
"not_in" => "A opção selecionada :attribute é inválida.",
"numeric" => ":attribute deve ser um número.",
"regex" => ":attribute está em um formato inválido.",
"required" => ":attribute é um campo obrigatório.",
"required_if" => ":attribute é necessário quando :other é :value.",
"required_with" => ":attribute é obrigatório quando :values está presente.",
"required_without" => ":attribute é obrigatório quando :values não está presente.",
"same" => ":attribute e :other devem corresponder.",
"size" => array(
"numeric" => ":attribute deve ter :size.",
"file" => ":attribute deve ter :size kilobytes.",
"string" => ":attribute deve conter :size caracteres.",
"array" => ":attribute deve conter :size itens.",
),
"unique" => ":attribute já está sendo utilizado.",
"url" => ":attribute está num formato inválido.",
"positive" => ":attribute deve ser maior que zero.",
"has_credit" => "O cliente não possui crédito suficiente.",
/*
|--------------------------------------------------------------------------
| Custom Validation Language Lines
|--------------------------------------------------------------------------
|
| Here you may specify custom validation messages for attributes using the
| convention "attribute.rule" to name the lines. This makes it quick to
| specify a specific custom language line for a given attribute rule.
|
*/
'custom' => array(),
/*
|--------------------------------------------------------------------------
| Custom Validation Attributes
|--------------------------------------------------------------------------
|
| The following language lines are used to swap attribute place-holders
| with something more reader friendly such as E-Mail Address instead
| of "email". This simply helps us make messages a little cleaner.
|
*/
'attributes' => array(),
);

7
app/models/Language.php Executable file
View File

@ -0,0 +1,7 @@
<?php
class Language extends Eloquent
{
public $timestamps = false;
protected $softDelete = false;
}

View File

@ -104,11 +104,25 @@ class User extends ConfideUser implements UserInterface, RemindableInterface
}
}
public function getLocale()
{
$language = Language::remember(DEFAULT_QUERY_CACHE)->where('id', '=', $this->account->language_id)->first();
return $language->locale;
}
public function showGreyBackground()
{
return !$this->theme_id || in_array($this->theme_id, [2, 3, 5, 6, 7, 8, 10, 11, 12]);
}
public function showSignUpPopOver()
{
$count = Session::get(SESSION_COUNTER, 0);
Session::put(SESSION_COUNTER, ++$count);
return $count == 1 || $count % 7 == 0;
}
public function afterSave($success=true, $forced = false)
{
if ($this->email)

View File

@ -22,37 +22,6 @@
//dd(gethostname());
//Log::error('test');
/*
Event::listen('illuminate.query', function($query, $bindings, $time, $name)
{
$data = compact('bindings', 'time', 'name');
// Format binding data for sql insertion
foreach ($bindings as $i => $binding)
{
if ($binding instanceof \DateTime)
{
$bindings[$i] = $binding->format('\'Y-m-d H:i:s\'');
}
else if (is_string($binding))
{
$bindings[$i] = "'$binding'";
}
}
// Insert bindings into query
$query = str_replace(array('%', '?'), array('%%', '%s'), $query);
$query = vsprintf($query, $bindings);
Log::info($query, $data);
});
*/
/*
Route::get('/send_emails', function() {
Artisan::call('ninja:send-invoices');
});
*/
Route::get('/', 'HomeController@showWelcome');
Route::get('/rocksteady', 'HomeController@showWelcome');
@ -167,7 +136,9 @@ HTML::macro('breadcrumbs', function() {
// Get the breadcrumbs by exploding the current path.
$basePath = Utils::basePath();
$path = $_SERVER['REQUEST_URI'];
$parts = explode('?', $_SERVER['REQUEST_URI']);
$path = $parts[0];
if ($basePath != '/')
{
$path = str_replace($basePath, '', $path);
@ -200,7 +171,9 @@ HTML::macro('breadcrumbs', function() {
return $str . '</ol>';
});
define('CONTACT_EMAIL', 'contact@invoiceninja.com');
define('ANALYTICS_KEY', 'UA-46031341-1');
define('ENV_DEVELOPMENT', 'local');
define('ENV_STAGING', 'staging');
@ -250,13 +223,14 @@ define('SESSION_CURRENCY', 'currency');
define('SESSION_DATE_FORMAT', 'dateFormat');
define('SESSION_DATE_PICKER_FORMAT', 'datePickerFormat');
define('SESSION_DATETIME_FORMAT', 'datetimeFormat');
define('SESSION_COUNTER', 'sessionCounter');
define('DEFAULT_TIMEZONE', 'US/Eastern');
define('DEFAULT_CURRENCY', 1); // US Dollar
define('DEFAULT_DATE_FORMAT', 'M j, Y');
define('DEFAULT_DATE_PICKER_FORMAT', 'M d, yyyy');
define('DEFAULT_DATETIME_FORMAT', 'F j, Y, g:i a');
define('DEFAULT_QUERY_CACHE', 120);
define('DEFAULT_QUERY_CACHE', 120); // minutes
define('GATEWAY_PAYPAL_EXPRESS', 17);
@ -266,7 +240,6 @@ if (Auth::check() && !Session::has(SESSION_TIMEZONE))
Event::fire('user.refresh');
}
Validator::extend('positive', function($attribute, $value, $parameters)
{
return Utils::parseFloat($value) > 0;
@ -281,4 +254,31 @@ Validator::extend('has_credit', function($attribute, $value, $parameters)
$credit = $client->getTotalCredit();
return $credit >= $amount;
});
});
/*
Event::listen('illuminate.query', function($query, $bindings, $time, $name)
{
$data = compact('bindings', 'time', 'name');
// Format binding data for sql insertion
foreach ($bindings as $i => $binding)
{
if ($binding instanceof \DateTime)
{
$bindings[$i] = $binding->format('\'Y-m-d H:i:s\'');
}
else if (is_string($binding))
{
$bindings[$i] = "'$binding'";
}
}
// Insert bindings into query
$query = str_replace(array('%', '?'), array('%%', '%s'), $query);
$query = vsprintf($query, $bindings);
Log::info($query, $data);
});
*/

View File

@ -1,170 +0,0 @@
@extends('master')
@section('head')
<link href="{{ asset('css/bootstrap.splash.css') }}" rel="stylesheet" type="text/css"/>
<link href="{{ asset('css/splash.css') }}" rel="stylesheet" type="text/css"/>
<link href="{{ asset('images/apple-touch-icon-114x114-precomposed.png') }}" rel="apple-touch-icon-precomposed" sizes="114x114">
<link href="{{ asset('images/apple-touch-icon-72x72-precomposed.png') }}" rel="apple-touch-icon-precomposed" sizes="72x72">
<link href="{{ asset('images/apple-touch-icon-57x57-precomposed.png') }}" rel="apple-touch-icon-precomposed">
@stop
@section('body')
{{ Form::open(array('url' => 'get_started', 'id' => 'startForm')) }}
{{ Form::hidden('guest_key') }}
{{ Form::close() }}
<script>
$(document).ready(function () {
if (isStorageSupported()) {
$('[name="guest_key"]').val(localStorage.getItem('guest_key'));
}
});
function isStorageSupported() {
try {
return 'localStorage' in window && window['localStorage'] !== null;
} catch (e) {
return false;
}
}
function getStarted() {
$('#startForm').submit();
}
</script>
<div class="navbar" style="margin-bottom:0px">
<div class="container">
<div class="navbar-inner">
<a class="brand" href="/"><img src=
"images/invoiceninja-logo.png"></a>
<ul class="navbar-list">
<li>{{ link_to('about', 'About Us' ) }}</li>
<li>{{ link_to('contact', 'Contact Us' ) }}</li>
<li>{{ link_to('login', Auth::check() ? 'My Account' : 'Login' ) }}</li>
</ul>
</div>
</div>
</div>
</div>
<section class="hero3" data-speed="2" data-type="background">
<div class="container">
<div class="caption">
<h1>WHY INVOICE NINJA?
</h1>
</div>
</div>
</section>
<section class="about center">
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<h2>Open Source Platform</h2>
<p>Free yourself from online invoicing platforms with high monthly fees and limited functionality. Being <a href="https://github.com/hillelcoren/invoice-ninja" target="_blank">open source</a> allows us fast app development, security audits by the open-course community, and we can keep it <strong>FREE!</strong></p>
</div>
</div>
</div>
</section>
<section class="about white-bg">
<div class="container">
<div class="row">
<div class="col-md-5">
<div class="screendump">
<img src="images/about1.jpg">
</div>
</div>
<div class="col-md-7">
<h2>Live PDF Creation</h2>
<p><strong>Look professional from day #1.</strong> Select one of our beautiful invoice templates to suit your company identity, switch between designs in real time to preview invoices & email them to clients with one click. The live preview PDF function was designed for an efficient and hassle-free experience, and its awesome!
</p>
</div>
</div>
</div>
</section>
<section class="about">
<div class="container">
<div class="row">
<div class="col-md-7">
<h2>Online Payments</h2>
<p><strong>Authorize.net, Beanstream, PayPal?</strong> InvoiceNinja supports the most popular online payment gateways! If you need help integrating a third party gateway we dont yet support, please contact us! Were happy to help! If you need assistance of want to learn more about online payment solutions, contact us!</p>
</div>
<div class="col-md-5">
<div class="screendump">
<img src="images/about2.jpg">
</div>
</div>
</div>
</div>
</section>
<!--
<section class="about center white-bg">
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<h2>Info about the company/story</h2>
<p>Donec id elit non mi porta gravida at eget metus.
Fusce dapibus, tellus ac cursus commodo, tortor mauris
condimentum nibh, ut fermentum massa justo sit amet
risus. Etiam porta sem malesuada magna mollis euismod.
Donec sed odio dui.</p>
</div>
</div>
</div>
</section>
-->
<section class="upper-footer">
<div class="container">
<div class="row">
<div class="col-md-3 center-block">
<a href="#">
<div class="cta">
<h2 onclick="getStarted()">Invoice Now <span>+</span></h2>
</div>
</a>
</div>
</div>
</div>
</section>
<footer>
<div class="navbar" style="margin-bottom:0px">
<div class="container">
<div class="social">
<!--
<a href="http://twitter.com/eas_id"><span class=
"socicon">c</span></a>
-->
<a href=
"http://facebook.com/invoiceninja" target="_blank"><span class=
"socicon">b</span></a> <a href=
"http://twitter.com/invoiceninja" target="_blank"><span class=
"socicon">a</span></a>
<p>Copyright © 2014 InvoiceNinja. All rights reserved.</p>
</div>
<div class="navbar-inner">
<ul class="navbar-list">
<li>{{ link_to('about', 'About Us' ) }}</li>
<li>{{ link_to('contact', 'Contact Us' ) }}</li>
<li>{{ link_to('login', Auth::check() ? 'My Account' : 'Login' ) }}</li>
</ul>
<!--
<ul class="navbar-list">
<li><a href="#">For developers</a></li>
<li><a href="#">Jobs</a></li>
<li><a href="#">Terms &amp; Conditions</a></li>
<li><a href="#">Our Blog</a></li>
</ul>
-->
</div>
</div>
</div>
</footer><script src="{{ asset('/js/retina-1.1.0.min.js') }}" type="text/javascript"></script>
@stop

View File

@ -62,8 +62,9 @@
{{ Former::text('email') }}
{{ Former::text('phone') }}
{{ Former::legend('Localization') }}
{{ Former::select('language_id')->addOption('','')->label('Language')
->fromQuery($languages, 'name', 'id') }}
{{ Former::select('currency_id')->addOption('','')->label('Currency')
->fromQuery($currencies, 'name', 'id') }}
{{ Former::select('timezone_id')->addOption('','')->label('Timezone')

View File

@ -14,10 +14,8 @@
@if ($accountGateway)
{{ Former::populateField('gateway_id', $accountGateway->gateway_id) }}
@foreach ($accountGateway->fields as $field => $junk)
@if ($field == 'testMode' || $field == 'developerMode')
@if ($config->$field)
{{-- Former::populateField($accountGateway->gateway_id.'_'.$field, true ) --}}
@endif
@if (in_array($field, ['solutionType', 'landingPage', 'headerImageUrl', 'brandName']))
{{-- do nothing --}}
@else
{{ Former::populateField($accountGateway->gateway_id.'_'.$field, $config->$field) }}
@endif

View File

@ -21,26 +21,26 @@
<div class="col-md-6">
{{ Former::legend('Organization') }}
{{ Former::legend('organization') }}
{{ Former::text('name')->data_bind("attr { placeholder: placeholderName }") }}
{{ Former::text('website') }}
{{ Former::text('work_phone')->label('Phone') }}
{{ Former::text('work_phone') }}
{{ Former::legend('Address') }}
{{ Former::text('address1')->label('Street') }}
{{ Former::text('address2')->label('Apt/Suite') }}
{{ Former::legend('address') }}
{{ Former::text('address1') }}
{{ Former::text('address2') }}
{{ Former::text('city') }}
{{ Former::text('state')->label('State/Province') }}
{{ Former::text('state') }}
{{ Former::text('postal_code') }}
{{ Former::select('country_id')->addOption('','')->label('Country')
{{ Former::select('country_id')->addOption('','')
->fromQuery($countries, 'name', 'id') }}
</div>
<div class="col-md-6">
{{ Former::legend('Contacts') }}
{{ Former::legend('contacts') }}
<div data-bind='template: { foreach: contacts,
beforeRemove: hideContact,
afterAdd: showContact }'>
@ -62,14 +62,14 @@
</div>
</div>
{{ Former::legend('Additional Info') }}
{{ Former::legend('additional_info') }}
{{ Former::select('payment_terms')->addOption('','')
->fromQuery($paymentTerms, 'name', 'num_days') }}
{{ Former::select('currency_id')->addOption('','')->label('Currency')
{{ Former::select('currency_id')->addOption('','')
->fromQuery($currencies, 'name', 'id') }}
{{ Former::select('size_id')->addOption('','')->label('Size')
{{ Former::select('size_id')->addOption('','')
->fromQuery($sizes, 'name', 'id') }}
{{ Former::select('industry_id')->addOption('','')->label('Industry')
{{ Former::select('industry_id')->addOption('','')
->fromQuery($industries, 'name', 'id') }}
{{ Former::textarea('private_notes') }}

View File

@ -1,216 +0,0 @@
@extends('master')
@section('head')
<link href="{{ asset('vendor/bootstrap/dist/css/bootstrap.min.css') }}" rel="stylesheet" type="text/css"/>
<link href="{{ asset('css/bootstrap.splash.css') }}" rel="stylesheet" type="text/css"/>
<link href="{{ asset('css/splash.css') }}" rel="stylesheet" type="text/css"/>
<link href="{{ asset('images/apple-touch-icon-114x114-precomposed.png') }}" rel="apple-touch-icon-precomposed" sizes="114x114">
<link href="{{ asset('images/apple-touch-icon-72x72-precomposed.png') }}" rel="apple-touch-icon-precomposed" sizes="72x72">
<link href="{{ asset('images/apple-touch-icon-57x57-precomposed.png') }}" rel="apple-touch-icon-precomposed">
@stop
@section('body')
{{ Form::open(array('url' => 'get_started', 'id' => 'startForm')) }}
{{ Form::hidden('guest_key') }}
{{ Form::close() }}
<script>
$(document).ready(function () {
if (isStorageSupported()) {
$('[name="guest_key"]').val(localStorage.getItem('guest_key'));
}
$("#feedbackSubmit").click(function() {
//clear any errors
contactForm.clearErrors();
//do a little client-side validation -- check that each field has a value and e-mail field is in proper format
var hasErrors = false;
$('.feedbackForm input,textarea').each(function() {
if (!$(this).val()) {
hasErrors = true;
contactForm.addError($(this));
}
});
var $email = $('#email');
if (!contactForm.isValidEmail($email.val())) {
hasErrors = true;
contactForm.addError($email);
}
//if there are any errors return without sending e-mail
if (hasErrors) {
return false;
}
});
});
//namespace as not to pollute global namespace
var contactForm = {
isValidEmail: function (email) {
var regex = /^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/;
return regex.test(email);
},
clearErrors: function () {
$('#emailAlert').remove();
$('.feedbackForm .help-block').hide();
$('.feedbackForm .form-group').removeClass('has-error');
},
addError: function ($input) {
$input.siblings('.help-block').show();
$input.parent('.form-group').addClass('has-error');
},
addAjaxMessage: function(msg, isError) {
$("#feedbackSubmit").after('<div id="emailAlert" class="alert alert-' + (isError ? 'danger' : 'success') + '" style="margin-top: 5px;">' + $('<div/>').text(msg).html() + '</div>');
}
};
function isStorageSupported() {
try {
return 'localStorage' in window && window['localStorage'] !== null;
} catch (e) {
return false;
}
}
function getStarted() {
$('#startForm').submit();
}
</script>
<div class="navbar" style="margin-bottom:0px">
<div class="container">
<div class="navbar-inner">
<a class="brand" href="/"><img src=
"images/invoiceninja-logo.png"></a>
<ul class="navbar-list">
<li>{{ link_to('about', 'About Us' ) }}</li>
<li>{{ link_to('contact', 'Contact Us' ) }}</li>
<li>{{ link_to('login', Auth::check() ? 'My Account' : 'Login' ) }}</li>
</ul>
</div>
</div>
</div>
</div>
<section class="hero4" data-speed="2" data-type="background">
<div class="container">
<div class="caption">
<h1>Contact us
</h1>
</div>
</div>
</section>
<section class="about contact">
<div class="container">
<div id="contact_form" class="row">
@if (Session::has('message'))
<div class="alert alert-info">{{ Session::get('message') }}</div>
@endif
@if (Session::has('error'))
<div class="alert alert-danger">{{ Session::get('error') }}</div>
@endif
<div class="row">
<div class="col-md-7">
<h2>Questions, special requests, or just want to say hi?</h2>
<p>Fill in the form below and we'll get back to you as soon as possible. Hope to hear from you!</p>
{{ Form::open(['url' => 'contact', 'class' => 'feedbackForm']) }}
<div class="form-group">
<input type="text" class="form-control" id="name" name="name" placeholder="Name">
<span class="help-block" style="display: none;">Please enter your name.</span>
</div>
<div class="form-group">
<input type="email" class="form-control" id="email" name="email" placeholder="Email Address">
<span class="help-block" style="display: none;">Please enter a valid e-mail address.</span>
</div>
<div class="form-group">
<textarea rows="10" cols="100" class="form-control" id="message" name="message" placeholder="Message"></textarea>
<span class="help-block" style="display: none;">Please enter a message.</span>
</div>
<div class="row">
<div class="col-md-5">
<button type="submit" id="feedbackSubmit" class="btn btn-primary btn-lg">Send Message <span class="glyphicon glyphicon-send"></span></button>
</div>
</div>
{{ Form::close() }}
</div>
<div class="col-md-4 col-md-offset-1 address">
<h2>Other ways to reach us</h2>
<p><span class="glyphicon glyphicon-send"></span><a href="mailto:contact@invoiceninja.com">contact@invoiceninja.com</a></p>
<p><span class="glyphicon glyphicon-earphone"></span>+1-800-763-1948</p>
<p><span class="github"></span><div style="padding-top:10px"> &nbsp;&nbsp;<a href="https://github.com/hillelcoren/invoice-ninja" target="_blank">GitHub Project</a></div></p>
</div>
</div>
</div>
</div>
</div>
</section>
<section class="upper-footer white-bg">
<div class="container">
<div class="row">
<div class="col-md-3 center-block">
<a href="#">
<div class="cta">
<h2 onclick="getStarted()">Invoice Now <span>+</span></h2>
</div>
</a>
</div>
</div>
</div>
</section>
<footer>
<div class="navbar" style="margin-bottom:0px">
<div class="container">
<div class="social">
<!--
<a href="http://twitter.com/eas_id"><span class=
"socicon">c</span></a>
-->
<a href=
"http://facebook.com/invoiceninja" target="_blank"><span class=
"socicon">b</span></a> <a href=
"http://twitter.com/invoiceninja" target="_blank"><span class=
"socicon">a</span></a>
<p>Copyright © 2014 InvoiceNinja. All rights reserved.</p>
</div>
<div class="navbar-inner">
<ul class="navbar-list">
<li>{{ link_to('about', 'About Us' ) }}</li>
<li>{{ link_to('contact', 'Contact Us' ) }}</li>
<li>{{ link_to('login', Auth::check() ? 'My Account' : 'Login' ) }}</li>
</ul>
<!--
<ul class="navbar-list">
<li><a href="#">For developers</a></li>
<li><a href="#">Jobs</a></li>
<li><a href="#">Terms &amp; Conditions</a></li>
<li><a href="#">Our Blog</a></li>
</ul>
-->
</div>
</div>
</div>
</footer><script src="{{ asset('/js/retina-1.1.0.min.js') }}" type="text/javascript"></script>
@stop

View File

@ -94,6 +94,22 @@
<div class="navbar-form navbar-right">
@if (Auth::check() && !Auth::user()->registered)
{{ Button::sm_success_primary('Sign up', array('id' => 'signUpButton', 'data-toggle'=>'modal', 'data-target'=>'#signUpModal')) }} &nbsp;
@if (Auth::check() && Auth::user()->showSignUpPopOver())
<button id="signUpPopOver" type="button" class="btn btn-default" data-toggle="popover" data-placement="bottom" data-content="Sign up to save your work" data-html="true" style="display:none">
Sign Up
</button>
<script>
$(function() {
$('#signUpPopOver').show().popover('show').hide();
$('body').click(function() {
$('#signUpPopOver').popover('hide');
});
});
</script>
@endif
@endif
@if (Auth::check())
@ -103,7 +119,7 @@
@if (Auth::check() && Auth::user()->registered)
{{ Auth::user()->getFullName() }}
@else
My Company
Guest
@endif
</span>
<span class="caret"></span>
@ -476,4 +492,5 @@
</script>
@stop

View File

@ -20,7 +20,7 @@
'client' => 'required',
'email' => 'required',
'product_key' => 'max:20',
)); }}
)) }}
<input type="submit" style="display:none" name="submitButton" id="submitButton">
@ -128,7 +128,7 @@
<i style="display:none" data-bind="visible: actionsVisible() &amp;&amp; $parent.invoice_items().length > 1" class="fa fa-sort"></i>
</td>
<td>
{{ Former::text('product_key')->useDatalist(Product::getProductKeys($products), 'key')->onkeyup('onItemChange()')
{{ Former::text('product_key')->useDatalist(Product::getProductKeys($products), 'product_key')->onkeyup('onItemChange()')
->raw()->data_bind("value: product_key, valueUpdate: 'afterkeydown'")->addClass('datalist') }}
</td>
<td>

View File

@ -52,15 +52,9 @@
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-46031341-1');
ga('create', ANALYTICS_KEY);
ga('send', 'pageview');
</script>
@else
<style>
.navbar {
background-color: #006600 !important;
}
</style>
@endif
@yield('body')

View File

@ -0,0 +1,86 @@
@extends('public.header')
@section('content')
<section class="hero3" data-speed="2" data-type="background">
<div class="container">
<div class="caption">
<h1>WHY INVOICE NINJA?
</h1>
</div>
</div>
</section>
<section class="about center">
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<h2>Open Source Platform</h2>
<p>Free yourself from online invoicing platforms with high monthly fees and limited functionality. Being <a href="https://github.com/hillelcoren/invoice-ninja" target="_blank">open source</a> allows us fast app development, security audits by the open-course community, and we can keep it <strong>FREE!</strong></p>
</div>
</div>
</div>
</section>
<section class="about white-bg">
<div class="container">
<div class="row">
<div class="col-md-5">
<div class="screendump">
<img src="images/about1.jpg">
</div>
</div>
<div class="col-md-7">
<h2>Live PDF Creation</h2>
<p><strong>Look professional from day #1.</strong> Select one of our beautiful invoice templates to suit your company identity, switch between designs in real time to preview invoices & email them to clients with one click. The live preview PDF function was designed for an efficient and hassle-free experience, and its awesome!
</p>
</div>
</div>
</div>
</section>
<section class="about">
<div class="container">
<div class="row">
<div class="col-md-7">
<h2>Online Payments</h2>
<p><strong>Authorize.net, Beanstream, PayPal?</strong> InvoiceNinja supports the most popular online payment gateways! If you need help integrating a third party gateway we dont yet support, please contact us! Were happy to help! If you need assistance of want to learn more about online payment solutions, contact us!</p>
</div>
<div class="col-md-5">
<div class="screendump">
<img src="images/about2.jpg">
</div>
</div>
</div>
</div>
</section>
<!--
<section class="about center white-bg">
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<h2>Info about the company/story</h2>
<p>Donec id elit non mi porta gravida at eget metus.
Fusce dapibus, tellus ac cursus commodo, tortor mauris
condimentum nibh, ut fermentum massa justo sit amet
risus. Etiam porta sem malesuada magna mollis euismod.
Donec sed odio dui.</p>
</div>
</div>
</div>
</section>
-->
<section class="upper-footer">
<div class="container">
<div class="row">
<div class="col-md-3 center-block">
<a href="#">
<div class="cta">
<h2 onclick="getStarted()">Invoice Now <span>+</span></h2>
</div>
</a>
</div>
</div>
</div>
</section>
@stop

View File

@ -0,0 +1,150 @@
@extends('public.header')
@section('content')
<script>
$(document).ready(function () {
$("#feedbackSubmit").click(function() {
//clear any errors
contactForm.clearErrors();
//do a little client-side validation -- check that each field has a value and e-mail field is in proper format
var hasErrors = false;
$('.feedbackForm input,textarea').each(function() {
if (!$(this).val()) {
hasErrors = true;
contactForm.addError($(this));
}
});
var $email = $('#email');
if (!contactForm.isValidEmail($email.val())) {
hasErrors = true;
contactForm.addError($email);
}
//if there are any errors return without sending e-mail
if (hasErrors) {
return false;
}
});
});
//namespace as not to pollute global namespace
var contactForm = {
isValidEmail: function (email) {
var regex = /^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/;
return regex.test(email);
},
clearErrors: function () {
$('#emailAlert').remove();
$('.feedbackForm .help-block').hide();
$('.feedbackForm .form-group').removeClass('has-error');
},
addError: function ($input) {
$input.siblings('.help-block').show();
$input.parent('.form-group').addClass('has-error');
},
addAjaxMessage: function(msg, isError) {
$("#feedbackSubmit").after('<div id="emailAlert" class="alert alert-' + (isError ? 'danger' : 'success') + '" style="margin-top: 5px;">' + $('<div/>').text(msg).html() + '</div>');
}
};
function isStorageSupported() {
try {
return 'localStorage' in window && window['localStorage'] !== null;
} catch (e) {
return false;
}
}
function getStarted() {
$('#startForm').submit();
}
</script>
<section class="hero4" data-speed="2" data-type="background">
<div class="container">
<div class="caption">
<h1>Contact us
</h1>
</div>
</div>
</section>
<section class="about contact">
<div class="container">
<div id="contact_form" class="row">
@if (Session::has('message'))
<div class="alert alert-info">{{ Session::get('message') }}</div>
@endif
@if (Session::has('error'))
<div class="alert alert-danger">{{ Session::get('error') }}</div>
@endif
<div class="row">
<div class="col-md-7">
<h2>Questions, special requests, or just want to say hi?</h2>
<p>Fill in the form below and we'll get back to you as soon as possible. Hope to hear from you!</p>
{{ Form::open(['url' => 'contact', 'class' => 'feedbackForm']) }}
<div class="form-group">
<input type="text" class="form-control" id="name" name="name" placeholder="Name">
<span class="help-block" style="display: none;">Please enter your name.</span>
</div>
<div class="form-group">
<input type="email" class="form-control" id="email" name="email" placeholder="Email Address">
<span class="help-block" style="display: none;">Please enter a valid e-mail address.</span>
</div>
<div class="form-group">
<textarea rows="10" cols="100" class="form-control" id="message" name="message" placeholder="Message"></textarea>
<span class="help-block" style="display: none;">Please enter a message.</span>
</div>
<div class="row">
<div class="col-md-5">
<button type="submit" id="feedbackSubmit" class="btn btn-primary btn-lg">Send Message <span class="glyphicon glyphicon-send"></span></button>
</div>
</div>
{{ Form::close() }}
</div>
<div class="col-md-4 col-md-offset-1 address">
<h2>Other ways to reach us</h2>
<p><span class="glyphicon glyphicon-send"></span><a href="mailto:contact@invoiceninja.com">contact@invoiceninja.com</a></p>
<p><span class="glyphicon glyphicon-earphone"></span>+1-800-763-1948</p>
<p><span class="github"></span><div style="padding-top:10px"> &nbsp;&nbsp;<a href="https://github.com/hillelcoren/invoice-ninja" target="_blank">GitHub Project</a></div></p>
</div>
</div>
</div>
</div>
</div>
</section>
<section class="upper-footer white-bg">
<div class="container">
<div class="row">
<div class="col-md-3 center-block">
<a href="#">
<div class="cta">
<h2 onclick="getStarted()">Invoice Now <span>+</span></h2>
</div>
</a>
</div>
</div>
</div>
</section>
@stop

View File

@ -0,0 +1,112 @@
@extends('master')
@section('head')
<link href="{{ asset('vendor/bootstrap/dist/css/bootstrap.min.css') }}" rel="stylesheet" type="text/css"/>
<link href="{{ asset('css/bootstrap.splash.css') }}" rel="stylesheet" type="text/css"/>
<link href="{{ asset('css/splash.css') }}" rel="stylesheet" type="text/css"/>
<link href="{{ asset('images/apple-touch-icon-114x114-precomposed.png') }}" rel="apple-touch-icon-precomposed" sizes="114x114">
<link href="{{ asset('images/apple-touch-icon-72x72-precomposed.png') }}" rel="apple-touch-icon-precomposed" sizes="72x72">
<link href="{{ asset('images/apple-touch-icon-57x57-precomposed.png') }}" rel="apple-touch-icon-precomposed">
@stop
@section('body')
<div id="fb-root"></div>
<script>(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/all.js#xfbml=1&appId=635126583203143";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script>
{{ Form::open(array('url' => 'get_started', 'id' => 'startForm')) }}
{{ Form::hidden('guest_key') }}
{{ Form::close() }}
<script>
$(document).ready(function () {
if (isStorageSupported()) {
$('[name="guest_key"]').val(localStorage.getItem('guest_key'));
}
});
function isStorageSupported() {
try {
return 'localStorage' in window && window['localStorage'] !== null;
} catch (e) {
return false;
}
}
function getStarted() {
$('#startForm').submit();
}
</script>
<div class="navbar" style="margin-bottom:0px">
<div class="container">
<div class="navbar-inner">
<a class="brand" href="/"><img src=
"images/invoiceninja-logo.png"></a>
<ul class="navbar-list">
<li>{{ link_to('about', 'About Us' ) }}</li>
<li>{{ link_to('contact', 'Contact Us' ) }}</li>
<li>{{ link_to('login', Auth::check() ? 'My Account' : 'Login' ) }}</li>
</ul>
</div>
</div>
</div>
@yield('content')
<footer>
<div class="navbar" style="margin-bottom:0px">
<div class="container">
<div class="social">
<div class="fb-like" data-href="https://www.invoiceninja.com" data-layout="button" data-action="like" data-show-faces="false" data-share="false"></div>
<div class="fb-follow" data-href="https://www.facebook.com/invoiceninja" data-colorscheme="light" data-layout="button" data-show-faces="false"></div>
<!--
<a href="http://twitter.com/eas_id"><span class=
"socicon">c</span></a>
<a href=
"http://facebook.com/invoiceninja" target="_blank"><span class=
"socicon">b</span></a> <a href=
"http://twitter.com/invoiceninja" target="_blank"><span class=
"socicon">a</span></a>
-->
<p>Copyright © 2014 InvoiceNinja. All rights reserved.</p>
</div>
<div class="navbar-inner">
<ul class="navbar-list">
<li>{{ link_to('about', 'About Us' ) }}</li>
<li>{{ link_to('contact', 'Contact Us' ) }}</li>
<li>{{ link_to('login', Auth::check() ? 'My Account' : 'Login' ) }}</li>
</ul>
<!--
<ul class="navbar-list">
<li><a href="#">For developers</a></li>
<li><a href="#">Jobs</a></li>
<li><a href="#">Terms &amp; Conditions</a></li>
<li><a href="#">Our Blog</a></li>
</ul>
-->
</div>
</div>
</div>
</footer><script src="{{ asset('/js/retina-1.1.0.min.js') }}" type="text/javascript"></script>
@stop

113
app/views/public/splash.blade.php Executable file
View File

@ -0,0 +1,113 @@
@extends('public.header')
@section('content')
<section class="hero background" data-speed="2" data-type="background">
<div class="caption-side"></div>
<div class="container">
<div class="row" style="margin:0;">
<div class="caption-wrap">
<div class="caption">
<h1>THE <span style="color:#2299c0">SIMPLE</span> &amp;
<span style="color:#edd71e">FREE</span> WAY TO INVOICE
CLIENTS</h1>
<p>It's that easy. Stop spending time on
complicated and expensive invoicing.<br>
No fuss, just get started and <span style=
"color:#2299c0">get paid.</span></p>
</div>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-md-3 center-block">
<a href="#">
<div class="cta">
<h2 id="startButton" onclick="getStarted()">Invoice Now <span>+</span></h2>
</div>
</a>
</div>
</div>
</div>
</section>
<section class="features">
<div class="container">
<div class="row">
<div class="col-md-3 one">
<div class="box">
<div class="icon"><img src="images/icon-free.png"></div>
<h2>100% FREE, ALWAYS</h2>
<p>Invoicing with no monthly fee, because you have enough bills already! Free, now and forever! Quality invoicing to build your business and get paid.</p>
</div>
</div>
<div class="col-md-3 two">
<div class="box">
<div class="icon"><img src=
"images/icon-opensource.png"></div>
<h2>OPEN-SOURCE</h2>
<p>Cloud-based, super secure, and user-developed. Open source platforms are a better way to do business (and save the world). Need we say more?</p>
</div>
</div>
<div class="col-md-3 three">
<div class="box">
<div class="icon"><img src="images/icon-pdf.png"></div>
<h2>LIVE .PDF VIEW</h2>
<p>Create beautiful email-ready .PDF invoices created instantly as you type. Our Save & send feature saves you time and impresses clients.</p>
</div>
</div>
<div class="col-md-3 four">
<div class="box">
<div class="icon"><img src=
"images/icon-payment.png"></div>
<h2>ONLINE PAYMENTS</h2>
<p>PayPal? Authorize.Net? Stripe? We support many payment technologies and if you need help or advice well lend a hand (were pretty friendly).</p>
</div>
</div>
</div>
</div>
</section>
<section class="blue">
<div class="container">
<div class="row">
<div class="col-md-6">
<!--<h1>2.500 <span>sent invoices</span></h1>-->
</div>
<div class="col-md-6">
<!--<h1>$350.456 <span>billed</span></h1>-->
</div>
</div>
</div>
</section>
<section class="hero2">
<div class="container">
<div class="caption">
<h1>SIMPLE, INTUITIVE INVOICING.</h1>
</div>
</div>
</section>
<section class="upper-footer">
<div class="container">
<div class="row">
<div class="col-md-3 center-block">
<a href="#">
<div class="cta">
<h2 onclick="getStarted()">Invoice Now <span>+</span></h2>
</div>
</a>
</div>
</div>
</div>
</section>
@stop

View File

@ -1,29 +1,6 @@
@extends('master')
@extends('public.header')
@section('head')
<link href="{{ asset('css/bootstrap.splash.css') }}" rel="stylesheet" type="text/css"/>
<link href="{{ asset('css/splash.css') }}" rel="stylesheet" type="text/css"/>
<link href="{{ asset('images/apple-touch-icon-114x114-precomposed.png') }}" rel="apple-touch-icon-precomposed" sizes="114x114">
<link href="{{ asset('images/apple-touch-icon-72x72-precomposed.png') }}" rel="apple-touch-icon-precomposed" sizes="72x72">
<link href="{{ asset('images/apple-touch-icon-57x57-precomposed.png') }}" rel="apple-touch-icon-precomposed">
@stop
@section('body')
<div class="navbar" style="margin-bottom:0px">
<div class="container">
<div class="navbar-inner">
<a class="brand" href="#"><img src=
"images/invoiceninja-logo.png"></a>
<ul class="navbar-list">
<li>{{ link_to('about', 'About Us' ) }}</li>
<li>{{ link_to('contact', 'Contact Us' ) }}</li>
<li>{{ link_to('login', Auth::check() ? 'My Account' : 'Login' ) }}</li>
</ul>
</div>
</div>
</div>
</div>
@section('content')
<section class="hero3" data-speed="2" data-type="background">
<div class="container">
@ -170,41 +147,4 @@
<p>&nbsp;</p>
<p>&nbsp;</p>
<footer>
<div class="navbar" style="margin-bottom:0px">
<div class="container">
<div class="social">
<!--
<a href="http://twitter.com/eas_id"><span class=
"socicon">c</span></a>
-->
<a href=
"http://facebook.com/invoiceninja" target="_blank"><span class=
"socicon">b</span></a> <a href=
"http://twitter.com/invoiceninja" target="_blank"><span class=
"socicon">a</span></a>
<p>Copyright © 2014 InvoiceNinja. All rights reserved.</p>
</div>
<div class="navbar-inner">
<ul class="navbar-list">
<li>{{ link_to('about', 'About Us' ) }}</li>
<li>{{ link_to('contact', 'Contact Us' ) }}</li>
<li>{{ link_to('login', Auth::check() ? 'My Account' : 'Login' ) }}</li>
</ul>
<!--
<ul class="navbar-list">
<li><a href="#">For developers</a></li>
<li><a href="#">Jobs</a></li>
<li><a href="#">Terms &amp; Conditions</a></li>
<li><a href="#">Our Blog</a></li>
</ul>
-->
</div>
</div>
</div>
</footer><script src="{{ asset('/js/retina-1.1.0.min.js') }}" type="text/javascript"></script>
@stop
@stop

View File

@ -1,196 +0,0 @@
@extends('master')
@section('head')
<link href="{{ asset('css/bootstrap.splash.css') }}" rel="stylesheet" type="text/css"/>
<link href="{{ asset('css/splash.css') }}" rel="stylesheet" type="text/css"/>
<link href="{{ asset('images/apple-touch-icon-114x114-precomposed.png') }}" rel="apple-touch-icon-precomposed" sizes="114x114">
<link href="{{ asset('images/apple-touch-icon-72x72-precomposed.png') }}" rel="apple-touch-icon-precomposed" sizes="72x72">
<link href="{{ asset('images/apple-touch-icon-57x57-precomposed.png') }}" rel="apple-touch-icon-precomposed">
@stop
@section('body')
{{ Form::open(array('url' => 'get_started', 'id' => 'startForm')) }}
{{ Form::hidden('guest_key') }}
{{ Form::close() }}
<script>
$(document).ready(function () {
if (isStorageSupported()) {
$('[name="guest_key"]').val(localStorage.getItem('guest_key'));
}
});
function isStorageSupported() {
try {
return 'localStorage' in window && window['localStorage'] !== null;
} catch (e) {
return false;
}
}
function getStarted() {
$('#startForm').submit();
}
</script>
<div class="navbar" style="margin-bottom:0px">
<div class="container">
<div class="navbar-inner">
<a class="brand" href="/"><img src=
"images/invoiceninja-logo.png"></a>
<ul class="navbar-list">
<li>{{ link_to('about', 'About Us' ) }}</li>
<li>{{ link_to('contact', 'Contact Us' ) }}</li>
<li>{{ link_to('login', Auth::check() ? 'My Account' : 'Login' ) }}</li>
</ul>
</div>
</div>
</div>
<section class="hero background" data-speed="2" data-type="background">
<div class="caption-side"></div>
<div class="container">
<div class="row" style="margin:0;">
<div class="caption-wrap">
<div class="caption">
<h1>THE <span style="color:#2299c0">SIMPLE</span> &amp;
<span style="color:#edd71e">FREE</span> WAY TO INVOICE
CLIENTS</h1>
<p>It's that easy. Stop spending time on
complicated and expensive invoicing.<br>
No fuss, just get started and <span style=
"color:#2299c0">get paid.</span></p>
</div>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-md-3 center-block">
<a href="#">
<div class="cta">
<h2 id="startButton" onclick="getStarted()">Invoice Now <span>+</span></h2>
</div>
</a>
</div>
</div>
</div>
</section>
<section class="features">
<div class="container">
<div class="row">
<div class="col-md-3 one">
<div class="box">
<div class="icon"><img src="images/icon-free.png"></div>
<h2>100% FREE, ALWAYS</h2>
<p>Invoicing with no monthly fee, because you have enough bills already! Free, now and forever! Quality invoicing to build your business and get paid.</p>
</div>
</div>
<div class="col-md-3 two">
<div class="box">
<div class="icon"><img src=
"images/icon-opensource.png"></div>
<h2>OPEN-SOURCE</h2>
<p>Cloud-based, super secure, and user-developed. Open source platforms are a better way to do business (and save the world). Need we say more?</p>
</div>
</div>
<div class="col-md-3 three">
<div class="box">
<div class="icon"><img src="images/icon-pdf.png"></div>
<h2>LIVE .PDF VIEW</h2>
<p>Create beautiful email-ready .PDF invoices created instantly as you type. Our Save & send feature saves you time and impresses clients.</p>
</div>
</div>
<div class="col-md-3 four">
<div class="box">
<div class="icon"><img src=
"images/icon-payment.png"></div>
<h2>ONLINE PAYMENTS</h2>
<p>PayPal? Authorize.Net? Stripe? We support many payment technologies and if you need help or advice well lend a hand (were pretty friendly).</p>
</div>
</div>
</div>
</div>
</section>
<section class="blue">
<div class="container">
<div class="row">
<div class="col-md-6">
<!--<h1>2.500 <span>sent invoices</span></h1>-->
</div>
<div class="col-md-6">
<!--<h1>$350.456 <span>billed</span></h1>-->
</div>
</div>
</div>
</section>
<section class="hero2">
<div class="container">
<div class="caption">
<h1>SIMPLE, INTUITIVE INVOICING.</h1>
</div>
</div>
</section>
<section class="upper-footer">
<div class="container">
<div class="row">
<div class="col-md-3 center-block">
<a href="#">
<div class="cta">
<h2 onclick="getStarted()">Invoice Now <span>+</span></h2>
</div>
</a>
</div>
</div>
</div>
</section>
<footer>
<div class="navbar" style="margin-bottom:0px">
<div class="container">
<div class="social">
<!--
<a href="http://twitter.com/eas_id"><span class=
"socicon">c</span></a>
-->
<a href=
"http://facebook.com/invoiceninja" target="_blank"><span class=
"socicon">b</span></a> <a href=
"http://twitter.com/invoiceninja" target="_blank"><span class=
"socicon">a</span></a>
<p>Copyright © 2014 InvoiceNinja. All rights reserved.</p>
</div>
<div class="navbar-inner">
<ul class="navbar-list">
<li>{{ link_to('about', 'About Us' ) }}</li>
<li>{{ link_to('contact', 'Contact Us' ) }}</li>
<li>{{ link_to('login', Auth::check() ? 'My Account' : 'Login' ) }}</li>
</ul>
<!--
<ul class="navbar-list">
<li><a href="#">For developers</a></li>
<li><a href="#">Jobs</a></li>
<li><a href="#">Terms &amp; Conditions</a></li>
<li><a href="#">Our Blog</a></li>
</ul>
-->
</div>
</div>
</div>
</footer><script src="{{ asset('/js/retina-1.1.0.min.js') }}" type="text/javascript"></script>
@stop

View File

@ -616,6 +616,9 @@ color: #fff;
background-color: #08273c;
border-color: #08273c;
}
#signUpPopOver {
cursor: pointer;
}
@media (max-width: 767px) {
.navbar-default .navbar-nav .open .dropdown-menu > li > a {
color: #ecf0f1;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 KiB

After

Width:  |  Height:  |  Size: 15 KiB