Client - display characters limitation on textarea - fix #81
This commit is contained in:
parent
7cea812d8b
commit
fdfd828677
20
fittrackee/dist/asset-manifest.json
vendored
20
fittrackee/dist/asset-manifest.json
vendored
@ -1,15 +1,15 @@
|
|||||||
{
|
{
|
||||||
"files": {
|
"files": {
|
||||||
"main.css": "/static/css/main.8c7e57e2.chunk.css",
|
"main.css": "/static/css/main.98601af9.chunk.css",
|
||||||
"main.js": "/static/js/main.9a854965.chunk.js",
|
"main.js": "/static/js/main.99ae4b8a.chunk.js",
|
||||||
"main.js.map": "/static/js/main.9a854965.chunk.js.map",
|
"main.js.map": "/static/js/main.99ae4b8a.chunk.js.map",
|
||||||
"runtime-main.js": "/static/js/runtime-main.14e737bb.js",
|
"runtime-main.js": "/static/js/runtime-main.14e737bb.js",
|
||||||
"runtime-main.js.map": "/static/js/runtime-main.14e737bb.js.map",
|
"runtime-main.js.map": "/static/js/runtime-main.14e737bb.js.map",
|
||||||
"static/js/2.8c02a30e.chunk.js": "/static/js/2.8c02a30e.chunk.js",
|
"static/js/2.ce83ecf7.chunk.js": "/static/js/2.ce83ecf7.chunk.js",
|
||||||
"static/js/2.8c02a30e.chunk.js.map": "/static/js/2.8c02a30e.chunk.js.map",
|
"static/js/2.ce83ecf7.chunk.js.map": "/static/js/2.ce83ecf7.chunk.js.map",
|
||||||
"index.html": "/index.html",
|
"index.html": "/index.html",
|
||||||
"static/css/main.8c7e57e2.chunk.css.map": "/static/css/main.8c7e57e2.chunk.css.map",
|
"static/css/main.98601af9.chunk.css.map": "/static/css/main.98601af9.chunk.css.map",
|
||||||
"static/js/2.8c02a30e.chunk.js.LICENSE.txt": "/static/js/2.8c02a30e.chunk.js.LICENSE.txt",
|
"static/js/2.ce83ecf7.chunk.js.LICENSE.txt": "/static/js/2.ce83ecf7.chunk.js.LICENSE.txt",
|
||||||
"static/media/en.9e6dbfb0.svg": "/static/media/en.9e6dbfb0.svg",
|
"static/media/en.9e6dbfb0.svg": "/static/media/en.9e6dbfb0.svg",
|
||||||
"static/media/fr.d0f9280c.svg": "/static/media/fr.d0f9280c.svg",
|
"static/media/fr.d0f9280c.svg": "/static/media/fr.d0f9280c.svg",
|
||||||
"static/media/mail-send.619079f0.svg": "/static/media/mail-send.619079f0.svg",
|
"static/media/mail-send.619079f0.svg": "/static/media/mail-send.619079f0.svg",
|
||||||
@ -17,8 +17,8 @@
|
|||||||
},
|
},
|
||||||
"entrypoints": [
|
"entrypoints": [
|
||||||
"static/js/runtime-main.14e737bb.js",
|
"static/js/runtime-main.14e737bb.js",
|
||||||
"static/js/2.8c02a30e.chunk.js",
|
"static/js/2.ce83ecf7.chunk.js",
|
||||||
"static/css/main.8c7e57e2.chunk.css",
|
"static/css/main.98601af9.chunk.css",
|
||||||
"static/js/main.9a854965.chunk.js"
|
"static/js/main.99ae4b8a.chunk.js"
|
||||||
]
|
]
|
||||||
}
|
}
|
2
fittrackee/dist/index.html
vendored
2
fittrackee/dist/index.html
vendored
@ -1 +1 @@
|
|||||||
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name="theme-color" content="#000000"><link rel="manifest" href="/manifest.json"><link rel="shortcut icon" href="/favicon.ico"><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fork-awesome@1.1.7/css/fork-awesome.min.css" integrity="sha256-gsmEoJAws/Kd3CjuOQzLie5Q3yshhvmo7YNtBG7aaEY=" crossorigin="anonymous"><link rel="stylesheet" href="https://cdn.jsdelivr.net/foundation-icons/3.0/foundation-icons.min.css"><link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css" integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ==" crossorigin=""><title>FitTrackee</title><link href="/static/css/main.8c7e57e2.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script><script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script><script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script><script type="text/javascript">$(document).ready((function(){$("li.nav-item").click((function(){$("button.navbar-toggler").toggleClass("collapsed"),$("#navbarSupportedContent").toggleClass("show")}))}))</script><script>!function(e){function t(t){for(var n,i,l=t[0],f=t[1],a=t[2],p=0,s=[];p<l.length;p++)i=l[p],Object.prototype.hasOwnProperty.call(o,i)&&o[i]&&s.push(o[i][0]),o[i]=0;for(n in f)Object.prototype.hasOwnProperty.call(f,n)&&(e[n]=f[n]);for(c&&c(t);s.length;)s.shift()();return u.push.apply(u,a||[]),r()}function r(){for(var e,t=0;t<u.length;t++){for(var r=u[t],n=!0,l=1;l<r.length;l++){var f=r[l];0!==o[f]&&(n=!1)}n&&(u.splice(t--,1),e=i(i.s=r[0]))}return e}var n={},o={1:0},u=[];function i(t){if(n[t])return n[t].exports;var r=n[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,i),r.l=!0,r.exports}i.m=e,i.c=n,i.d=function(e,t,r){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(i.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)i.d(r,n,function(t){return e[t]}.bind(null,n));return r},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="/";var l=this.webpackJsonpfittrackee_client=this.webpackJsonpfittrackee_client||[],f=l.push.bind(l);l.push=t,l=l.slice();for(var a=0;a<l.length;a++)t(l[a]);var c=f;r()}([])</script><script src="/static/js/2.8c02a30e.chunk.js"></script><script src="/static/js/main.9a854965.chunk.js"></script></body></html>
|
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name="theme-color" content="#000000"><link rel="manifest" href="/manifest.json"><link rel="shortcut icon" href="/favicon.ico"><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fork-awesome@1.1.7/css/fork-awesome.min.css" integrity="sha256-gsmEoJAws/Kd3CjuOQzLie5Q3yshhvmo7YNtBG7aaEY=" crossorigin="anonymous"><link rel="stylesheet" href="https://cdn.jsdelivr.net/foundation-icons/3.0/foundation-icons.min.css"><link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css" integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ==" crossorigin=""><title>FitTrackee</title><link href="/static/css/main.98601af9.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script><script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script><script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script><script type="text/javascript">$(document).ready((function(){$("li.nav-item").click((function(){$("button.navbar-toggler").toggleClass("collapsed"),$("#navbarSupportedContent").toggleClass("show")}))}))</script><script>!function(e){function t(t){for(var n,i,l=t[0],f=t[1],a=t[2],p=0,s=[];p<l.length;p++)i=l[p],Object.prototype.hasOwnProperty.call(o,i)&&o[i]&&s.push(o[i][0]),o[i]=0;for(n in f)Object.prototype.hasOwnProperty.call(f,n)&&(e[n]=f[n]);for(c&&c(t);s.length;)s.shift()();return u.push.apply(u,a||[]),r()}function r(){for(var e,t=0;t<u.length;t++){for(var r=u[t],n=!0,l=1;l<r.length;l++){var f=r[l];0!==o[f]&&(n=!1)}n&&(u.splice(t--,1),e=i(i.s=r[0]))}return e}var n={},o={1:0},u=[];function i(t){if(n[t])return n[t].exports;var r=n[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,i),r.l=!0,r.exports}i.m=e,i.c=n,i.d=function(e,t,r){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(i.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)i.d(r,n,function(t){return e[t]}.bind(null,n));return r},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="/";var l=this.webpackJsonpfittrackee_client=this.webpackJsonpfittrackee_client||[],f=l.push.bind(l);l.push=t,l=l.slice();for(var a=0;a<l.length;a++)t(l[a]);var c=f;r()}([])</script><script src="/static/js/2.ce83ecf7.chunk.js"></script><script src="/static/js/main.99ae4b8a.chunk.js"></script></body></html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
fittrackee/dist/static/css/main.98601af9.chunk.css
vendored
Normal file
2
fittrackee/dist/static/css/main.98601af9.chunk.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
fittrackee/dist/static/css/main.98601af9.chunk.css.map
vendored
Normal file
1
fittrackee/dist/static/css/main.98601af9.chunk.css.map
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
fittrackee/dist/static/js/main.99ae4b8a.chunk.js
vendored
Normal file
2
fittrackee/dist/static/js/main.99ae4b8a.chunk.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
fittrackee/dist/static/js/main.99ae4b8a.chunk.js.map
vendored
Normal file
1
fittrackee/dist/static/js/main.99ae4b8a.chunk.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -362,6 +362,11 @@ label {
|
|||||||
padding: 0.1em;
|
padding: 0.1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.remaining-chars {
|
||||||
|
font-size: 0.8em;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
.sport-img {
|
.sport-img {
|
||||||
max-width: 35px;
|
max-width: 35px;
|
||||||
max-height: 35px;
|
max-height: 35px;
|
||||||
@ -440,6 +445,10 @@ label {
|
|||||||
color: black;
|
color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.user-bio, .workout-notes {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
|
||||||
.user-filters {
|
.user-filters {
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
@ -516,7 +525,7 @@ label {
|
|||||||
line-height: 400px;
|
line-height: 400px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.workout-notes, .actvitiy-segments {
|
.workout-notes, .actvity-segments {
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
|
45
fittrackee_client/src/components/Common/CustomTextArea.jsx
Normal file
45
fittrackee_client/src/components/Common/CustomTextArea.jsx
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { withTranslation } from 'react-i18next'
|
||||||
|
import { connect } from 'react-redux'
|
||||||
|
|
||||||
|
class CustomTextArea extends React.Component {
|
||||||
|
constructor(props, context) {
|
||||||
|
super(props, context)
|
||||||
|
this.state = {
|
||||||
|
text: props.defaultValue ? props.defaultValue : '',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleOnChange(changeEvent) {
|
||||||
|
this.setState({ text: changeEvent.target.value })
|
||||||
|
if (this.props.onTextChange) {
|
||||||
|
this.props.onTextChange(changeEvent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { charLimit, loading, name, t } = this.props
|
||||||
|
const { text } = this.state
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<textarea
|
||||||
|
name={name}
|
||||||
|
defaultValue={text}
|
||||||
|
disabled={loading ? loading : false}
|
||||||
|
className="form-control input-lg"
|
||||||
|
maxLength={charLimit}
|
||||||
|
onChange={event => this.handleOnChange(event)}
|
||||||
|
/>
|
||||||
|
<div className="remaining-chars">
|
||||||
|
{t('common:remaining characters')}: {text.length}/{charLimit}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withTranslation()(
|
||||||
|
connect(state => ({
|
||||||
|
loading: state.loading,
|
||||||
|
}))(CustomTextArea)
|
||||||
|
)
|
@ -79,7 +79,7 @@ function ProfileDetail({
|
|||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<span className="user-label">{t('user:Bio')}</span>:{' '}
|
<span className="user-label">{t('user:Bio')}</span>:{' '}
|
||||||
{user.bio}
|
<span className="user-bio">{user.bio}</span>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
{/* eslint-disable-next-line max-len */}
|
{/* eslint-disable-next-line max-len */}
|
||||||
|
@ -10,6 +10,7 @@ import { deleteUser, handleProfileFormSubmit } from '../../actions/user'
|
|||||||
import { history } from '../../index'
|
import { history } from '../../index'
|
||||||
import { languages } from '../NavBar/LanguageDropdown'
|
import { languages } from '../NavBar/LanguageDropdown'
|
||||||
import CustomModal from '../Common/CustomModal'
|
import CustomModal from '../Common/CustomModal'
|
||||||
|
import CustomTextArea from '../Common/CustomTextArea'
|
||||||
|
|
||||||
class ProfileEdit extends React.Component {
|
class ProfileEdit extends React.Component {
|
||||||
constructor(props, context) {
|
constructor(props, context) {
|
||||||
@ -198,12 +199,11 @@ class ProfileEdit extends React.Component {
|
|||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label>
|
<label>
|
||||||
{t('user:Bio')}:
|
{t('user:Bio')}:
|
||||||
<textarea
|
<CustomTextArea
|
||||||
|
charLimit={200}
|
||||||
name="bio"
|
name="bio"
|
||||||
className="form-control input-lg"
|
defaultValue={formData.bio}
|
||||||
maxLength="200"
|
onTextChange={e => this.handleFormChange(e)}
|
||||||
value={formData.bio}
|
|
||||||
onChange={e => this.handleFormChange(e)}
|
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -7,6 +7,7 @@ import { addWorkout, editWorkout } from '../../../actions/workouts'
|
|||||||
import { history } from '../../../index'
|
import { history } from '../../../index'
|
||||||
import { getFileSize } from '../../../utils'
|
import { getFileSize } from '../../../utils'
|
||||||
import { translateSports } from '../../../utils/workouts'
|
import { translateSports } from '../../../utils/workouts'
|
||||||
|
import CustomTextArea from '../../Common/CustomTextArea'
|
||||||
|
|
||||||
function FormWithGpx(props) {
|
function FormWithGpx(props) {
|
||||||
const {
|
const {
|
||||||
@ -105,12 +106,11 @@ function FormWithGpx(props) {
|
|||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label>
|
<label>
|
||||||
{t('workouts:Notes')}:
|
{t('workouts:Notes')}:
|
||||||
<textarea
|
<CustomTextArea
|
||||||
name="notes"
|
charLimit={500}
|
||||||
defaultValue={workout ? workout.notes : ''}
|
defaultValue={workout ? workout.notes : ''}
|
||||||
disabled={loading}
|
loading={loading}
|
||||||
className="form-control input-lg"
|
name="notes"
|
||||||
maxLength="500"
|
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -5,6 +5,7 @@ import { addWorkoutWithoutGpx, editWorkout } from '../../../actions/workouts'
|
|||||||
import { history } from '../../../index'
|
import { history } from '../../../index'
|
||||||
import { getDateWithTZ } from '../../../utils'
|
import { getDateWithTZ } from '../../../utils'
|
||||||
import { formatWorkoutDate, translateSports } from '../../../utils/workouts'
|
import { formatWorkoutDate, translateSports } from '../../../utils/workouts'
|
||||||
|
import CustomTextArea from '../../Common/CustomTextArea'
|
||||||
|
|
||||||
function FormWithoutGpx(props) {
|
function FormWithoutGpx(props) {
|
||||||
const { onAddOrEdit, sports, t, user, workout } = props
|
const { onAddOrEdit, sports, t, user, workout } = props
|
||||||
@ -106,11 +107,10 @@ function FormWithoutGpx(props) {
|
|||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label>
|
<label>
|
||||||
{t('workouts:Notes')}:
|
{t('workouts:Notes')}:
|
||||||
<textarea
|
<CustomTextArea
|
||||||
name="notes"
|
charLimit={500}
|
||||||
defaultValue={workout ? workout.notes : ''}
|
defaultValue={workout ? workout.notes : ''}
|
||||||
className="form-control input-lg"
|
name="notes"
|
||||||
maxLength="500"
|
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
"Page not found": "Page not found",
|
"Page not found": "Page not found",
|
||||||
"Previous": "Prev",
|
"Previous": "Prev",
|
||||||
"registration date": "registration date",
|
"registration date": "registration date",
|
||||||
|
"remaining characters": "remaining characters",
|
||||||
"Sort": "Sort",
|
"Sort": "Sort",
|
||||||
"Sort by": "Sort by",
|
"Sort by": "Sort by",
|
||||||
"Sport": "Sport",
|
"Sport": "Sport",
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
"No workouts.": "Pas de séances.",
|
"No workouts.": "Pas de séances.",
|
||||||
"Page not found": "Page introuvable",
|
"Page not found": "Page introuvable",
|
||||||
"Previous": "Page précédente",
|
"Previous": "Page précédente",
|
||||||
|
"remaining characters": "nombre de caractères restants ",
|
||||||
"registration date": "date d'inscription",
|
"registration date": "date d'inscription",
|
||||||
"Sort": "Tri",
|
"Sort": "Tri",
|
||||||
"Sort by": "Trier par",
|
"Sort by": "Trier par",
|
||||||
|
Loading…
Reference in New Issue
Block a user