From b6e4c39ae1a0a13b7bc887ff91f0143cdda0cfe9 Mon Sep 17 00:00:00 2001 From: deflax Date: Mon, 29 Apr 2024 18:50:23 +0300 Subject: [PATCH] move files around --- src/rfront/.babelrc | 1 + src/rfront/.dockerignore | 5 + src/rfront/.eslintrc.json | 171 ++++++++++++++++++++++ src/rfront/front/App.css | 59 ++++++++ src/rfront/front/App.js | 63 ++++++++ src/rfront/front/components/Messages.jsx | 13 ++ src/rfront/front/components/TextField.jsx | 42 ++++++ src/rfront/front/index.css | 14 ++ src/rfront/front/index.js | 7 + src/rfront/front/webpack.config.js | 29 ++++ src/rfront/tests/App.test.js | 9 ++ src/rfront/tests/setup.js | 6 + 12 files changed, 419 insertions(+) create mode 100644 src/rfront/.babelrc create mode 100644 src/rfront/.dockerignore create mode 100644 src/rfront/.eslintrc.json create mode 100644 src/rfront/front/App.css create mode 100644 src/rfront/front/App.js create mode 100644 src/rfront/front/components/Messages.jsx create mode 100644 src/rfront/front/components/TextField.jsx create mode 100644 src/rfront/front/index.css create mode 100644 src/rfront/front/index.js create mode 100644 src/rfront/front/webpack.config.js create mode 100644 src/rfront/tests/App.test.js create mode 100644 src/rfront/tests/setup.js diff --git a/src/rfront/.babelrc b/src/rfront/.babelrc new file mode 100644 index 0000000..484f36f --- /dev/null +++ b/src/rfront/.babelrc @@ -0,0 +1 @@ +{ "presets": ["@babel/react"] } diff --git a/src/rfront/.dockerignore b/src/rfront/.dockerignore new file mode 100644 index 0000000..f84630c --- /dev/null +++ b/src/rfront/.dockerignore @@ -0,0 +1,5 @@ +.git/ +data/ +node_modules/ +public/index.js +k8s/ diff --git a/src/rfront/.eslintrc.json b/src/rfront/.eslintrc.json new file mode 100644 index 0000000..275e7c1 --- /dev/null +++ b/src/rfront/.eslintrc.json @@ -0,0 +1,171 @@ +{ + "env": { + "browser": true, + "node": true, + "es6": true, + "jest": true + }, + "globals": { + "io": "readonly" + }, + "parser": "@babel/eslint-parser", + "parserOptions": { + "sourceType": "module", + "ecmaVersion": 2021, + "ecmaFeatures": { + "jsx": true + } + }, + "settings": { + "react": { + "version": "detect" + } + }, + "plugins": ["node", "react", "security"], + "extends": ["eslint:recommended", "plugin:node/recommended", "plugin:react/recommended", "plugin:security/recommended"], + "rules": { + "node/exports-style": ["error", "module.exports"], + "node/no-extraneous-import": ["error", { + "allowModules": ["prop-types"] + }], + "node/no-unpublished-require": 0, + "node/no-unpublished-import": 0, + "node/no-unsupported-features/es-syntax": 0, + + "comma-dangle": [ 2, "always-multiline" ], + "no-console": 1, + "no-constant-condition": 2, + "no-control-regex": 2, + "no-debugger": 1, + "no-dupe-keys": 2, + "no-duplicate-case": 2, + "no-empty-character-class": 2, + "no-empty": [2, { "allowEmptyCatch": true } ], + "no-extra-boolean-cast": 2, + "no-extra-semi": 2, + "no-func-assign": 2, + "no-inner-declarations": 2, + "no-invalid-regexp": 2, + "no-irregular-whitespace": 2, + "no-negated-in-lhs": 2, + "no-unreachable": 2, + "use-isnan": 2, + "valid-typeof": 2, + + "accessor-pairs": 2, + "block-scoped-var": 2, + "curly": 2, + "default-case": 0, + "dot-location": [ 2, "property" ], + "dot-notation": 0, + "eqeqeq": [ 2, "smart" ], + "no-alert": 1, + "no-caller": 2, + "no-case-declarations": 0, + "no-div-regex": 1, + "no-else-return": 2, + "no-eval": 2, + "no-extend-native": 2, + "no-extra-bind": 2, + "no-fallthrough": 2, + "no-floating-decimal": 2, + "no-implied-eval": 2, + "no-iterator": 2, + "no-labels": 2, + "no-lone-blocks": 2, + "no-loop-func": 2, + "no-multi-spaces": 0, + "no-multi-str": 2, + "no-native-reassign": 2, + "no-new-func": 2, + "no-new-wrappers": 2, + "no-new": 2, + "no-octal-escape": 2, + "no-octal": 2, + "no-param-reassign": 0, + "no-proto": 2, + "no-redeclare": 2, + "no-return-assign": 2, + "no-self-compare": 2, + "no-throw-literal": 2, + "no-unused-expressions": [ 2, { "allowShortCircuit": true } ], + "no-useless-call": 2, + "no-useless-concat": 2, + "no-void": 2, + "no-warning-comments": 1, + "no-with": 2, + "radix": 0, + "vars-on-top": 0, + "wrap-iife": 0, + "yoda": 2, + + "strict": 2, + + "no-catch-shadow": 2, + "no-delete-var": 2, + "no-shadow-restricted-names": 2, + "no-shadow": 0, + "no-undef-init": 2, + "no-unused-vars": 2, + "no-use-before-define": 0, + + "global-require": 0, + "handle-callback-err": 1, + "no-new-require": 2, + + "array-bracket-spacing": 0, + "block-spacing": [ 2, "always" ], + "brace-style": 0, + "camelcase": 0, + "comma-spacing": [ 2, { "before": false, "after": true } ], + "comma-style": [ 2, "last" ], + "computed-property-spacing": 0, + "consistent-this": [ 2, "self" ], + "eol-last": 2, + "func-style": 0, + "indent": [ 2, 2, { "SwitchCase": 1, "MemberExpression": 1 } ], + "key-spacing": 0, + "new-cap": 0, + "new-parens": 2, + "newline-after-var": 0, + "no-array-constructor": 2, + "no-bitwise": 2, + "no-continue": 0, + "no-lonely-if": 2, + "no-mixed-spaces-and-tabs": 2, + "no-multiple-empty-lines": [ 2, { "max": 2, "maxEOF": 1 } ], + "no-nested-ternary": 2, + "no-new-object": 2, + "no-spaced-func": 0, + "no-trailing-spaces": [ 2, { "skipBlankLines": true } ], + "no-unneeded-ternary": 2, + "object-curly-spacing": 0, + "one-var": 0, + "operator-linebreak": [ 2, "after" ], + "quote-props": 0, + "quotes": [ 2, "single", "avoid-escape" ], + "semi": [ 2, "always" ], + "space-before-blocks": [ 2, "always" ], + "space-before-function-paren": 0, + "space-in-parens": 0, + "space-infix-ops": 2, + "space-unary-ops": [ 2, { "words": true, "nonwords": false } ], + "spaced-comment": [ 2, "always" ], + "keyword-spacing": 2, + + "arrow-parens": [ 2, "as-needed" ], + "arrow-spacing": 2, + "constructor-super": 2, + "generator-star-spacing": [ 2, { "before": true, "after": false } ], + "no-confusing-arrow": 2, + "no-class-assign": 2, + "no-const-assign": 2, + "no-dupe-class-members": 2, + "no-this-before-super": 2, + "no-var": 2, + "prefer-arrow-callback": 0, + "prefer-spread": 1, + "prefer-template": 0, + "require-yield": 2 + } +} diff --git a/src/rfront/front/App.css b/src/rfront/front/App.css new file mode 100644 index 0000000..058b1d0 --- /dev/null +++ b/src/rfront/front/App.css @@ -0,0 +1,59 @@ +.App { + text-align: center; + display: flex; + flex-direction: column; + flex-wrap: wrap; + align-content: space-around; + align-items: center; + margin: 66px; + border-style: solid; + border-color: deeppink; + margin-top: 20px; +} + +.App-logo { + height: 40vmin; + pointer-events: none; +} + +@media (prefers-reduced-motion: no-preference) { + .App-logo { + animation: App-logo-spin infinite 20s linear; + } +} + +.App-header { + background-color: #282c34; + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + font-size: calc(10px + 2vmin); + color: white; +} + +.App-link { + color: #61dafb; +} + +@keyframes App-logo-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +.message { + color: deeppink; +} + +.list-message { + margin: 5px; + display: flex; + flex-direction: column; + flex-wrap: wrap; +} + diff --git a/src/rfront/front/App.js b/src/rfront/front/App.js new file mode 100644 index 0000000..890fc6f --- /dev/null +++ b/src/rfront/front/App.js @@ -0,0 +1,63 @@ +import "./App.css"; +import Messages from "./components/Messages"; +import TextField from "./components/TextField"; +import { useEffect, useState } from "react"; +import { io } from "socket.io-client"; + +function App() { + const [messages, setMessages] = useState([]); + const [socketInstance, setSocketInstance] = useState(""); + + useEffect(() => { + fetch(`${process.env.REACT_APP_BACKEND_SERVICE_URL}/messages`) + .then((response) => response.json()) + .then((responseData) => { + setMessages(responseData); + }); + }, []); + useEffect(() => { + const socket = io(`${process.env.REACT_APP_WEBSOCKET_SERVICE_URL}`, { + transports: ["websocket"], + cors: { + origin: "http://localhost:3000/", + withCredentials: true, + }, + }); + setSocketInstance(socket); + + socket.on("connect", (data) => { + console.log("socket - connected users:", data); + }); + + socket.on("disconnect", (data) => { + console.log("socket - disconnect users:", data); + }); + + socket.on("new_message", (data) => { + const updatedMessages = [...messages, data]; + setMessages(updatedMessages); + console.log(data); + }); + + return function cleanup() { + console.log("clean up"); + socket.disconnect(); + }; + }, [messages]); + return ( +
+ {messages.length !== 0 ? ( + + ) : ( +

No Messages

+ )} + +
+ ); +} + +export default App; diff --git a/src/rfront/front/components/Messages.jsx b/src/rfront/front/components/Messages.jsx new file mode 100644 index 0000000..75ab2c3 --- /dev/null +++ b/src/rfront/front/components/Messages.jsx @@ -0,0 +1,13 @@ +export default function Messages({ messages }) { + return ( + <> + {messages.map((message) => ( +
  • + Message: {message.text} + Date: {message.date} +
  • + ))} + + ); +} + diff --git a/src/rfront/front/components/TextField.jsx b/src/rfront/front/components/TextField.jsx new file mode 100644 index 0000000..61fe092 --- /dev/null +++ b/src/rfront/front/components/TextField.jsx @@ -0,0 +1,42 @@ +import { useState } from "react"; + +export default function TextField({ messages, setMessages, socket }) { + const [inputValue, setInputValue] = useState(""); + + function handleClick() { + const data = { text: inputValue }; + fetch(`${process.env.REACT_APP_BACKEND_SERVICE_URL}/messages`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(data), + }) + .then((response) => response.json()) + .then((responseData) => { + if (responseData.status === "error") { + console.log("error", responseData); + return; + } + const updatedMessages = [...messages, responseData.message]; + setMessages(updatedMessages); + setInputValue(""); + + socket.emit("new_message", responseData.message); + }); + } + function handleTyping(event) { + setInputValue(event.target.value); + } + return ( + <> + + + + ); +} diff --git a/src/rfront/front/index.css b/src/rfront/front/index.css new file mode 100644 index 0000000..ad5c070 --- /dev/null +++ b/src/rfront/front/index.css @@ -0,0 +1,14 @@ +body { + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', + 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', + sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +code { + font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', + monospace; +} + diff --git a/src/rfront/front/index.js b/src/rfront/front/index.js new file mode 100644 index 0000000..a64e7d5 --- /dev/null +++ b/src/rfront/front/index.js @@ -0,0 +1,7 @@ +import React from "react"; +import ReactDOM from "react-dom/client"; +import "./index.css"; +import App from "./App"; + +const root = ReactDOM.createRoot(document.getElementById("root")); +root.render(); diff --git a/src/rfront/front/webpack.config.js b/src/rfront/front/webpack.config.js new file mode 100644 index 0000000..b144c78 --- /dev/null +++ b/src/rfront/front/webpack.config.js @@ -0,0 +1,29 @@ +const CopyWebpackPlugin = require('copy-webpack-plugin'); +const config = require('./src/config'); + +module.exports = { + mode: config.debug ? 'development' : 'production', + entry: `${__dirname}/src/frontend/index.js`, + module: { + rules: [ + { + test: /\.js$/, + exclude: /node_modules/, + loader: 'babel-loader', + }, + ], + }, + output: { + filename: 'index.js', + path: `${__dirname}/public`, + publicPath: '/', + }, + plugins: [ + new CopyWebpackPlugin({ + patterns: [ + { from: 'node_modules/xterm/css', to: 'xterm/css' }, + { from: 'node_modules/xterm/lib', to: 'xterm/lib' }, + ], + }), + ], +}; diff --git a/src/rfront/tests/App.test.js b/src/rfront/tests/App.test.js new file mode 100644 index 0000000..b42080d --- /dev/null +++ b/src/rfront/tests/App.test.js @@ -0,0 +1,9 @@ +import { render, screen } from '@testing-library/react'; +import App from './App'; + +test('renders learn react link', () => { + render(); + const linkElement = screen.getByText(/learn react/i); + expect(linkElement).toBeInTheDocument(); +}); + diff --git a/src/rfront/tests/setup.js b/src/rfront/tests/setup.js new file mode 100644 index 0000000..4c2ef26 --- /dev/null +++ b/src/rfront/tests/setup.js @@ -0,0 +1,6 @@ +// jest-dom adds custom jest matchers for asserting on DOM nodes. +// allows you to do things like: +// expect(element).toHaveTextContent(/react/i) +// learn more: https://github.com/testing-library/jest-dom +import "@testing-library/jest-dom"; +