Skip to content

Commit 33dab59

Browse files
committed
feat: Implement experience card
1 parent 8856666 commit 33dab59

File tree

3 files changed

+166
-26
lines changed

3 files changed

+166
-26
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="24dp"
3+
android:height="24dp"
4+
android:viewportWidth="960"
5+
android:viewportHeight="960">
6+
<path
7+
android:fillColor="#e3e3e3"
8+
android:pathData="M200,840q-33,0 -56.5,-23.5T120,760v-560q0,-33 23.5,-56.5T200,120h240q17,0 28.5,11.5T480,160q0,17 -11.5,28.5T440,200L200,200v560h560v-240q0,-17 11.5,-28.5T800,480q17,0 28.5,11.5T840,520v240q0,33 -23.5,56.5T760,840L200,840ZM760,256L416,600q-11,11 -28,11t-28,-11q-11,-11 -11,-28t11,-28l344,-344L600,200q-17,0 -28.5,-11.5T560,160q0,-17 11.5,-28.5T600,120h200q17,0 28.5,11.5T840,160v200q0,17 -11.5,28.5T800,400q-17,0 -28.5,-11.5T760,360v-104Z"/>
9+
</vector>

composeApp/src/wasmJsMain/kotlin/org/nsh07/nsh07/ui/AppScreen.kt

Lines changed: 52 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,30 @@ import org.jetbrains.compose.resources.painterResource
2525
fun AppScreen(modifier: Modifier = Modifier) {
2626
val uriHandler = LocalUriHandler.current
2727
var selectedItem by remember { mutableStateOf(0) }
28+
2829
val paragraphs = remember {
2930
listOf(
3031
"Hi, I'm Nishant. I'm currently a hobbyist software developer and a computer science student at the Indian Institute of Information Technology Bhagalpur.",
3132
"I've written a variety of programs in multiple languages over my years as a hobbyist developer since back when I was in middle and high school (~2019) in Python and C++, spanning multiple areas like games, CLI tools, GUI tools and automation scripts. I'm continuing to work towards persuing my passion of software development as my career, now as a CS student."
3233
)
3334
}
3435

36+
val experiences = remember {
37+
listOf(
38+
Experience(
39+
start = "May",
40+
end = "June 2022",
41+
position = "Research Asst. (Android Dev)",
42+
description = "Created an Android app for collecting and compiling a validation dataset for a binary image classification model from scratch. Generated output from the model on-device for a fast, offline experience. Designed an intuitive UI, with options for viewing and editing entries in the dataset. Optimized the UX: the validation dataset can be exported to the device with the click of a button.",
43+
company = "AIIMS Guwahati",
44+
companyUrl = "https://aiimsguwahati.ac.in/",
45+
skills = listOf("Kotlin", "Jetpack Compose", "PyTorch Android", "Android SDK")
46+
)
47+
)
48+
}
49+
50+
val cardPadding = remember { 16.dp }
51+
3552
Row(
3653
modifier = Modifier
3754
.padding(horizontal = 48.dp)
@@ -42,15 +59,13 @@ fun AppScreen(modifier: Modifier = Modifier) {
4259
Text(
4360
"Nishant Mishra",
4461
style = typography.displayLarge.copy(fontSize = 48.sp),
45-
color = colorScheme.onSurface,
46-
// modifier = Modifier.padding(start = 20.dp)
62+
color = colorScheme.onSurface
4763
)
4864
Spacer(Modifier.height(4.dp))
4965
Text(
5066
"Mobile app developer",
5167
style = typography.titleLarge,
52-
color = colorScheme.onSurface,
53-
// modifier = Modifier.padding(start = 20.dp)
68+
color = colorScheme.onSurface
5469
)
5570
Spacer(Modifier.height(20.dp))
5671
Text(
@@ -87,8 +102,7 @@ fun AppScreen(modifier: Modifier = Modifier) {
87102

88103
Row(
89104
horizontalArrangement = Arrangement.spacedBy(4.dp),
90-
verticalAlignment = Alignment.CenterVertically,
91-
// modifier = Modifier.padding(start = 20.dp)
105+
verticalAlignment = Alignment.CenterVertically
92106
) {
93107
IconButton(onClick = { uriHandler.openUri("https://github.com/nsh07") }) {
94108
Icon(
@@ -123,16 +137,21 @@ fun AppScreen(modifier: Modifier = Modifier) {
123137

124138
LazyColumn(
125139
contentPadding = PaddingValues(vertical = 96.dp),
126-
modifier = Modifier.fillMaxHeight().weight(1f)
140+
modifier = Modifier.fillMaxHeight().weight(1.1f)
127141
) {
128142
items(paragraphs) {
129143
Text(
130144
it,
131145
style = typography.bodyLarge,
132146
color = colorScheme.onSurfaceVariant,
133-
modifier = Modifier.padding(bottom = 16.dp)
147+
modifier = Modifier.padding(start = cardPadding, bottom = 16.dp, end = cardPadding)
134148
)
135149
}
150+
item { Spacer(Modifier.height(112.dp)) }
151+
items(experiences) {
152+
ExperienceCard(experience = it, cardPadding = cardPadding)
153+
}
154+
item { Spacer(Modifier.height(112.dp)) }
136155
item {
137156
Column(
138157
horizontalAlignment = Alignment.CenterHorizontally,
@@ -148,24 +167,12 @@ fun AppScreen(modifier: Modifier = Modifier) {
148167
Text("Work in progress", style = typography.headlineSmall)
149168
}
150169
}
170+
item { Spacer(Modifier.height(112.dp)) }
151171
item {
152-
Text(
153-
buildAnnotatedString {
154-
append("Layout inspired by ")
155-
withLink(
156-
LinkAnnotation.Url(
157-
url = "https://brittanychiang.com/",
158-
styles = TextLinkStyles(SpanStyle(color = colorScheme.onSurface))
159-
)
160-
) {
161-
append("Brittany Chiang")
162-
}
163-
append("'s website")
164-
},
165-
color = colorScheme.outline,
166-
style = typography.bodyMedium
167-
)
168-
Row(verticalAlignment = Alignment.CenterVertically) {
172+
Row(
173+
verticalAlignment = Alignment.CenterVertically,
174+
modifier = Modifier.padding(horizontal = cardPadding)
175+
) {
169176
Text(
170177
buildAnnotatedString {
171178
append("Built with ")
@@ -223,7 +230,26 @@ fun AppScreen(modifier: Modifier = Modifier) {
223230
}
224231
append('.')
225232
},
226-
color = colorScheme.outline, style = typography.bodyMedium
233+
color = colorScheme.outline,
234+
style = typography.bodyMedium,
235+
modifier = Modifier.padding(horizontal = cardPadding)
236+
)
237+
Text(
238+
buildAnnotatedString {
239+
append("Layout inspired by ")
240+
withLink(
241+
LinkAnnotation.Url(
242+
url = "https://brittanychiang.com/",
243+
styles = TextLinkStyles(SpanStyle(color = colorScheme.onSurface))
244+
)
245+
) {
246+
append("Brittany Chiang")
247+
}
248+
append("'s website")
249+
},
250+
color = colorScheme.outline,
251+
style = typography.bodyMedium,
252+
modifier = Modifier.padding(horizontal = cardPadding)
227253
)
228254
}
229255
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package org.nsh07.nsh07.ui
2+
3+
import androidx.compose.animation.animateColorAsState
4+
import androidx.compose.animation.core.tween
5+
import androidx.compose.foundation.background
6+
import androidx.compose.foundation.clickable
7+
import androidx.compose.foundation.interaction.MutableInteractionSource
8+
import androidx.compose.foundation.interaction.collectIsHoveredAsState
9+
import androidx.compose.foundation.layout.*
10+
import androidx.compose.foundation.shape.CircleShape
11+
import androidx.compose.material3.Icon
12+
import androidx.compose.material3.MaterialTheme.colorScheme
13+
import androidx.compose.material3.MaterialTheme.shapes
14+
import androidx.compose.material3.MaterialTheme.typography
15+
import androidx.compose.material3.Text
16+
import androidx.compose.runtime.Composable
17+
import androidx.compose.runtime.getValue
18+
import androidx.compose.runtime.remember
19+
import androidx.compose.ui.Alignment
20+
import androidx.compose.ui.Modifier
21+
import androidx.compose.ui.draw.clip
22+
import androidx.compose.ui.platform.LocalUriHandler
23+
import androidx.compose.ui.text.intl.Locale
24+
import androidx.compose.ui.text.toUpperCase
25+
import androidx.compose.ui.unit.Dp
26+
import androidx.compose.ui.unit.dp
27+
import androidx.compose.ui.util.fastForEach
28+
import nsh07.composeapp.generated.resources.Res
29+
import nsh07.composeapp.generated.resources.open_in_browser
30+
import org.jetbrains.compose.resources.painterResource
31+
import kotlin.text.Typography.bullet
32+
import kotlin.text.Typography.mdash
33+
34+
@Composable
35+
fun ExperienceCard(
36+
experience: Experience,
37+
cardPadding: Dp,
38+
modifier: Modifier = Modifier
39+
) {
40+
val colorScheme = colorScheme
41+
val uriHandler = LocalUriHandler.current
42+
43+
val interactionSource = remember { MutableInteractionSource() }
44+
val hovered by interactionSource.collectIsHoveredAsState()
45+
46+
val backgroundColor by animateColorAsState(
47+
if (hovered) colorScheme.surfaceContainerLowest else colorScheme.surface,
48+
animationSpec = tween()
49+
)
50+
Box(
51+
modifier
52+
.clip(shapes.large)
53+
.background(backgroundColor)
54+
.clickable(
55+
onClick = { uriHandler.openUri(experience.companyUrl) },
56+
interactionSource = interactionSource
57+
)
58+
) {
59+
Row(Modifier.fillMaxWidth().padding(cardPadding)) {
60+
Text(
61+
remember { "${experience.start} $mdash ${experience.end}".toUpperCase(Locale.current) },
62+
style = typography.labelMedium,
63+
color = colorScheme.outline,
64+
modifier = Modifier.padding(vertical = 4.dp).weight(1f)
65+
)
66+
Column(Modifier.weight(3f)) {
67+
FlowRow(itemVerticalAlignment = Alignment.CenterVertically) {
68+
Text("${experience.position} $bullet ${experience.company} ")
69+
Icon(painterResource(Res.drawable.open_in_browser), null, modifier = Modifier.size(16.dp))
70+
}
71+
Text(
72+
experience.description,
73+
style = typography.bodyMedium,
74+
color = colorScheme.onSurfaceVariant,
75+
modifier = Modifier.padding(top = 8.dp)
76+
)
77+
FlowRow(
78+
horizontalArrangement = Arrangement.spacedBy(6.dp),
79+
modifier = Modifier.padding(top = 16.dp)
80+
) {
81+
experience.skills.fastForEach {
82+
Box(Modifier.clip(CircleShape).background(colorScheme.secondaryContainer)) {
83+
Text(
84+
it,
85+
style = typography.labelMedium,
86+
color = colorScheme.onSecondaryContainer,
87+
modifier = Modifier.padding(vertical = 4.dp, horizontal = 12.dp)
88+
)
89+
}
90+
}
91+
}
92+
}
93+
}
94+
}
95+
}
96+
97+
data class Experience(
98+
val start: String,
99+
val end: String,
100+
val position: String,
101+
val description: String,
102+
val company: String,
103+
val companyUrl: String,
104+
val skills: List<String>
105+
)

0 commit comments

Comments
 (0)