Création d'une page de base de données d'employés React à l'aide d'Airtable et de Quarkly

Avez-vous entendu parler d'un outil comme Airtable, mais ne saviez pas par où commencer? Ensuite, nous vous invitons dans le monde de la programmation visuelle de la construction d'une base de données!







Avec cet article, nous commençons une série de tutoriels dans lesquels nous donnerons des exemples pratiques d'utilisation de notre outil Quarkly. Dans ce tutoriel, nous allons créer une application Web simple qui affichera les employés de l'entreprise. Lors de la création de l'application, aucun employé des chemins de fer russes n'a été blessé.







Le front sera réalisé à l'aide de Quarkly et les données seront extraites de la base de données dans Airtable. En sortie, nous obtenons une application de réaction synchronisée avec la base de données.









Préambule. Pourquoi Airtable



Airtable est un outil sans code populaire où vous pouvez agrandir vos bases de données. Ils ressemblent à des tableaux, mais ils ont des fonctionnalités beaucoup plus puissantes. En particulier, pour notre leçon, Airtable a été choisi en raison de la manière facile de transférer des données via l'API.







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. Ajoutons maintenant deux composants Link , dans lesquels nous aurons le téléphone et l' e - mail :



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





    changer en:



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





    Et ajoutez les lignes suivantes:



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





    Sans oublier leurs remplacements :



    "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"
    	}
    },
          
          





    Vérification du résultat:





Notre code final ressemble à ceci:







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;
      
      





Nous nous engageons sur GitHub et publions sur Netlify:











Nous attendons quelques minutes et vérifions: https://keen-varahamihira-c54ae1.netlify.app/













Pour vérifier la synchronisation, modifiez les données dans la base de données:









Ils apparaîtront maintenant dans l'application:









À l'avenir, nous pourrons styliser nos éléments avec des cartes comme nous le souhaitons sans interrompre l'importation configurée depuis Airtable. Un exemple peut être vu ici .







Dépôt GitHub: https://github.com/quarkly-dev/Getting-data-from-Airtable-tutorial







Merci de votre attention!







— . , , .








All Articles