Erstellen einer React-Mitarbeiterdatenbankseite mit Airtable und Quarkly

Haben Sie von einem Tool wie Airtable gehört, wussten aber nicht, wo Sie anfangen sollen? Dann laden wir Sie in die Welt der visuellen Programmierung beim Aufbau einer Datenbank ein!







Mit diesem Beitrag beginnen wir eine Reihe von Tutorials, in denen wir praktische Beispiele für die Arbeit mit unserem Quarkly-Tool geben. In diesem Tutorial erstellen wir eine einfache Webanwendung, in der Mitarbeiter des Unternehmens angezeigt werden. Bei der Erstellung der Anwendung wurde kein einziger Mitarbeiter der Russian Railways verletzt.







Die Front wird mit Quarkly erstellt und die Daten werden aus der Datenbank in Airtable gezogen. Am Ausgang erhalten wir eine mit der Datenbank synchronisierte Reaktionsanwendung.









Präambel. Warum Airtable



Airtable ist ein beliebtes No-Code-Tool, mit dem Sie Ihre Datenbanken groß machen können. Sie sehen aus wie Tabellen, haben aber eine viel leistungsfähigere Funktionalität. Insbesondere für unsere Lektion wurde Airtable ausgewählt, da Daten auf einfache Weise über die API übertragen werden können.







Airtable, . Airtable Chat & Community .







Quarkly, :







  • . , : email . — .
  • . Airtable, .


, , :











1. Quarkly



:



  1. Quarkly, Airtable Example;
  2. ;
  3. . + Team;







  4. (StackItem) ;







    «» Convert to Component. EmployeeCard.



  5. react-, -.


:



  1. . , ;



  2. EmployeeCard Stack. Stack , EmployeeCard: , «» Convert to Component. EmployeeTable.







    , . Airtable.




2. Airtable



Airtable /.







  1. Add a base, . Start with a template;



  2. HR & Recruiting Employee directory. Use template;



  3. ;





, .









3. API



Airtable API. , , Airtable .







  1. API : https://airtable.com/api



  2. Employee directory. AUTHENTICATION.



  3. , EXAMPLE USING BEARER TOKEN (RECOMMENDED).



    :



    $ curl https://api.airtable.com/v0/app2MdLITmRTBsrkg/Employee%20directory \

    -H "Authorization: Bearer YOUR_API_KEY"




  4. YOUR_API_KEY. , . .



  5. API Generate API key;



  6. . 3. .




4. Airtable Quarkly



EmployeeTable , API.







  1. . Components <> EmployeeTable ( );



  2. :



  3. :



    import React from "react";
          
          





    :



    import React, { useEffect, useState } from "react";
          
          





    useEffect useState, ;
  4. , EmployeeCard:



    import EmployeeCard from "./EmployeeCard";
          
          



  5. children ( ) override (, ):



    const EmployeeTable = props => {
    	const {
    		children,
    		rest
    	} = useOverrides(props, overrides, defaultProps);
          
          





    :



    const EmployeeTable = props => {
    	const {
    		override,
    		rest
    	} = useOverrides(props, overrides, defaultProps);
          
          



  6. useState, :



    const [employees, setEmployees] = useState([]);
          
          



  7. useEffect, API Airtable setEmployees.



    , . fetch URL , ?view=All%20employees. headers API , 3 , 4.



    useEffect(() => {
    			fetch("https://api.airtable.com/v0/appWw7KBKSc9bPjZE/Employee%20directory?view=All%20employees", {
    				headers: {
    					'Authorization': 'Bearer YOUR_API_KEY'
    				}
    			})
    			.then(response => response.json())
    			.then(data => setEmployees(data.records.map(({ fields }) => fields)));
    	}, []);
          
          



  8. , props override. , .



    :



    return <Stack {...rest}>
    		{children}
    	</Stack>;
    };
          
          





    :



    return <Stack {...rest}>
    		{
    			employees.map(employee => <EmployeeCard  {...override("employeeCard")}  employee={employee} />)
    		}
    	</Stack>;
    };
          
          



  9. Ctrl + S ( Cmd + S Mac). :



    import React, { useEffect, useState } from "react";
    import { useOverrides, Stack } from "@quarkly/components";
    import EmployeeCard from "./EmployeeCard";
    const defaultProps = {
    	"margin-top": "40px"
    };
    const overrides = {};
    
    const EmployeeTable = props => {
    	const {
    		override,
    		rest
    	} = useOverrides(props, overrides, defaultProps);
    
    	const [employees, setEmployees] = useState([]);
    
    	useEffect(() => {
    			fetch("https://api.airtable.com/v0/appWw7KBKSc9bPjZE/Employee%20directory?view=All%20employees", {
    				headers: {
    					'Authorization': 'Bearer YOUR_API_KEY'
    				}
    			})
    			.then(response => response.json())
    			.then(data => setEmployees(data.records.map(({ fields }) => fields)));
    	}, []);
    	
    	return <Stack {...rest}>
    		{
    			employees.map(employee => <EmployeeCard  {...override("employeeCard")} employee={employee} />)
    		}
    	</Stack>;
    };
    
    Object.assign(EmployeeTable, {
    	...Stack,
    	defaultProps,
    	overrides
    });
    export default EmployeeTable;
          
          





    : API YOUR_API_KEY.


! Airtable, employees map. employees <EmployeeCard/>, .







EmpolyeeCard .









5. EmpolyeeCard



.







  1. . Components, EmployeeCard, <>.
  2. :



    import React from "react";
    import { useOverrides, Override, StackItem } from "@quarkly/components";
    import { Box, Text } from "@quarkly/widgets";
    const defaultProps = {
    	"width": "25%",
    	"lg-width": "50%",
    	"sm-width": "100%"
    };
    const overrides = {
    	"box": {
    		"kind": "Box",
    		"props": {
    			"height": "0",
    			"margin": "0 0 20px 0",
    			"padding-bottom": "100%",
    			"background": "url(https://images.unsplash.com/photo-1503443207922-dff7d543fd0e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=582&q=80) 50% 0/cover no-repeat"
    		}
    	},
    	"text": {
    		"kind": "Text",
    		"props": {
    			"color": "--grey",
    			"margin": "0",
    			"children": "CEO"
    		}
    	},
    	"text1": {
    		"kind": "Text",
    		"props": {
    			"as": "h3",
    			"font": "--headline3",
    			"margin": "5px 0 20px 0",
    			"children": "Nathan K. Joe"
    		}
    	},
    	"text2": {
    		"kind": "Text",
    		"props": {
    			"as": "p",
    			"margin": "20px 0 5px 0",
    			"children": "This space is 100% editable. Use it to introduce a team member, describe their work experience and role within the company. This is also a great place to highlight a team member's strong sides."
    		}
    	}
    };
    
    const EmployeeCard = props => {
    	const {
    		override,
    		children,
    		rest
    	} = useOverrides(props, overrides, defaultProps);
    	return <StackItem {...rest}>
    		<Override slot="StackItemContent" flex-direction="column" />
    		<Box {...override("box")} />
    		<Text {...override("text")} />
    		<Text {...override("text1")} />
    		<Text {...override("text2")} />
    		{children}
    	</StackItem>;
    };
    
    Object.assign(EmployeeCard, { ...StackItem,
    	defaultProps,
    	overrides
    });
    export default EmployeeCard;
          
          



  3. :



    } = useOverrides(props, overrides, defaultProps);
          
          





    :



    const { employee = {} } = rest;
          
          





    employee .
  4. , , . :



    <Box {...override("box")} />
          
          





    :



    <Box {...override("box")} background-image={`url(${employee.Photo && employee.Photo[0] && employee.Photo[0].url})`}/>
          
          





    :



    "background": "url(https://images.unsplash.com/photo-1503443207922-dff7d543fd0e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=582&q=80) 50% 0/cover no-repeat"
          
          





    :



    "background-size": "cover",
    "background-position": "center",
    "background-image": "url(https://images.unsplash.com/photo-1503443207922-dff7d543fd0e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=582&q=80) 50% 0/cover no-repeat"
          
          





    :



  5. , . API Airtable . https://airtable.com/api, .



    EMPLOYEE DIRECTORY TABLE.



    , :



    Name

    Department

    Home address

    Email address

    DOB

    Start date

    Phone

    Reports to

    Title

    Status

    Photo

    Location
  6. Title. :



    <Text {...override("text")} />
          
          





    :



    <Text {...override("title")} children={employee.Title} />
          
          





    overrides , .



    :



    "text": {
    	"kind": "Text",
    	"props": {
    		"color": "--grey",
    		"margin": "0",
    		"children": "CEO"
    	}
    },
          
          





    :



    "title": {
    	"kind": "Text",
    	"props": {
    		"color": "--grey",
    		"margin": "0",
    		"children": "Title"
    	}
    },
          
          





    :







    : .
  7. Name Home address.



    :



    <Text {...override("text1")} />
    <Text {...override("text2")} />
          
          





    :



    <Text {...override("name")} children={employee.Name} />
    <Text {...override("address")} children={employee['Home address']} />
          
          





    overrides. :



    "text1": {
    	"kind": "Text",
    	"props": {
    		"as": "h3",
    		"font": "--headline3",
    		"margin": "5px 0 20px 0",
    		"children": "Nathan K. Joe"
    	}
    },
    "text2": {
    	"kind": "Text",
    	"props": {
    		"as": "p",
    		"margin": "20px 0 5px 0",
    		"children": "This space is 100% editable. Use it to introduce a team member, describe their work experience and role within the company. This is also a great place to highlight a team member's strong sides."
    	}
    }
          
          





    :



    "name": {
    	"kind": "Text",
    	"props": {
    		"as": "h3",
    		"font": "--headline3",
    		"margin": "5px 0 5px 0",
    		"children": "Name"
    	}
    },
    "address": {
    	"kind": "Text",
    	"props": {
    		"as": "p",
    		"margin": "10px 0 5px 0",
    		"children": "Home address"
    	}
    },
          
          





    :



  8. Text . Department Reports to, DEPARTMENTS TABLE.



    :



    <Text {...override("address")} children={employee['Home address']} />
    <Text {...override("Start date")} children={`Start date: ${employee['Start date']}`} />
    <Text {...override("Status")} children={employee['Status']} />
    <Text {...override("DOB")} children={`Birth date: ${employee['DOB']}`} />
          
          









    "address": {
    	"kind": "Text",
    	"props": {
    		"as": "p",
    		"margin": "10px 0 5px 0",
    		"children": "Home address"
    	}
    },
    "Start date": {
    	"kind": "Text",
    	"props": {
    		"as": "p",
    		"margin": "10px 0 5px 0",
    		"children": "Start date"
    	
    	}
    },
    "Status": {
    	"kind": "Text",
    	"props": {
    		"as": "p",
    		"margin": "10px 0 5px 0",
    		"children": "Status"
    	}
    },
    "DOB": {
    	"kind": "Text",
    	"props": {
    		"as": "p",
    		"margin": "10px 0 5px 0",
    		"children": "Birth date"
    	}
    },
          
          





    :



  9. Fügen wir nun zwei Link- Komponenten hinzu , in denen wir Telefon und E-Mail haben werden :



    import { Box, Text } from "@quarkly/widgets";
          
          





    ändern:



    import { Box, Text, Link } from "@quarkly/widgets";
          
          





    Und fügen Sie die folgenden Zeilen hinzu:



    <Link {...override("Email address")} children={employee['Email address']} href={`mailto:${employee['Email address']}`} />
    <Link {...override("Phone")} children={employee['Phone']} href={`tel:${employee['Phone']}`}/>
          
          





    Nicht zu vergessen ihre Überschreibungen :



    "Email address": {
    	"kind": "Link",
    	"props": {
    		"margin": "10px 0 5px 0",
    		"color": "--primary",
    		"text-decoration": "none",
    		"children": "Email"
    	}
    },
    "Phone": {
    	"kind": "Link",
    	"props": {
    		"margin": "10px 0 5px 0",
    		"color": "--primary",
    		"text-decoration": "none",
    		"children": "Phone"
    	}
    },
          
          





    Ergebnis überprüfen:





Unser endgültiger Code sieht folgendermaßen aus:







import React from "react";
import { useOverrides, Override, StackItem } from "@quarkly/components";
import { Box, Text, Link } from "@quarkly/widgets";
const defaultProps = {
	"width": "25%",
	"lg-width": "50%",
	"sm-width": "100%"
};
const overrides = {
	"box": {
		"kind": "Box",
		"props": {
			"height": "0",
			"margin": "0 0 20px 0",
			"padding-bottom": "100%",
			"background-size": "cover",
			"background-position": "center",
			"background-image": "url(https://images.unsplash.com/photo-1503443207922-dff7d543fd0e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=582&q=80) 50% 0/cover no-repeat"
		}
	},
	"title": {
		"kind": "Text",
		"props": {
			"color": "--grey",
			"margin": "0",
			"children": "title"
		}
	},
	"name": {
		"kind": "Text",
		"props": {
			"as": "h3",
			"font": "--headline3",
			"margin": "5px 0 5px 0",
			"children": "Name"
		}
	},
	"address": {
		"kind": "Text",
		"props": {
			"as": "p",
			"margin": "10px 0 5px 0",
			"children": "Home address"
		}
	},
	"Start date": {
		"kind": "Text",
		"props": {
			"as": "p",
			"margin": "10px 0 5px 0",
			"children": "Start date"
		}
	},
	"Status": {
		"kind": "Text",
		"props": {
			"as": "p",
			"margin": "10px 0 5px 0",
			"children": "Status"
		}
	},
	"DOB": {
		"kind": "Text",
		"props": {
			"as": "p",
			"margin": "10px 0 5px 0",
			"children": "Birth date"
		}
	},
	"Email address": {
		"kind": "Link",
		"props": {
			"margin": "10px 0 5px 0",
			"color": "--primary",
			"text-decoration": "none",
			"children": "Email"
		}
	},
	"Phone": {
		"kind": "Link",
		"props": {
			"margin": "10px 0 5px 0",
			"color": "--primary",
			"text-decoration": "none",
			"children": "Phone"
		}
	},
};

const EmployeeCard = props => {
	const {
		override,
		children,
		rest
	} = useOverrides(props, overrides, defaultProps);
	
		const { employee = {} } = rest;

	
	return <StackItem {...rest}>
		<Override slot="StackItemContent" flex-direction="column" />
		<Box {...override("box")} background-image={`url(${employee.Photo[0].url})`}/>
		<Text {...override("title")} children={employee.Title} />
		<Text {...override("name")} children={employee.Name} />
		<Text {...override("address")} children={employee['Home address']} />
		<Text {...override("Start date")} children={`Start date: ${employee['Start date']}`} />
		<Text {...override("Status")} children={employee['Status']} />
		<Text {...override("DOB")} children={`Birth date: ${employee['DOB']}`} />
		<Link {...override("Email address")} children={employee['Email address']} href={`mailto:${employee['Email address']}`} />
		<Link {...override("Phone")} children={employee['Phone']} href={`tel:${employee['Phone']}`}/>
		{children}
	</StackItem>;
};

Object.assign(EmployeeCard, { ...StackItem,
	defaultProps,
	overrides
});
export default EmployeeCard;
      
      





Wir verpflichten uns zu GitHub und veröffentlichen in Netlify:











Wir warten ein paar Minuten und überprüfen: https://keen-varahamihira-c54ae1.netlify.app/













Ändern Sie die Daten in der Datenbank, um die Synchronisierung zu überprüfen:









Sie werden nun in der Anwendung angezeigt:









In Zukunft können wir unsere Elemente mit Karten nach Belieben gestalten, ohne den konfigurierten Import von Airtable zu unterbrechen. Ein Beispiel ist zu sehen, hier .







GitHub-Repository: https://github.com/quarkly-dev/Getting-data-from-Airtable-tutorial







Vielen Dank für Ihre Aufmerksamkeit!







— . , , .








All Articles