Skip to content

Commit

Permalink
added completed templates
Browse files Browse the repository at this point in the history
  • Loading branch information
Ryan Irelan committed Sep 8, 2021
1 parent 6dbea4e commit 7c66c6e
Show file tree
Hide file tree
Showing 12 changed files with 430 additions and 0 deletions.
Empty file added templates/.gitkeep
Empty file.
49 changes: 49 additions & 0 deletions templates/_components/forgot-password-form.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{% import '_macros/forms' as forms %}
<div class="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
<div class="bg-white py-8 px-4 shadow sm:rounded-lg sm:px-10">
<form sprig s-method="post" s-action="users/send-password-reset-email" s-indicator="#spinner" class="space-y-6">
{{ csrfInput() }}
<div>
<label for="email" class="block text-sm font-medium text-gray-700">
Your Account Email Address
</label>
<div class="mt-1">
<input id="email" name="loginName" type="email" autocomplete="email" class="appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none sm:text-sm" required value="">
</div>
</div>
<div>
<button type="submit" class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-gray-800 hover:bg-gray-700 focus:outline-none">
<div id="spinner" class="htmx-indicator pr-4">
<svg class="animate-spin h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
</div>
Request Password Reset
</button>
{% if errors is defined %}
<div class="rounded-lg bg-red-50 p-4 mt-4 border-2 border-red-100">
<div class="flex">
<div class="ml-3">
{{ forms.errorsList(errors) }}
</div>
</div>
</div>

{% endif %}

{% if success is defined and success %}
<div class="rounded-lg bg-green-50 p-4 mt-4 border-2 border-green-100">
<div class="flex">
<div class="ml-3">
<p class="text-sm font-medium text-green-800">
We just sent an email to your account email address. Use the link in the email to reset your password.
</p>
</div>
</div>
</div>
{% endif %}
</div>
</form>
</div>
</div>
68 changes: 68 additions & 0 deletions templates/_components/register-form.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{% import '_macros/forms' as forms %}
{% set user = user ?? null %}

<div class="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
<div class="bg-white py-8 px-4 shadow sm:rounded-lg sm:px-10">
<form sprig s-method="post" s-action="users/save-user" s-indicator="#spinner" class="space-y-6">
<div>
<label for="email" class="block text-sm font-medium text-gray-700">
First Name
</label>
<div class="mt-1">
<input id="first-name" name="firstName" type="text" autocomplete="first-name" class="appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 sm:text-sm" required value="{{ user.firstName ?? null }}">
</div>
{{ user ? forms.errorsList(user.getErrors('firstName')) }}
</div>
<div>
<label for="email" class="block text-sm font-medium text-gray-700">
Last Name
</label>
<div class="mt-1">
<input id="last-name" name="lastName" type="text" autocomplete="last-name" class="appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none sm:text-sm" required value="{{ user.lastName ?? null }}">
</div>
{{ user ? forms.errorsList(user.getErrors('lastName')) }}
</div>
<div>
<label for="email" class="block text-sm font-medium text-gray-700">
Email
</label>
<div class="mt-1">
<input id="email" name="email" type="email" autocomplete="email" class="appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none sm:text-sm" required value="{{ user.email ?? null }}">
</div>
{{ user ? forms.errorsList(user.getErrors('email')) }}
</div>

<div>
<label for="password" class="block text-sm font-medium text-gray-700">
Password
</label>
<div class="mt-1">
<input id="password" name="password" type="password" autocomplete="current-password" required class="appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none sm:text-sm">
</div>
{{ user ? forms.errorsList(user.getErrors('password')) }}
</div>
<div>
<button type="submit" class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-gray-800 hover:bg-gray-700 focus:outline-none">
<div id="spinner" class="htmx-indicator pr-4">
<svg class="animate-spin h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
</div>
Register
</button>
{% if success is defined and success %}
<div class="rounded-lg bg-green-50 p-4 mt-4 border-2 border-green-100">
<div class="flex">
<div class="ml-3">
<p class="text-sm font-medium text-green-800">
We created your account! Please check your email to verify your email address before logging in.
</p>
</div>
</div>
</div>
{% endif %}
</div>
</form>
</div>
</div>
Empty file.
15 changes: 15 additions & 0 deletions templates/_layout.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet">
<title>CraftQuest</title>
</head>
<body>
{% block headJs %}{% endblock %}
{% block headCss %}{% endblock %}
{% block content %}{% endblock %}
{% block footerJs %}{% endblock %}
</body>
</html>
5 changes: 5 additions & 0 deletions templates/_macros/forms.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{% macro errorsList(errors) %}
{% if errors %}
{{ ul(errors, {class: 'mt-2 text-sm text-red-600'}) }}
{% endif %}
{% endmacro %}
53 changes: 53 additions & 0 deletions templates/dashboard/index.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{% extends "_layout" %}
{% requireLogin %}
{% block content %}
<div class="relative h-screen flex overflow-hidden bg-gray-100">
<div class="hidden lg:flex lg:flex-shrink-0">
<div class="flex flex-col w-64">
<div class="flex flex-col flex-grow bg-gray-900 pt-5 pb-4 overflow-y-auto">
<div class="flex items-center flex-shrink-0 px-4">
<img class="h-8 w-auto" src="https://craftquest.io/img/logo.svg" alt="CraftQuest"">
</div>
<nav class="mt-5 flex-1 flex flex-col divide-y divide-black overflow-y-auto" aria-label="Sidebar">
<div class="px-2 space-y-1">
<a href="/dashboard" class="bg-gray-800 text-white group flex items-center px-2 py-2 text-sm leading-6 font-medium rounded-md" aria-current="page">
<svg class="mr-4 flex-shrink-0 h-6 w-6 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
</svg>
Home
</a>
<a href="/logout" class="text-gray-400 hover:text-white hover:bg-gray-800 group flex items-center px-2 py-2 text-sm leading-6 font-medium rounded-md">
<svg xmlns="http://www.w3.org/2000/svg" class="mr-4 flex-shrink-0 h-6 w-6 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" />
</svg>
Logout
</a>
</div>
</nav>
</div>
</div>
</div>
<div class="flex-1 overflow-auto focus:outline-none">
<main class="flex-1 relative pb-8 z-0 overflow-y-auto">
<div class="bg-white shadow">
<div class="px-4 sm:px-6 lg:max-w-6xl lg:mx-auto lg:px-8">
<div class="py-6 md:flex md:items-center md:justify-between lg:border-t lg:border-gray-200">
<div class="flex-1 min-w-0">
<div class="flex items-center">
<div>
<div class="flex items-center">
<h1 class="ml-3 text-2xl font-bold leading-7 text-gray-900 sm:leading-9 sm:truncate">
Welcome, {{ currentUser.firstName }}!
</h1>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</main>
</div>
</div>
{% endblock %}
23 changes: 23 additions & 0 deletions templates/forgot-password.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{% extends "_layout" %}
{% if currentUser %} {% redirect "/dashboard" %} {% endif %}
{% block headJs %}
{{ sprig.script }}
{% endblock %}
{% block headCss %}
<style>
.htmx-indicator { display: none; }
.htmx-request.htmx-indicator { display: block; }
</style>
{% endblock %}

{% block content %}
<div class="min-h-screen bg-gray-50 flex flex-col justify-center py-12 sm:px-6 lg:px-8">
<div class="sm:mx-auto sm:w-full sm:max-w-md">
<img class="mx-auto h-12 w-auto" src="https://craftquest.io/img/craftquest-logo-dark.svg" alt="CraftQuest">
<h2 class="mt-6 text-center text-3xl font-bold text-gray-800">
Oops! Reset Your Password
</h2>
</div>
{{ sprig('_components/forgot-password-form') }}
</div>
{% endblock %}
49 changes: 49 additions & 0 deletions templates/index.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{% extends "_layout" %}
{% block content %}
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 mt-6">
<div class="max-w-3xl mx-auto">
<img src="https://craftquest.io/img/craftquest-logo-dark.svg" class="h-12"/>
<h1 class="text-2xl mt-6 mb-6 font-extrabold">Front-end Registration Templates</h1>
<ul role="list" class="divide-y divide-gray-200">
<li class="py-4 pl-4 bg-gray-100">
<a class="underline" href="{{ url('login') }}">Log In</a> (<a href="">source</a>)
</li>
<li class="py-4 pl-4">
<a class="underline" href="{{ url('register') }}">Register</a> (<a href="">source</a>)
</li>
<li class="py-4 pl-4 bg-gray-100">
<a class="underline" href="{{ url('forgot-password') }}">Forgot Password Form</a> (<a href="">source</a>)
</li>
<li class="py-4 pl-4">
<a class="underline" href="{{ url('setpassword', {id: '12345', code: '12345'}) }}">Set Password</a> (<a href="">source</a>)<br>
Requires a valid reset password token in URL parameter.
</li>
<li class="py-4 pl-4 bg-gray-100">
<a class="underline" href="{{ url('dashboard') }}">Dashboard</a> (<a href="">source</a>)
</li>
<li class="py-4 pl-4">
<a class="underline" href="{{ url('logout') }}">Log Out</a> (action only)
</li>
</ul>

<div class="mt-6 border-t-2 border-gray-200 pt-6">
<p class="mt-2">Templates and settings for a reliable front-end user registration flow. Provided by <a class="underline" href="https://craftquest.io">CraftQuest</a></p>
<p class="mt-2"><em>The templates are only meant as example code, not to be copy and pasted into your project. Use code, settings, and interactions as a guide for your own project.</em></p>

<h3 class="text-xl mt-4">License Constraints</h3>
Requires Craft Pro license (can use trial version for testing locally.

<h3 class="text-xl mt-4">Plugins Used</h3>
<a class="underline" href="https://putyourlightson.com/sprig">Sprig</a>

<h3 class="text-xl mt-4">Credits & Acknowledgements</h3>
<ul class="mt-2">
<li><a class="underline" href="https://tailwindcss.com">Tailwind</a> by Tailwind Labs for the style framework</li>
<li><a class="underline" href="https://tailwindui.com">Tailwind UI</a> by Tailwind Labs for the starter styles</li>
<li><a class="underline" href="https://putyourlightson.com/sprig">Sprig</a> by Ben Croker at Put Your Lights On for the Javascript-free reactivity</li>
</ul>

</div>
</div>
</div>
{% endblock %}
70 changes: 70 additions & 0 deletions templates/login.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
{% extends "_layout" %}
{% if currentUser %} {% redirect "/dashboard" %}{% endif %}
{% import '_macros/forms' as forms %}
{% set user = user ?? null %}
{% block content %}
<div class="min-h-screen bg-gray-50 flex flex-col justify-center py-12 sm:px-6 lg:px-8">
<div class="sm:mx-auto sm:w-full sm:max-w-md">
<img class="mx-auto h-12 w-auto" src="https://craftquest.io/img/craftquest-logo-dark.svg" alt="CraftQuest">
<h2 class="mt-6 text-center text-3xl font-bold text-gray-800">
Welcome Back!
</h2>
</div>
<div class="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
<div class="bg-white py-8 px-4 shadow sm:rounded-lg sm:px-10">
<form method="post" class="space-y-6">
{{ csrfInput() }}
{{ actionInput('users/login') }}
<div>
<label for="email" class="block text-sm font-medium text-gray-700">
Email
</label>
<div class="mt-1">
<input id="email" name="loginName" type="email" autocomplete="email" class="appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none sm:text-sm" required value="{{ user.email ?? null }}">
</div>
{{ user ? forms.errorsList(user.getErrors('loginName')) }}
</div>

<div>
<label for="password" class="block text-sm font-medium text-gray-700">
Password
</label>
<div class="mt-1">
<input id="password" name="password" type="password" autocomplete="current-password" required class="appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none sm:text-sm">
</div>
{{ user ? forms.errorsList(user.getErrors('password')) }}
</div>

<div class="flex items-center justify-between">
<div class="text-sm">
<a href="/forgot-password" class="font-medium text-indigo-600 hover:text-indigo-500">
Forgot your password?
</a>
</div>
<div class="text-sm">
<a href="/register" class="font-medium text-indigo-600 hover:text-indigo-500">
Need an account?
</a>
</div>
</div>
{% if errorMessage is defined %}
<div class="rounded-lg bg-red-50 p-4 mt-4 border-2 border-red-100">
<div class="flex">
<div class="ml-3">
<p class="text-sm font-medium text-red-800">
{{ errorMessage }}
</p>
</div>
</div>
</div>
{% endif %}
<div>
<button type="submit" class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-gray-800 hover:bg-gray-700 focus:outline-none">
Log In
</button>
</div>
</form>
</div>
</div>
</div>
{% endblock %}
22 changes: 22 additions & 0 deletions templates/register.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{% extends "_layout" %}
{% if currentUser %} {% redirect "/dashboard" %} {% endif %}
{% block headJs %}
{{ sprig.script }}
{% endblock %}
{% block headCss %}
<style>
.htmx-indicator { display: none; }
.htmx-request.htmx-indicator { display: block; }
</style>
{% endblock %}
{% block content %}
<div class="min-h-screen bg-gray-50 flex flex-col justify-center py-12 sm:px-6 lg:px-8">
<div class="sm:mx-auto sm:w-full sm:max-w-md">
<img class="mx-auto h-12 w-auto" src="https://craftquest.io/img/craftquest-logo-dark.svg" alt="CraftQuest">
<h2 class="mt-6 text-center text-3xl font-bold text-gray-800">
Create Your Free Account
</h2>
</div>
{{ sprig('_components/register-form') }}
</div>
{% endblock %}
Loading

0 comments on commit 7c66c6e

Please sign in to comment.