implement just for you pages with phoenix-react

This commit is contained in:
Silas 2021-11-26 20:04:45 -05:00
parent bb09b926d9
commit 7b82a95e01
Signed by: silentsilas
GPG Key ID: 4199EFB7DAA34349
20 changed files with 1246 additions and 10998 deletions

View File

@ -1,5 +1,6 @@
{
"presets": [
"@babel/preset-env"
"@babel/preset-env",
"@babel/preset-react"
]
}

View File

@ -1,5 +1,5 @@
/* This file is for your main application css. */
@import "./phoenix.css";
/* @import "./phoenix.css"; */
/* LiveView specific classes for your customizations */
.phx-no-feedback.invalid-feedback,

View File

@ -1,7 +1,8 @@
// We need to import the CSS so that webpack will load it.
// The MiniCssExtractPlugin is used to separate it out into
// its own CSS file.
// import "../css/app.css"
import "react-phoenix"
import "../css/app.css"
// const _css = require("../css/app.css");
// webpack automatically bundles all modules in your
@ -17,10 +18,11 @@ import "phoenix_html"
import {Socket} from "phoenix"
import topbar from "topbar"
import {LiveSocket} from "phoenix_live_view"
import React from "react";
import ReactDOM from "react-dom";
import SplashPage from './pages/SplashPage';
import { GlobalStyle } from '@intended/intended-ui';
import JustPage from './pages/JustPage'
import ForPage from './pages/ForPage'
import YouPage from './pages/YouPage'
let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
let liveSocket = new LiveSocket("/live", Socket, {params: {_csrf_token: csrfToken}})
@ -39,10 +41,34 @@ liveSocket.connect()
// >> liveSocket.disableLatencySim()
window.liveSocket = liveSocket
ReactDOM.render(<div>
<GlobalStyle />
<SplashPage />
</div>
,
document.getElementById("root")
);
window.Components = {
SplashPage, JustPage, ForPage, YouPage
}
// const root_el = document.getElementById("root");
// const page = root_el.getAttribute("page")
// let result;
// switch(page) {
// case "splash":
// result = <SplashPage />
// break;
// case "just":
// result = <JustPage />
// break;
// case "for":
// case "you":
// case "identify":
// case "revealed":
// default:
// null
// break;
// }
// ReactDOM.render(<React.StrictMode>
// <GlobalStyle />
// { result }
// </React.StrictMode>
// ,
// root_el
// );

View File

@ -0,0 +1,61 @@
import React, { useState } from "react";
import { ProgressIndicator, Header2, Button, IconArrow, Label, Input, Select, CenteredContainer, SpaceBetweenContainer, Spacer, TextAlignWrapper, GlobalStyle } from "@intended/intended-ui";
const ForPage = () => {
const [recipientInput, setRecipientInput] = useState("");
const [serviceSelect, setServiceSelect] = useState("");
const handleRecipientInputChange = (
e: React.ChangeEvent<HTMLInputElement>
) => {
setRecipientInput(e.target.value);
};
const handleServiceChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
setServiceSelect(e.target.value);
};
return (
<React.StrictMode>
<GlobalStyle />
<CenteredContainer fullscreen>
<CenteredContainer>
<ProgressIndicator currentProgress={2} />
<Header2>Tell Someone</Header2>
<SpaceBetweenContainer>
<Label htmlFor="recipientInput">Who gets to know the secret?</Label>
<Label htmlFor="recipientInput">Required*</Label>
</SpaceBetweenContainer>
<Input
variant="primary"
id="recipientInput"
value={recipientInput}
onChange={handleRecipientInputChange}
placeholder="Username or Email"
/>
<Spacer space="2.5rem" />
<TextAlignWrapper align="left">
<Label htmlFor="serviceSelector">
What type of account is the above username or email associated with?
</Label>
</TextAlignWrapper>
<Select
id="serviceSelector"
onChange={handleServiceChange}
value={serviceSelect}
/>
<Spacer space="3rem" />
<SpaceBetweenContainer>
<Button variant="secondary" onClick={() => window.location.href = "/just"}>
<IconArrow arrowDirection="left" />
</Button>
<Button onClick={() => window.location.href = "/just/for/you"}>Generate Secret Code</Button>
</SpaceBetweenContainer>
</CenteredContainer>
</CenteredContainer>
</React.StrictMode>
);
};
export default ForPage;

View File

@ -0,0 +1,57 @@
import React, { useState } from "react";
import { ProgressIndicator, Header2, Button, IconArrow, Label, FileInput, TextArea, CenteredContainer, Spacer, TextAlignWrapper, GlobalStyle } from '@intended/intended-ui';
const JustPage = () => {
const [secretInput, setSecretInput] = useState("");
const [fileInput, setFileInput] = useState<File | null>(null);
const [fileName, setFileName] = useState("");
const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
setSecretInput(e.target.value);
};
const handleFile = (file: File) => {
setFileInput(file);
setFileName(file.name);
};
return (
<React.StrictMode>
<GlobalStyle />
<CenteredContainer fullscreen>
<CenteredContainer>
<ProgressIndicator currentProgress={1} />
<Header2>Create a secret</Header2>
<TextAlignWrapper align="left">
<Label htmlFor="secretInput">Enter your secret here</Label>
</TextAlignWrapper>
<TextArea
id="secretInput"
value={secretInput}
onChange={handleChange}
placeholder="Tell me your secrets"
/>
<Spacer space="2rem" />
<TextAlignWrapper align="center">
<Label htmlFor="fileInput">OR</Label>
</TextAlignWrapper>
<Spacer space="1.6rem" />
<FileInput id="fileInput" value={fileName} handleFile={handleFile} />
{ fileInput ? "" : ""}
<Spacer space="4rem" />
<div
style={{ display: "flex", justifyContent: "flex-end", width: "100%" }}
>
<Button variant="secondary" onClick={() => window.location.href = "/just/for"}>
<IconArrow arrowDirection="right" />
</Button>
</div>
</CenteredContainer>
</CenteredContainer>
</React.StrictMode>
);
};
export default JustPage;

View File

@ -1,23 +1,26 @@
import React from "react";
import { CenteredContainer, SplashIconHeader, Header1, Header3, Spacer, Button } from '@intended/intended-ui';
import { CenteredContainer, SplashIconHeader, Header1, Header3, Spacer, Button, GlobalStyle } from '@intended/intended-ui';
const SplashPage = () => {
return (
<CenteredContainer fullscreen>
<CenteredContainer wide>
<SplashIconHeader />
<Header1>Securely Share Your Secrets</Header1>
<Header3>
With Intended Link you can easily share messages and files securely
and secretly.
</Header3>
<Spacer />
<Button variant="secondary" boldFont onClick={() => {}}>
START SHARING
</Button>
<React.StrictMode>
<GlobalStyle />
<CenteredContainer fullscreen>
<CenteredContainer wide>
<SplashIconHeader />
<Header1>Securely Share Your Secrets</Header1>
<Header3>
With Intended Link you can easily share messages and files securely
and secretly.
</Header3>
<Spacer />
<Button variant="secondary" boldFont onClick={() => window.location.href = "/just"}>
START SHARING
</Button>
</CenteredContainer>
</CenteredContainer>
</CenteredContainer>
</React.StrictMode>
);
};

View File

@ -0,0 +1,50 @@
import React from "react";
import { ProgressIndicator, Header2, Button, IconArrow, InputButtonWithIcon, Label, Input, CenteredContainer, SpaceBetweenContainer, Spacer, TextAlignWrapper, GlobalStyle } from "@intended/intended-ui";
const YouPage = () => {
return (
<React.StrictMode>
<GlobalStyle />
<CenteredContainer fullscreen>
<CenteredContainer>
<ProgressIndicator currentProgress={3} />
<Header2>Share the secret</Header2>
<SpaceBetweenContainer>
<Label htmlFor="shareLink">Secret message url</Label>
<Label htmlFor="shareLink">
Share this link with the intended recepient
</Label>
</SpaceBetweenContainer>
<InputButtonWithIcon
id="shareLink"
onClick={() => {}}
value="https://intended.link/for/you/MWUzZjg4YmEtZmNmNy00M..."
variant="copy"
/>
<Spacer space="2rem" />
<TextAlignWrapper align="left">
<Label htmlFor="encodedSecret">
This is what your message looks like on our server. Pretty secure
looking eh?:
</Label>
</TextAlignWrapper>
<Input
variant="disabled-light"
id="encodedSecret"
value="\4š€Š”Çm’ÄyÆFՑ¬Ð$CÑӀÃyۄ"
/>
<Spacer space="3rem" />
<SpaceBetweenContainer>
<Button variant="secondary" onClick={() => window.location.href = "/just/for"}>
<IconArrow arrowDirection="left" />
</Button>
<Button onClick={() => {}}>Generate Secret Code</Button>
</SpaceBetweenContainer>
</CenteredContainer>
</CenteredContainer>
</React.StrictMode>
);
};
export default YouPage;

11914
assets/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -7,17 +7,19 @@
"watch": "webpack --mode development --watch"
},
"dependencies": {
"@intended/intended-ui": "0.1.16",
"@intended/intended-ui": "0.1.19",
"phoenix": "file:../deps/phoenix",
"phoenix_html": "file:../deps/phoenix_html",
"phoenix_live_view": "file:../deps/phoenix_live_view",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-phoenix": "file:../deps/react_phoenix",
"topbar": "^0.1.4"
},
"devDependencies": {
"@babel/core": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"@babel/preset-react": "^7.16.0",
"@types/phoenix": "^1.5.3",
"@types/react": "^17.0.37",
"@types/react-dom": "^17.0.11",

View File

@ -50,7 +50,11 @@ module.exports = (env, options) => {
]
},
resolve: {
extensions: [".ts", ".tsx", ".js", ".jsx"]
extensions: [".ts", ".tsx", ".js", ".jsx"],
alias: {
react: path.resolve(__dirname, './node_modules/react'),
'react-dom': path.resolve(__dirname, './node_modules/react-dom')
}
},
plugins: [
new MiniCssExtractPlugin({ filename: '../css/app.css' }),

View File

@ -37,6 +37,8 @@ defmodule EntenduWeb do
import Phoenix.Controller,
only: [get_flash: 1, get_flash: 2, view_module: 1, view_template: 1]
import ReactPhoenix.ClientSide
# Include shared imports and aliases for views
unquote(view_helpers())
end

View File

@ -1,4 +1,4 @@
<main role="main" class="container">
<main role="main">
<p class="alert alert-info" role="alert"><%= get_flash(@conn, :info) %></p>
<p class="alert alert-danger" role="alert"><%= get_flash(@conn, :error) %></p>
<%= @inner_content %>

View File

@ -9,24 +9,7 @@
<link phx-track-static rel="stylesheet" href="<%= Routes.static_path(@conn, "/css/app.css") %>"/>
<script defer phx-track-static type="text/javascript" src="<%= Routes.static_path(@conn, "/js/app.js") %>"></script>
</head>
<body>
<div id="root">
<header>
<section class="container">
<nav role="navigation">
<ul>
<li><a href="https://hexdocs.pm/phoenix/overview.html">Get Started</a></li>
<%= if function_exported?(Routes, :live_dashboard_path, 2) do %>
<li><%= link "LiveDashboard", to: Routes.live_dashboard_path(@conn, :home) %></li>
<% end %>
</ul>
</nav>
<a href="https://phoenixframework.org/" class="phx-logo">
<img src="<%= Routes.static_path(@conn, "/images/phoenix.png") %>" alt="Phoenix Framework Logo"/>
</a>
</section>
</header>
<body style="background: #060b2e;">
<%= @inner_content %>
</div>
</body>
</html>

View File

@ -1,6 +1 @@
<section class="phx-hero">
<h2>Create a secret!</h2>
<p>There will be a form here</p>
<p>And a file input here</p>
<p>Then a next button</p>
</section>
<%= react_component("Components.ForPage") %>

View File

@ -1,10 +1 @@
<section class="phx-hero">
<h2>Create a secret!</h2>
<p>There will be a form here</p>
<p>And a file input here</p>
<p>Then a next button</p>
<form phx-submit="just">
<textarea></textarea>
<button>Submit</button>
</form>
</section>
<%= react_component("Components.JustPage") %>

View File

@ -1,6 +1 @@
<section class="phx-hero">
<h2>Create a secret!</h2>
<p>There will be a form here</p>
<p>And a file input here</p>
<p>Then a next button</p>
</section>
<%= react_component("Components.YouPage") %>

View File

@ -1,10 +1,7 @@
<section class="phx-hero">
<h1>Überauth + Phoenix Example</h1>
<p>
This is an application to show an example of how to wire up
<a href="https://github.com/ueberauth/ueberauth">Überauth</a> with
<a href="https://github.com/phoenixframework/phoenix">Phoenix</a>.
</p>
<section>
<%= react_component("Components.SplashPage") %>
<%= if @current_user do %>
<h2>Welcome, <%= @current_user.name %>!</h2>
<div>
@ -13,7 +10,7 @@
<%= link "Logout", to: Routes.auth_path(@conn, :delete), method: "delete", class: "button" %>
<br>
<% else %>
<ul style="list-style: none">
<ul style="display: none;">
<li>
<a class="button" href="<%= Routes.auth_path(@conn, :request, "github") %>">
<i class="fa fa-github"></i>

View File

@ -49,7 +49,8 @@ defmodule Entendu.MixProject do
{:plug_cowboy, "~> 2.0"},
{:libcluster, "~> 3.2"},
{:ueberauth, "~> 0.7.0"},
{:ueberauth_github, "~> 0.8.1"}
{:ueberauth_github, "~> 0.8.1"},
{:react_phoenix, "~> 1.3"}
]
end

View File

@ -33,6 +33,7 @@
"plug_crypto": {:hex, :plug_crypto, "1.2.2", "05654514ac717ff3a1843204b424477d9e60c143406aa94daf2274fdd280794d", [:mix], [], "hexpm", "87631c7ad914a5a445f0a3809f99b079113ae4ed4b867348dd9eec288cecb6db"},
"postgrex": {:hex, :postgrex, "0.15.10", "2809dee1b1d76f7cbabe570b2a9285c2e7b41be60cf792f5f2804a54b838a067", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "1560ca427542f6b213f8e281633ae1a3b31cdbcd84ebd7f50628765b8f6132be"},
"ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"},
"react_phoenix": {:hex, :react_phoenix, "1.3.0", "78aa68fda37437085e96a1cadfa25817f224db9250423397e6039c0ebfe1a5c3", [:mix], [{:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.11 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}], "hexpm", "86f7e8500f3f6376766609120fbabc6f119adbc9b2569f076a71aae8e15a32f8"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"},
"telemetry": {:hex, :telemetry, "0.4.3", "a06428a514bdbc63293cd9a6263aad00ddeb66f608163bdec7c8995784080818", [:rebar3], [], "hexpm", "eb72b8365ffda5bed68a620d1da88525e326cb82a75ee61354fc24b844768041"},
"telemetry_metrics": {:hex, :telemetry_metrics, "0.6.1", "315d9163a1d4660aedc3fee73f33f1d355dcc76c5c3ab3d59e76e3edf80eef1f", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7be9e0871c41732c233be71e4be11b96e56177bf15dde64a8ac9ce72ac9834c6"},

3
package-lock.json generated
View File

@ -1,3 +0,0 @@
{
"lockfileVersion": 1
}