├── vite.config.js
├── src
├── supabase
│ └── supabase-client.jsx
├── components
│ ├── Secret.jsx
│ ├── EmptyComponent.jsx
│ ├── Home.jsx
│ ├── UserStatus.jsx
│ ├── About.jsx
│ ├── Login.jsx
│ └── Register.jsx
├── index.css
├── context
│ └── AuthContext.jsx
├── App.jsx
├── App.css
└── main.jsx
├── .gitignore
├── index.html
└── .eslintrc.cjs
/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 |
4 | // https://vitejs.dev/config/
5 | export default defineConfig({
6 | plugins: [react()],
7 | })
8 |
--------------------------------------------------------------------------------
/src/supabase/supabase-client.jsx:
--------------------------------------------------------------------------------
1 | import { createClient } from "@supabase/supabase-js";
2 |
3 | export const supabase = createClient(
4 | import.meta.env.VITE_SUPABASE_URL,
5 | import.meta.env.VITE_SUPABASE_API_KEY
6 | )
--------------------------------------------------------------------------------
/src/components/Secret.jsx:
--------------------------------------------------------------------------------
1 | export const Secret = () => {
2 |
3 | return (
4 | <>
5 |
Tajemství
6 |
7 | Tajná stránka jen pro registrované uživatele.
8 | >
9 | );
10 | }
11 |
12 | export default Secret;
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | :root {
2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
3 | line-height: 1.5;
4 | font-weight: 400;
5 |
6 | font-synthesis: none;
7 | text-rendering: optimizeLegibility;
8 | -webkit-font-smoothing: antialiased;
9 | -moz-osx-font-smoothing: grayscale;
10 | }
11 |
--------------------------------------------------------------------------------
/src/components/EmptyComponent.jsx:
--------------------------------------------------------------------------------
1 | export function EmptyComponent() {
2 | return (
3 |
4 |
Component
5 |
value
6 |
7 |
8 | );
9 | }
10 |
11 | export default EmptyComponent;
--------------------------------------------------------------------------------
/src/components/Home.jsx:
--------------------------------------------------------------------------------
1 | export function Home() {
2 |
3 | return (
4 | <>
5 | Úvod / Homepage
6 |
7 | Lorem ipsum, dolor sit amet consectetur adipisicing elit. Magnam provident iusto deleniti nulla nihil quasi quae pariatur, architecto hic aspernatur.
8 | >
9 | );
10 | }
11 |
12 | export default Home;
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/src/components/UserStatus.jsx:
--------------------------------------------------------------------------------
1 | import {useAuth} from '../context/AuthContext'
2 |
3 | export function UserStatus() {
4 |
5 | const {user, isAuth} = useAuth()
6 |
7 | return (
8 |
9 |
10 | {isAuth
11 | ?
{user.firstName} {user.lastName}
12 | :
Neni prihlaseny
13 | }
14 |
15 |
16 | );
17 | }
18 |
19 | export default UserStatus;
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite + React
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/components/About.jsx:
--------------------------------------------------------------------------------
1 | export function About() {
2 |
3 | return (
4 | <>
5 | O nás
6 |
7 |
8 | - Lorem, ipsum dolor sit amet consectetur adipisicing.
9 | - Explicabo quis dolorum suscipit. Deserunt, corporis delectus.
10 | - Eius libero quaerat, itaque exercitationem architecto modi.
11 | - Eos eius atque vero laudantium, eum dolores!
12 | - Fuga harum, saepe quos ratione dolorum omnis.
13 |
14 |
15 | >
16 | );
17 | }
18 |
19 | export default About;
--------------------------------------------------------------------------------
/src/context/AuthContext.jsx:
--------------------------------------------------------------------------------
1 | import { createContext, useContext, useEffect, useState } from "react"
2 | import { supabase } from "../supabase/supabase-client"
3 |
4 | const AuthContext = createContext({});
5 |
6 | export const useAuth = () => useContext(AuthContext)
7 |
8 |
9 |
10 |
11 | export function AuthProvider({children}) {
12 |
13 | const [user, setUser] = useState(null)
14 | const [isAuth, setIsAuth] = useState(false)
15 |
16 | return (
17 |
21 | {children}
22 |
23 | )
24 |
25 | }
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: { browser: true, es2020: true },
4 | extends: [
5 | 'eslint:recommended',
6 | 'plugin:react/recommended',
7 | 'plugin:react/jsx-runtime',
8 | 'plugin:react-hooks/recommended',
9 | ],
10 | ignorePatterns: ['dist', '.eslintrc.cjs'],
11 | parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
12 | settings: { react: { version: '18.2' } },
13 | plugins: ['react-refresh'],
14 | rules: {
15 | 'react/prop-types': 0,
16 | 'react/jsx-no-target-blank': 'off',
17 | 'react-refresh/only-export-components': [
18 | 'warn',
19 | { allowConstantExport: true },
20 | ],
21 | },
22 | }
23 |
--------------------------------------------------------------------------------
/src/App.jsx:
--------------------------------------------------------------------------------
1 | import './App.css'
2 |
3 | import {NavLink, Outlet} from 'react-router-dom'
4 |
5 | import UserStatus from './components/UserStatus'
6 | function App() {
7 | return (
8 | <>
9 | Supabase + Auth + Router
10 |
11 |
12 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | >
30 | )
31 | }
32 |
33 | export default App
34 |
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | .header {
2 | display: flex;
3 | justify-content: space-between;
4 | align-items: center;
5 | }
6 |
7 | .menu {
8 | display: flex;
9 | gap: 5px;
10 | }
11 |
12 | .menu a {
13 | padding: 10px 20px;
14 | background: #d5d5d5;
15 | text-decoration: none;
16 | color: navy;
17 | }
18 |
19 | .menu a:hover {
20 | background: #b5b5b5;
21 | }
22 |
23 | .menu a.active {
24 | background: dodgerblue;
25 | color: white;
26 | }
27 |
28 |
29 | .user-status {
30 | padding: 10px 20px;
31 | border: 5px solid dodgerblue;
32 | }
33 |
34 |
35 |
36 | .main {
37 | margin: 2em 0;
38 | padding: 1em;
39 | border: 5px solid silver;
40 | }
41 |
42 |
43 | .form-field {
44 | display: flex;
45 | align-items: baseline;
46 | max-width: 350px;
47 | }
48 |
49 | .form-field label {
50 | flex: 0 1 30%;
51 | display: block;
52 | margin-bottom: 10px;
53 | }
54 |
55 | .form-field input {
56 | flex: 0 1 70%;
57 | padding: 5px;
58 | }
59 |
60 |
--------------------------------------------------------------------------------
/src/main.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom/client'
3 | import './index.css'
4 |
5 | import {BrowserRouter, Routes, Route} from 'react-router-dom'
6 |
7 | import {AuthProvider} from './context/AuthContext'
8 |
9 | import App from './App.jsx'
10 | import Home from './components/Home'
11 | import About from './components/About'
12 | import Secret from './components/Secret'
13 | import Login from './components/Login'
14 | import Register from './components/Register'
15 |
16 | ReactDOM.createRoot(document.getElementById('root')).render(
17 |
18 |
19 |
20 |
21 | }>
22 | } />
23 | } />
24 | } />
25 | } />
26 | } />
27 |
28 |
29 |
30 |
31 | ,
32 | )
33 |
--------------------------------------------------------------------------------
/src/components/Login.jsx:
--------------------------------------------------------------------------------
1 | import {useState} from 'react'
2 | import {Link} from 'react-router-dom'
3 |
4 | import {supabase} from '../supabase/supabase-client'
5 |
6 | export const Login = () => {
7 |
8 | const [email, setEmail] = useState('')
9 | const [password, setPassword] = useState('')
10 |
11 | const handleSubmit = async (e) =>{
12 | e.preventDefault()
13 | console.log('Prihlasuji...', email, password)
14 |
15 | const {data, error} = await supabase.auth.signInWithPassword({ email, password });
16 |
17 | if (!error && data) {
18 | console.log(data)
19 | }
20 |
21 | if (error) {
22 | console.log(error)
23 | }
24 | }
25 |
26 | return (
27 | <>
28 | Přihlášení
29 |
30 |
54 | >
55 | )
56 | }
57 |
58 | export default Login
--------------------------------------------------------------------------------
/src/components/Register.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from 'react'
2 |
3 | import {supabase} from './../supabase/supabase-client'
4 |
5 | export function Register() {
6 | const [email, setEmail] = useState('')
7 | const [password, setPassword] = useState('')
8 | const [firstName, setFirstName] = useState('')
9 | const [lastName, setLastName] = useState('')
10 | const [age, setAge] = useState('')
11 |
12 | const [message, setMessage] = useState(null)
13 |
14 | const handleSubmit = async (e) =>{
15 | e.preventDefault()
16 |
17 | setMessage(null)
18 |
19 | if (email === '' || password === '') {
20 | return
21 | }
22 |
23 | const { data, error } = await supabase.auth.signUp({
24 | email,
25 | password,
26 | options: {
27 | data: {
28 | firstName,
29 | lastName,
30 | age,
31 | }
32 | }
33 | });
34 |
35 | if (!error && data) {
36 | setMessage("Registration Successful. Check your email to confirm your account");
37 | console.log(data)
38 | }
39 |
40 | if (error) {
41 | console.log(error)
42 | }
43 |
44 | }
45 |
46 | return (
47 | <>
48 | Registrace
49 |
50 | {message && {message}
}
51 |
52 |
103 | >
104 | )
105 | }
106 |
107 | export default Register;
--------------------------------------------------------------------------------