Skip to content

Commit f34a58d

Browse files
committed
Updating to receive extended Github user details
Minor fix: trimming username from request
1 parent 9d247d2 commit f34a58d

File tree

4 files changed

+104
-51
lines changed

4 files changed

+104
-51
lines changed

internals/github-service.go

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313
func fetchGitHubProfile(username, token string) (*views.GitHubUser, error) {
1414
ctx := context.Background()
1515

16-
// Set up GitHub client with authentication if a token is provided
1716
var client *github.Client
1817
if token != "" {
1918
ts := oauth2.StaticTokenSource(
@@ -25,7 +24,6 @@ func fetchGitHubProfile(username, token string) (*views.GitHubUser, error) {
2524
client = github.NewClient(nil)
2625
}
2726

28-
// Fetch the user details
2927
user, _, err := client.Users.Get(ctx, username)
3028
if err != nil {
3129
if rateLimitErr, ok := err.(*github.RateLimitError); ok {
@@ -34,11 +32,18 @@ func fetchGitHubProfile(username, token string) (*views.GitHubUser, error) {
3432
return nil, err
3533
}
3634

37-
// Map the GitHub API response to our GitHubUser struct
3835
return &views.GitHubUser{
39-
Login: user.GetLogin(),
40-
Name: user.GetName(),
41-
AvatarURL: user.GetAvatarURL(),
42-
Bio: user.GetBio(),
36+
Login: user.GetLogin(),
37+
Name: user.GetName(),
38+
AvatarURL: user.GetAvatarURL(),
39+
Bio: user.GetBio(),
40+
Company: user.GetCompany(),
41+
Blog: user.GetBlog(),
42+
Location: user.GetLocation(),
43+
Email: user.GetEmail(),
44+
PublicRepos: user.GetPublicRepos(),
45+
Followers: user.GetFollowers(),
46+
Following: user.GetFollowing(),
47+
CreatedAt: user.GetCreatedAt().Format("2006-01-02"),
4348
}, nil
4449
}

internals/handlers.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"go-github/views"
77
"net/http"
8+
"strings"
89
"time"
910

1011
"github.com/a-h/templ"
@@ -21,6 +22,7 @@ func render(ctx *gin.Context, status int, template templ.Component) error {
2122
func getUserHandler(ctx *gin.Context) {
2223
_, cancel := context.WithTimeout(context.Background(), appTimeout)
2324
username := ctx.Query("username")
25+
username = strings.TrimSpace(username)
2426

2527
if username == "" {
2628
username = "rajatasusual"

internals/xata-service.go

Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"fmt"
66
"go-github/views"
7+
"reflect"
78

89
"github.com/hashicorp/go-retryablehttp"
910
"github.com/xataio/xata-go/xata"
@@ -14,6 +15,19 @@ var xataURL = GetEnvVariable("XATA_DATABASE_URL")
1415
var databaseName = GetEnvVariable("XATA_DATABASE_NAME")
1516
var tableName = GetEnvVariable("XATA_TABLE_NAME")
1617

18+
// toXataValue is a helper function to convert interface{} to *xata.DataInputRecordValue
19+
func toXataValue(value interface{}) *xata.DataInputRecordValue {
20+
switch v := value.(type) {
21+
case string:
22+
return xata.ValueFromString(v)
23+
case int:
24+
return xata.ValueFromInteger(v)
25+
// Add cases for other types if needed
26+
default:
27+
return nil
28+
}
29+
}
30+
1731
func createNewEntry(inputGitHubUser *views.GitHubUser) (id string, err error) {
1832

1933
ctx := context.Background()
@@ -51,7 +65,7 @@ func FetchProfileFromXata(id string) (*views.GitHubUser, error) {
5165
return nil, fmt.Errorf("failed to create records client: %v", err)
5266
}
5367

54-
// retrieve the record
68+
// Retrieve the record
5569
getRecordRequest := xata.GetRecordRequest{
5670
RecordRequest: xata.RecordRequest{
5771
DatabaseName: xata.String(databaseName),
@@ -60,7 +74,6 @@ func FetchProfileFromXata(id string) (*views.GitHubUser, error) {
6074
RecordID: id,
6175
}
6276
recordRetrieved, err := recordsCli.Get(ctx, getRecordRequest)
63-
6477
if err != nil {
6578
return nil, fmt.Errorf("failed to get record: %v", err)
6679
}
@@ -69,13 +82,34 @@ func FetchProfileFromXata(id string) (*views.GitHubUser, error) {
6982
return nil, nil
7083
}
7184

72-
return &views.GitHubUser{
73-
Login: recordRetrieved.Data["Login"].(string),
74-
Name: recordRetrieved.Data["Name"].(string),
75-
AvatarURL: recordRetrieved.Data["AvatarURL"].(string),
76-
Bio: recordRetrieved.Data["Bio"].(string),
77-
}, nil
85+
// Create an empty GitHubUser instance
86+
user := &views.GitHubUser{}
87+
userValue := reflect.ValueOf(user).Elem()
88+
userType := userValue.Type()
89+
90+
// Populate struct fields dynamically
91+
for i := 0; i < userType.NumField(); i++ {
92+
field := userType.Field(i)
93+
fieldValue := userValue.Field(i)
94+
95+
// Get the data from recordRetrieved.Data map based on the field name
96+
if val, ok := recordRetrieved.Data[field.Name]; ok {
97+
// Type-assert and set the field value dynamically
98+
99+
if fieldValue.CanSet() {
100+
switch v := val.(type) {
101+
case string:
102+
fieldValue.SetString(v)
103+
case int:
104+
case float64:
105+
fieldValue.SetInt(int64(v))
106+
// Add cases for other types if needed, e.g., bool, float, etc.
107+
}
108+
}
109+
}
110+
}
78111

112+
return user, nil
79113
}
80114

81115
func FetchAllUsers() ([]*views.GitHubUser, error) {
@@ -113,17 +147,26 @@ func FetchAllUsers() ([]*views.GitHubUser, error) {
113147
}
114148

115149
func generateInsertRecordRequest(databaseName, tableName string, inputGitHubUser *views.GitHubUser) xata.InsertRecordWithIDRequest {
150+
body := make(map[string]*xata.DataInputRecordValue)
151+
152+
// Use reflection to iterate over fields in GitHubUser struct
153+
userType := reflect.TypeOf(*inputGitHubUser)
154+
userValue := reflect.ValueOf(*inputGitHubUser)
155+
156+
for i := 0; i < userType.NumField(); i++ {
157+
field := userType.Field(i)
158+
fieldValue := userValue.Field(i).Interface()
159+
160+
// Convert the field value to *xata.DataInputRecordValue
161+
body[field.Name] = toXataValue(fieldValue)
162+
}
163+
116164
return xata.InsertRecordWithIDRequest{
117165
RecordRequest: xata.RecordRequest{
118166
TableName: tableName,
119167
DatabaseName: &databaseName,
120168
},
121169
RecordID: inputGitHubUser.Login,
122-
Body: map[string]*xata.DataInputRecordValue{
123-
"Login": xata.ValueFromString(inputGitHubUser.Login),
124-
"Name": xata.ValueFromString(inputGitHubUser.Name),
125-
"AvatarURL": xata.ValueFromString(inputGitHubUser.AvatarURL),
126-
"Bio": xata.ValueFromString(inputGitHubUser.Bio),
127-
},
170+
Body: body,
128171
}
129172
}

views/index.templ

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
11
package views
22

33
import "go-github/views/components"
4-
// GitHubUser represents a GitHub user
4+
import "fmt"
5+
6+
// GitHubUser represents a GitHub user with extended details
57
type GitHubUser struct {
6-
Login string
7-
Name string
8-
AvatarURL string
9-
Bio string
8+
Login string
9+
Name string
10+
AvatarURL string
11+
Bio string
12+
Company string
13+
Blog string
14+
Location string
15+
Email string
16+
PublicRepos int
17+
Followers int
18+
Following int
19+
CreatedAt string
1020
}
1121

1222
templ Index(user *GitHubUser) {
@@ -21,51 +31,44 @@ templ Index(user *GitHubUser) {
2131
</h3>
2232
</nav>
2333
<div class="mt-6 w-full flex justify-center items-center flex-col">
24-
// FORM PROCESSING
25-
<form
26-
method="get"
27-
onsubmit="submit()"
28-
class="w-96"
29-
>
34+
<!-- Search Form -->
35+
<form method="get" class="w-96">
3036
<input
3137
type="text"
3238
name="username"
33-
cols="30"
34-
rows="2"
3539
class="w-full border rounded-lg mb-2 p-4"
3640
placeholder="Input username"
3741
id="username"
38-
3942
value={user.Login}
40-
4143
autocomplete="off"
42-
autofocus
4344
required
4445
/>
45-
<button
46-
class="py-1 px-4 w-full h-10 rounded-lg text-white bg-zinc-800"
47-
>
46+
<button class="py-1 px-4 w-full h-10 rounded-lg text-white bg-zinc-800">
4847
Search
4948
</button>
5049
</form>
5150
<br>
52-
<!-- RESULT PROCESSING -->
51+
52+
<!-- Profile Information -->
5353
<div class="w-full flex justify-center items-center flex-col">
54-
<img
55-
class="w-24 h-24 rounded-full"
56-
src={user.AvatarURL}
57-
/>
54+
<img class="w-24 h-24 rounded-full" src={user.AvatarURL} />
5855
<h1 class="text-3xl font-bold">{user.Name}</h1>
5956
<p>{user.Bio}</p>
57+
58+
<!-- Additional Information -->
59+
<p><strong>Username:</strong> {user.Login}</p>
60+
<p><strong>Company:</strong> {user.Company}</p>
61+
<p><strong>Blog:</strong> <a href={templ.URL(user.Blog)}>{user.Blog}</a></p>
62+
<p><strong>Location:</strong> {user.Location}</p>
63+
<p><strong>Email:</strong> {user.Email}</p>
64+
<p><strong>Public Repos:</strong> { fmt.Sprintf("%d", user.PublicRepos) }</p>
65+
<p><strong>Followers:</strong> { fmt.Sprintf("%d", user.Followers) }</p>
66+
<p><strong>Following:</strong> { fmt.Sprintf("%d", user.Following) }</p>
67+
<p><strong>Joined:</strong> {user.CreatedAt}</p>
6068
</div>
6169
</div>
6270
</main>
6371
</body>
6472
@components.Footer()
6573
</html>
66-
<script>
67-
function submit() {
68-
{ fmt.Println("Form submitted!") }
69-
}
70-
</script>
71-
}
74+
}

0 commit comments

Comments
 (0)