ReactJS Github API – Github User Check Projesi

ReactJS Github API kullanarak bir Github user sorgu projesi geliştireceğiz.

Bir input kısmımız olacak. Bu kısma girilen kullanıcı adı, Github’un bize sunduğu kullanıcı isimlerinin olduğu API’den kontrol edilecek. Eğer API’de girilen kullanıcı varsa ekrana o kullanıcının takipçi sayısı, takip ettiği sayısı ve depo sayısı yazdırılacak. Kullanacağımız API’ye buraya tıklayarak ulaşabilirsiniz.

Proje sonundaki görünüm aşağıdaki gibidir.

Projeye başlamadan önce standart bir React projesi oluşturun. Ve aşağıdaki kodları yazın.

<pre style="background: rgb(238, 238, 238); border: 1px dashed rgb(153, 153, 153); line-height: 14px; outline: 0px; overflow: auto; padding: 5px; vertical-align: baseline; width: 592.016px;"><code style="background-attachment: initial; background-clip: initial; background-color: #f1f1f1; background-origin: initial; background-position: 0% 0%; background-repeat: no-repeat; background-size: initial; background: url("images/code.gif") left top no-repeat rgb(241, 241, 241); border-color: rgb(221, 221, 221); border-image: initial; border-style: dotted dotted dotted solid; border-width: 1px 1px 1px 10px; display: block; margin: 0px; outline: 0px; padding: 20px; vertical-align: baseline;">const API = 'https://api.github.com/users';
class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      username: 'reactjs',
      name:'',
      avatar:'',
      location:'',
      repos:'',
      followers: '',
      following:'',
      homeUrl:'',
      notFound:''
    }
  }

Yukardaki kodlarda öncelikle API isimli bir değişken oluşturduk ve içerisine Github API bağlantısını yazdık. Veri çekmek için API değişkenini kullanacağız.

Daha sonra bir React componentı oluşturduk ve içerisine boş değerler verdik. BU değerleri API’den gelen verileri kullanarak dolduracağız.

Sonrasında ise aşağıdaki kodları yazıyoruz.

<pre style="background: rgb(238, 238, 238); border: 1px dashed rgb(153, 153, 153); line-height: 14px; outline: 0px; overflow: auto; padding: 5px; vertical-align: baseline; width: 592.016px;"><code style="background-attachment: initial; background-clip: initial; background-color: #f1f1f1; background-origin: initial; background-position: 0% 0%; background-repeat: no-repeat; background-size: initial; background: url("images/code.gif") left top no-repeat rgb(241, 241, 241); border-color: rgb(221, 221, 221); border-image: initial; border-style: dotted dotted dotted solid; border-width: 1px 1px 1px 10px; display: block; margin: 0px; outline: 0px; padding: 20px; vertical-align: baseline;">  fetchProfile(username) { 
    let url = `${API}/${username}`;
    fetch(url)
      .then((res) => res.json() )
      .then((data) => {
        this.setState({
          username: data.login,
          name: data.name,
          avatar: data.avatar_url,
          location: data.location,
          repos: data.public_repos,
          followers: data.followers,
          following: data.following,
          homeUrl: data.html_url,
          notFound: data.message
        })
      })
      .catch((error) => console.log('Oops! . Bir Problem Var.') )
  }

Yukarıdaki kodları yazarak projemizle API arasındaki bağlantıyı yapıyoruz. Eğer bağlantı başarısız olursa ekrana “Bir Problem Var.” mesajı yazdırılacak.

Artık verileri ekrana yazdırmaya hazırız. Güzel gözükmesi için yukarıdaki resimde olduğu gibi bir card içerisinde ekrana yazdıracağız. Bu yüzden aşağıdaki kodları yazıyoruz.

<pre style="background: rgb(238, 238, 238); border: 1px dashed rgb(153, 153, 153); line-height: 14px; outline: 0px; overflow: auto; padding: 5px; vertical-align: baseline; width: 592.016px;"><code style="background-attachment: initial; background-clip: initial; background-color: #f1f1f1; background-origin: initial; background-position: 0% 0%; background-repeat: no-repeat; background-size: initial; background: url("images/code.gif") left top no-repeat rgb(241, 241, 241); border-color: rgb(221, 221, 221); border-image: initial; border-style: dotted dotted dotted solid; border-width: 1px 1px 1px 10px; display: block; margin: 0px; outline: 0px; padding: 20px; vertical-align: baseline;">  componentDidMount() {
    this.fetchProfile(this.state.username);
  }
  render() {
    return (
      <div>
         <section id="card">
           <SearchProfile fetchProfile={this.fetchProfile.bind(this)}/>
           <Profile data={this.state} />
         </section>
                </div>
    )
  }
}
class SearchProfile extends React.Component {
  render() {
    return (
      <div className="search--box">
         <form onSubmit={this.handleForm.bind(this)}>
           <label><input type="search" ref="username" placeholder="Kullanıcı Adı Gir + Enter"/></label>
         </form>
      </div>
    )
  }
  
  handleForm(e) {
   e.preventDefault();
    let username = this.refs.username.getDOMNode().value
    this.props.fetchProfile(username);
    this.refs.username.getDOMNode().value = '';
  }
}

Bu kodlarla beraber arama çubuğumuzu oluşturduk ve DOM kullanarak yapılan aramaya göre API’den ilgili veriyi almasını sağladık.

Daha sonrasında verileri ekrana yazdırmak için aşağıdaki kodlarla card yapımızı oluşturuyoruz.

<pre style="background: rgb(238, 238, 238); border: 1px dashed rgb(153, 153, 153); line-height: 14px; outline: 0px; overflow: auto; padding: 5px; vertical-align: baseline; width: 592.016px;"><code style="background-attachment: initial; background-clip: initial; background-color: #f1f1f1; background-origin: initial; background-position: 0% 0%; background-repeat: no-repeat; background-size: initial; background: url("images/code.gif") left top no-repeat rgb(241, 241, 241); border-color: rgb(221, 221, 221); border-image: initial; border-style: dotted dotted dotted solid; border-width: 1px 1px 1px 10px; display: block; margin: 0px; outline: 0px; padding: 20px; vertical-align: baseline;">class Profile extends React.Component {
  render() {
    let data = this.props.data;
    let followers = `${data.homeUrl}/followers`;
    let repositories = `${data.homeUrl}?tab=repositories`;
    let following = `${data.homeUrl}/following`;
    if (data.notFound === 'Not Found')
      return (
         <div className="notfound">
            <h2>Oops !!!</h2>
            <p>Bulunamadı </p>
         </div>
      );
      else
      return (
        <section className="github--profile">
          <div className="github--profile__info">
            <a href={data.homeUrl} target="_blank" title={data.name || data.username}><img src={data.avatar} alt={data.username}/></a>
            <h2><a href={data.homeUrl} title={data.username} target="_blank">{data.name || data.username}</a></h2>
            <h3>{data.location || 'SpringBoard Assignment'}</h3>
          </div>
          <div className="github--profile__state">
            <ul>
               <li>
                  <a href={followers} target="_blank" title="Takipçi Sayısı"><i>{data.followers}</i><span>Takipçi </span></a>
               </li>
               <li>
                  <a href={repositories} target="_blank" title="Depo Sayısı"><i>{data.repos}</i><span>Depolar</span></a>
               </li>
               <li>
                  <a href={following} target="_blank" title="Takip Edilen Sayısı"><i>{data.following}</i><span>Takip Edilen</span></a>
               </li>
            </ul>
          </div>
        </section>
      );
  }
}

Yukarıdaki kodlarda gerekli olan bilgileri yazdırmak için “followers,following” gibi değişkenler oluşturduk. Sonrasında HTML kodlarını yazdığımız yerde ilgili yere ilgili veriyi çektik.

Son olarak aşağıdaki kodu yazarak projemizi çalışmaya hazır bir hâle getiriyoruz.

<pre style="background: rgb(238, 238, 238); border: 1px dashed rgb(153, 153, 153); line-height: 14px; outline: 0px; overflow: auto; padding: 5px; vertical-align: baseline; width: 592.016px;"><code style="background-attachment: initial; background-clip: initial; background-color: #f1f1f1; background-origin: initial; background-position: 0% 0%; background-repeat: no-repeat; background-size: initial; background: url("images/code.gif") left top no-repeat rgb(241, 241, 241); border-color: rgb(221, 221, 221); border-image: initial; border-style: dotted dotted dotted solid; border-width: 1px 1px 1px 10px; display: block; margin: 0px; outline: 0px; padding: 20px; vertical-align: baseline;">
React.render(<App />, document.body);

Daha güzel bir görünüm için aşağıdaki CSS kodlarını yazıyoruz.

<pre style="background: rgb(238, 238, 238); border: 1px dashed rgb(153, 153, 153); line-height: 14px; outline: 0px; overflow: auto; padding: 5px; vertical-align: baseline; width: 592.016px;"><code style="background-attachment: initial; background-clip: initial; background-color: #f1f1f1; background-origin: initial; background-position: 0% 0%; background-repeat: no-repeat; background-size: initial; background: url("images/code.gif") left top no-repeat rgb(241, 241, 241); border-color: rgb(221, 221, 221); border-image: initial; border-style: dotted dotted dotted solid; border-width: 1px 1px 1px 10px; display: block; margin: 0px; outline: 0px; padding: 20px; vertical-align: baseline;">@import url(https://fonts.googleapis.com/css?family=Titillium+Web:400,700,600);

$titillium :'Titillium Web', sans-serif;
$primary-color:#1a4e8e;
$gray:#ecf0f1;

body{background:$gray; font-family:$titillium;font-weight:400;}
*{
	margin:0;
	padding:0;
    box-sizing: border-box;
    &:active, &:focus{
    	border: 0;
    	outline: 0;
    }
}
a{text-decoration: none;display: inline-block;}

#card{width:25rem;margin:auto;overflow:hidden;
	position: absolute;top: 50%;left: 50%;
	transform: translateX(-50%) translateY(-50%);
}
.search--box{
	label{position: relative;
		&:after{position: absolute;content:"";
		border-right:.625rem solid transparent;border-left:.625rem solid transparent;border-bottom:.625rem solid #fff;
		bottom:-1.0625rem;right:50%;margin-right:-0.3125rem;
		}
	}
	input[type='search']{width:100%; font:1rem $titillium;color:$primary-color; border:0;padding:.75rem .9375rem .9375rem;
		background:darken($gray, 2%);border-radius:.3125rem .3125rem 0 0;text-align: center;box-sizing: border-box;
	}
}
.notfound{background: #fff;padding:1.875rem;text-align: center;
	h2{font-size:2rem;color:lighten($primary-color, 11%);margin-bottom:.625rem;}
	p{font-size:1rem;color:darken($gray, 25%);}
}
.github--profile{width:100%;
	&__info{background: #fff;text-align: center;padding:1.875rem .9375rem;
		img{width:6.25rem;height:6.25rem;border-radius:50%;display: block;box-shadow:0 0 .0625rem rgba(0,0,0,.5);}
		h2 a{font-size:1.65rem;color:lighten($primary-color, 11%);}
		h3{font-size:1.1885rem;color:darken($gray, 16%);}
	}
	&__state{background:$primary-color;text-align: center;padding:1.875rem .9375rem;border-radius:0 0 .3125rem .3125rem;
		ul{direction:ltr;}
		li{list-style: none;display: inline-block;margin-right:1rem; &:last-child{margin-right:0;}}
		a{color:#fff;}
		i{font-size:1.5rem;font-weight:700;font-style: normal;display: block;}
		span{font-size:.844rem;letter-spacing:.0625rem;color:lighten($primary-color, 17%);}
	}
}

.hesmaili{font-size:.9rem;font-weight:400;color:darken($gray, 19%); 
position: absolute;bottom:3%;left:50%;transform: translateX(-50%);
	a{color:lighten($primary-color, 11%);}
}

Projemiz hazır. Eğer kod yazmadan direkt olarak denemek isterseniz buraya tıklayarak codepen sayfasına ulaşabilirsiniz.

Kaynak : Github Profile Card (codepen.io)

Yorum yapın