Giter VIP home page Giter VIP logo

spacex's People

Contributors

notshadowm avatar

Watchers

 avatar

spacex's Issues

Pagination should re-communicate with the servers

When the data's pagination settings are changed, the UI should resend for the new data from the backend, use the limit and offset methods provided by the API to achieve this. This goes for both launches and missions.

Field onChange

A cleaner approach to specify fields' handlers, is to eliminate custom implementation where applicable.
Example:
Instead of

function Selection({ e, index, formData }) {
  return (
    <Select key={index} value={formData[e.state] || e.name} style={e.style} allowClear onChange={(value) => e.setData(value)}>
      {e.contents.map((x, ind) => <Option key={ind} value={x.value}>{x.text}</Option>)}
    </Select>
  );
}
.
.
.
    state: 'launch_year', setData: (value) => { setFormData({ launch_year: value }); }, name: 'Year', style: { width: 80, marginLeft: 20 }, contents: years.map((e) => ({ value: e, text: e })),

You can do:

function Selection({ field, form, onChange }) {
  return (
    <Select key={index} value={form[field.name]} style={e.style} allowClear onChange={(value) => onChange({ name, value })}>
      {field.options.map((x, ind) => <Option key={ind} value={x.value}>{x.text}</Option>)}
    </Select>
  );
}
.
.
.
    name: 'launch_year', label: 'Year', style: { width: 80, marginLeft: 20 }, contents: years.map((e) => ({ value: e, text: e })),

This way, you don't need to create a custom onChange for every input in your system

File structure

General components like Loading, ModalRow and Selection are not exclusive to RecentLaunches and should be exported elsewhere.

No hardcoding

<Option value="2020">2020</Option>
<Option value="2019">2019</Option>
<Option value="2018">2018</Option>
<Option value="2017">2017</Option>
<Option value="2016">2016</Option>
<Option value="2015">2015</Option>
<Option value="2014">2014</Option>
<Option value="2013">2013</Option>
<Option value="2012">2012</Option>
<Option value="2011">2011</Option>
<Option value="2010">2010</Option>
<Option value="2009">2009</Option>
<Option value="2008">2008</Option>

<Modal title="Settings" footer={null} visible={isModalVisible} onOk={handleOk} onCancel={handleCancel}>
<div className="switches">
<Row>
<Col span={50}>Mission icon : </Col>
<Col span={50}><img src={smallData?.mission_icon} alt="icon" style={{ width: '40px' }} /></Col>
</Row>
<Row>
<Col span={50}>Launch site : </Col>
<Col span={50}>{smallData?.launch_site}</Col>
</Row>
<Row>
<Col span={50}>Rocket Name : </Col>
<Col span={50}>{smallData?.rocket_name}</Col>
</Row>
<Row>
<Col span={50}>Launch date : </Col>
<Col span={50}>{smallData?.launch_date}</Col>
</Row>
<Row>
<Col span={50}>Mission name : </Col>
<Col span={50}>{smallData?.mission_name}</Col>
</Row>
<Row>
<Col span={50}>Is upcoming : </Col>
<Col span={50}>{smallData?.is_upcoming ? 'Yes' : 'No'}</Col>
</Row>
<Row>
<Col span={50}>Media : </Col>
<Col span={50}>{smallData?.media.map((e, index) => <a key={index} href={e}>link </a>)}</Col>
</Row>
<Row>
<Col span={50}>Images : </Col>
<Col span={50} className="grid-container">{smallData?.images.map((e, index) => <img className="grid-item" key={index} src={e} alt="rocketImage" style={{ width: '26px' }} />)}</Col>
</Row>
<Row>
<Col span={50}>Rocket active : </Col>
<Col span={50}>{smallData?.rocketActive ? 'Yes' : 'No'}</Col>
</Row>
<Row>
<Col span={50}>Cost per launch : </Col>
<Col span={50}>{smallData?.cost_per_launch}</Col>
</Row>
<Row>
<Col span={50}>Mass : </Col>
<Col span={50}>{smallData?.mass[weight]}</Col>
</Row>
<Row>
<Col span={50}>Diameter : </Col>
<Col span={50}>{smallData?.diameter[distance]}</Col>
</Row>
<Row>
<Col span={50}>Success rate : </Col>
<Col span={50}>{smallData?.success_rate_pct}</Col>
</Row>
<Row>
<Col span={50}>Rocket Description : </Col>
<Col span={50}>{smallData?.description}</Col>
</Row>
</div>
</Modal>

<Select defaultValue={name || 'Rocket Name'} style={{ width: 130, marginLeft: 50 }} allowClear onChange={handleOnNameChange}>
{names.map((e, index) => <Option key={index} value={e}>{e}</Option>)}
</Select>
<Select defaultValue={core || 'Core'} style={{ width: 100, marginLeft: 50 }} allowClear onChange={handleOnCoreChange}>
<Option value="true">reused</Option>
<Option value="false">not reused</Option>
</Select>
<Select defaultValue={fairings || 'Fairings'} style={{ width: 100, marginLeft: 50 }} allowClear onChange={handleOnFairingsChange}>
<Option value="true">reused</Option>
<Option value="false">not reused</Option>
</Select>
<Select defaultValue={missionId || 'Mission ID'} style={{ width: 110, marginLeft: 50 }} allowClear onChange={handleOnMissionIdChange}>
{missionsIds.map((e, index) => <Option key={index} value={e}>{e}</Option>)}
</Select>
<Select defaultValue={launching || 'Launching Success'} style={{ width: 160, marginLeft: 50 }} allowClear onChange={handleOnLaunchingChange}>
<Option value="true">Success</Option>
<Option value="false">Failed</Option>
</Select>
<Select defaultValue={landing || 'Landing Success'} style={{ width: 160, marginLeft: 50 }} allowClear onChange={handleOnLandingChange}>
<Option value="true">Success</Option>
<Option value="false">Failed</Option>
</Select>

In these sections, options and labels are hard coded, it's a much better practice to store the schema of your forms in one place "Like a JSON object", which will contain the labels and general options, and then use that JSON object in your components, rather than hardcoding the values into JSX.

Component separation

return !data ? <div>loading....</div>

<Col span={50}>Mission icon : </Col>
<Col span={50}><img src={smallData?.mission_icon} alt="icon" style={{ width: '40px' }} /></Col>

When a piece of code seems to be written over and over again, it's better to separate that piece of code into its own component, and then reuse that piece of code in the rest of the project.

One state for the form

const [year, setYear] = useState();
const [name, setName] = useState();
const [names, setNames] = useState();
const [core, setCore] = useState();
const [fairings, setFairings] = useState();
const [missionsIds, setMissionsIds] = useState();
const [missionId, setMissionId] = useState();
const [launching, setLaunching] = useState();
const [landing, setLanding] = useState();

const handleOnYearChange = (value) => {
setYear(value);
setData();
allData(name, value, core, fairings, missionId, launching, landing);
};
const handleOnNameChange = (value) => {
setName(value);
setData();
allData(value, year, core, fairings, missionId, launching, landing);
};
const handleOnCoreChange = (value) => {
setCore(value);
setData();
allData(name, year, value, fairings, missionId, launching, landing);
};
const handleOnFairingsChange = (value) => {
setFairings(value);
setData();
allData(name, year, core, value, missionId, launching, landing);
};
const handleOnMissionIdChange = (value) => {
setMissionId(value);
setData();
allData(name, year, core, fairings, value, launching, landing);
};
const handleOnLaunchingChange = (value) => {
setLaunching(value);
setData();
allData(name, year, core, fairings, missionId, value, landing);
};
const handleOnLandingChange = (value) => {
setLanding(value);
setData();
allData(name, year, core, fairings, missionId, launching, value);
};

All of these fields are part of the same form, changing any of the fields will result in that "Form" updating the table, create a single state for all the form fields, and a generic "handleChange" function that can be passed to any of the inputs.

Separation of concerns

const query = gql`
{
launchesPastResult(find: {mission_name:"${smallName}"}){
data {
links {
mission_patch_small
wikipedia
video_link
reddit_media
reddit_recovery
reddit_launch
reddit_campaign
flickr_images
}
launch_site {
site_name
}
rocket {
rocket_name
rocket {
country
active
cost_per_launch
mass {
kg
lb
}
diameter {
feet
meters
}
success_rate_pct
description
}
}
launch_date_utc
mission_name
upcoming
}
}
}
`;

Every seemingly different functionality in a component (e.g. Store, API calls, Gql queries/mutations, translations, ...etc) should exist in a different location than the component.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.