Skip to content

Commit 27cbb0a

Browse files
authored
Merge pull request #14 from hfidelis/@features
@features
2 parents a00c586 + 79a40cc commit 27cbb0a

File tree

11 files changed

+374
-57
lines changed

11 files changed

+374
-57
lines changed

src/assets/images/me-irl.jpeg

115 KB
Loading

src/components/icons/IconFacebook.vue

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<script lang="ts" setup>
2+
const props = defineProps({
3+
color: {
4+
type: String,
5+
required: false,
6+
default: '#0b0b0b',
7+
},
8+
size: {
9+
type: [String, Number],
10+
required: false,
11+
default: '32',
12+
},
13+
})
14+
</script>
15+
16+
<template>
17+
<svg
18+
xmlns="http://www.w3.org/2000/svg"
19+
viewBox="0 0 24 24"
20+
:width="`${props.size}px`"
21+
:heigth="`${props.size}px`"
22+
>
23+
<path
24+
d="M12 2.04C6.5 2.04 2 6.53 2 12.06C2 17.06 5.66 21.21 10.44 21.96V14.96H7.9V12.06H10.44V9.85C10.44 7.34 11.93 5.96 14.22 5.96C15.31 5.96 16.45 6.15 16.45 6.15V8.62H15.19C13.95 8.62 13.56 9.39 13.56 10.18V12.06H16.34L15.89 14.96H13.56V21.96A10 10 0 0 0 22 12.06C22 6.53 17.5 2.04 12 2.04Z"
25+
:fill="props.color"
26+
/>
27+
</svg>
28+
</template>

src/components/icons/IconTwitter.vue

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<script lang="ts" setup>
2+
const props = defineProps({
3+
color: {
4+
type: String,
5+
required: false,
6+
default: '#0b0b0b',
7+
},
8+
size: {
9+
type: [String, Number],
10+
required: false,
11+
default: '32',
12+
},
13+
})
14+
</script>
15+
16+
<template>
17+
<svg
18+
xmlns="http://www.w3.org/2000/svg"
19+
viewBox="0 0 24 24"
20+
:width="`${props.size}px`"
21+
:heigth="`${props.size}px`"
22+
>
23+
<path
24+
d="M22.46,6C21.69,6.35 20.86,6.58 20,6.69C20.88,6.16 21.56,5.32 21.88,4.31C21.05,4.81 20.13,5.16 19.16,5.36C18.37,4.5 17.26,4 16,4C13.65,4 11.73,5.92 11.73,8.29C11.73,8.63 11.77,8.96 11.84,9.27C8.28,9.09 5.11,7.38 3,4.79C2.63,5.42 2.42,6.16 2.42,6.94C2.42,8.43 3.17,9.75 4.33,10.5C3.62,10.5 2.96,10.3 2.38,10C2.38,10 2.38,10 2.38,10.03C2.38,12.11 3.86,13.85 5.82,14.24C5.46,14.34 5.08,14.39 4.69,14.39C4.42,14.39 4.15,14.36 3.89,14.31C4.43,16 6,17.26 7.89,17.29C6.43,18.45 4.58,19.13 2.56,19.13C2.22,19.13 1.88,19.11 1.54,19.07C3.44,20.29 5.7,21 8.12,21C16,21 20.33,14.46 20.33,8.79C20.33,8.6 20.33,8.42 20.32,8.23C21.16,7.63 21.88,6.87 22.46,6Z"
25+
:fill="props.color"
26+
/>
27+
</svg>
28+
</template>

src/components/icons/IconWhatsapp.vue

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<script lang="ts" setup>
2+
const props = defineProps({
3+
color: {
4+
type: String,
5+
required: false,
6+
default: '#0b0b0b',
7+
},
8+
size: {
9+
type: [String, Number],
10+
required: false,
11+
default: '32',
12+
},
13+
})
14+
</script>
15+
16+
<template>
17+
<svg
18+
xmlns="http://www.w3.org/2000/svg"
19+
viewBox="0 0 24 24"
20+
:width="`${props.size}px`"
21+
:heigth="`${props.size}px`"
22+
>
23+
<path
24+
d="M12.04 2C6.58 2 2.13 6.45 2.13 11.91C2.13 13.66 2.59 15.36 3.45 16.86L2.05 22L7.3 20.62C8.75 21.41 10.38 21.83 12.04 21.83C17.5 21.83 21.95 17.38 21.95 11.92C21.95 9.27 20.92 6.78 19.05 4.91C17.18 3.03 14.69 2 12.04 2M12.05 3.67C14.25 3.67 16.31 4.53 17.87 6.09C19.42 7.65 20.28 9.72 20.28 11.92C20.28 16.46 16.58 20.15 12.04 20.15C10.56 20.15 9.11 19.76 7.85 19L7.55 18.83L4.43 19.65L5.26 16.61L5.06 16.29C4.24 15 3.8 13.47 3.8 11.91C3.81 7.37 7.5 3.67 12.05 3.67M8.53 7.33C8.37 7.33 8.1 7.39 7.87 7.64C7.65 7.89 7 8.5 7 9.71C7 10.93 7.89 12.1 8 12.27C8.14 12.44 9.76 14.94 12.25 16C12.84 16.27 13.3 16.42 13.66 16.53C14.25 16.72 14.79 16.69 15.22 16.63C15.7 16.56 16.68 16.03 16.89 15.45C17.1 14.87 17.1 14.38 17.04 14.27C16.97 14.17 16.81 14.11 16.56 14C16.31 13.86 15.09 13.26 14.87 13.18C14.64 13.1 14.5 13.06 14.31 13.3C14.15 13.55 13.67 14.11 13.53 14.27C13.38 14.44 13.24 14.46 13 14.34C12.74 14.21 11.94 13.95 11 13.11C10.26 12.45 9.77 11.64 9.62 11.39C9.5 11.15 9.61 11 9.73 10.89C9.84 10.78 10 10.6 10.1 10.45C10.23 10.31 10.27 10.2 10.35 10.04C10.43 9.87 10.39 9.73 10.33 9.61C10.27 9.5 9.77 8.26 9.56 7.77C9.36 7.29 9.16 7.35 9 7.34C8.86 7.34 8.7 7.33 8.53 7.33Z"
25+
:fill="props.color"
26+
/>
27+
</svg>
28+
</template>
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<script setup lang="ts">
2+
import { ref, watch } from 'vue'
3+
4+
import IconFacebook from '@/components/icons/IconFacebook.vue'
5+
import IconTwitter from '@/components/icons/IconTwitter.vue'
6+
import IconLinkedin from '@/components/icons/IconLinkedin.vue'
7+
import IconWhatsapp from '@/components/icons/IconWhatsapp.vue'
8+
9+
import SocialOption from '@/types/components/social-share/SocialOption.type'
10+
11+
interface SocialShareProps {
12+
type: SocialOption
13+
url: string
14+
isDark: boolean
15+
}
16+
17+
const props = defineProps<SocialShareProps>()
18+
19+
const currentColor = ref<string>('white')
20+
21+
const getContextIcon = (type: SocialOption) => {
22+
const COMPONENTS: { [key in SocialOption]: any } = {
23+
facebook: IconFacebook,
24+
twitter: IconTwitter,
25+
linkedin: IconLinkedin,
26+
whatsapp: IconWhatsapp,
27+
}
28+
29+
return COMPONENTS[type]
30+
}
31+
32+
const getContextColor = (type: SocialOption) => {
33+
const COLORS: { [key in SocialOption]: string } = {
34+
facebook: '#1877f2',
35+
twitter: '#1da1f2',
36+
linkedin: '#0077b5',
37+
whatsapp: '#25d366',
38+
}
39+
40+
return COLORS[type]
41+
}
42+
43+
watch(
44+
() => props.type,
45+
() => {
46+
currentColor.value = getContextColor(props.type)
47+
},
48+
{ immediate: true }
49+
)
50+
</script>
51+
52+
<template>
53+
<div>
54+
<a
55+
:href="props.url"
56+
target="_blank"
57+
rel="noopener noreferrer"
58+
class="share__button"
59+
:class="isDark ? 'dark' : 'light'"
60+
:style="{ backgroundColor: getContextColor(props.type) }"
61+
>
62+
<component
63+
:is="getContextIcon(props.type)"
64+
:size="20"
65+
:color="'white'"
66+
/>
67+
</a>
68+
</div>
69+
</template>
70+
71+
<style lang="scss" scoped>
72+
@import '@/styles/app.scss';
73+
74+
.share__button {
75+
display: inline-flex;
76+
justify-content: center;
77+
align-items: center;
78+
border-radius: 50%;
79+
padding: 0.3rem;
80+
transition: all 0.3s ease-in-out;
81+
82+
&:hover {
83+
transform: scale(1.1);
84+
filter: brightness(1.8);
85+
}
86+
87+
&.dark {
88+
box-shadow: $dark-mode-shadow;
89+
}
90+
91+
&.light {
92+
box-shadow: $light-mode-shadow;
93+
}
94+
}
95+
</style>

src/locales/en-US.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@
5757
"title": "Oops! It looks like this post doesn't exists...",
5858
"subtitle": "Maybe you typed the wrong address or the post has been removed.",
5959
"back": "Back to home"
60-
}
60+
},
61+
"share": "Share",
62+
"defaultAuthor": "Heitor Fidelis"
6163
}
6264
}
6365
}

src/locales/pt-BR.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@
5757
"title": "Ops! Parece que este post não existe...",
5858
"subtitle": "Talvez você tenha digitado o endereço errado ou o post foi removido.",
5959
"back": "Voltar para o início"
60-
}
60+
},
61+
"share": "Compartilhar",
62+
"defaultAuthor": "Heitor Fidelis"
6163
}
6264
}
6365
}

src/services/post/files/django-optimizations.en-us.md

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
# Ways to optimize queries in Django 🐍🚀
1+
## Ways to optimize queries in Django 🐍🚀
22

33
We can make our operations more performant using Django's own methods, generally request delays are consequence from multiple JOINS performed inside queries, result from model's relationships.
44

5-
## 1. Using `prefetch_related()` and `select_related()`
5+
### 1. Using `prefetch_related()` and `select_related()`
66

77
When we define the ***queryset*** of a ***view*** we can perform ***JOINS*** in advance within it. Thus, we reduce the number of operations that will be realized later.
88

99
**Example:** Within the ***serializer*** used by ***view*** we need data from some entity related to the model, to fill in a field for example. So for each instance that will be serialized, a set of operations will be performed to bring this data. When performing these operations in ***view*** when defining the ***queryset***, all operations will be done in a single shot, carrying all needed data to serializer.
1010

11-
### `select_related()`: Used for 1-to-1 `OneToOneField` or `ForeignKey` relationships.
11+
**`select_related()`**: Used for 1-to-1 `OneToOneField` or `ForeignKey` relationships.
1212

13-
### `prefetch_related()`: Using for relationships where we will have several objects, such as `ManyToManyField` or reverse `ForeignKey` accesses.
13+
**`prefetch_related()`**: Using for relationships where we will have several objects, such as `ManyToManyField` or reverse `ForeignKey` accesses.
1414

15-
### Example:
15+
**Example:**
1616

1717
```python
1818
# models.py
@@ -28,7 +28,7 @@ class Employee(models.Model):
2828
company = models.ForeignKey(Company, on_delete=models.PROTECT, blank=True, null=True)
2929
```
3030

31-
### In the `Employee` entity serializer we look for the *name* of `Company` through the *FK*, each time this *serializer* receives an instance to *serialize*, it will do a *JOIN* with ` Company` to fetch the data.
31+
In the `Employee` entity serializer we look for the *name* of `Company` through the *FK*, each time this *serializer* receives an instance to *serialize*, it will do a *JOIN* with ` Company` to fetch the data.
3232

3333
```python
3434
# serializers.py
@@ -45,7 +45,7 @@ class EmployeeSerializer(serializers.ModelSerializer):
4545
]
4646
```
4747

48-
### In the `Employee` entity *view* we use `select_related()` passing the *FK* field to `Company`, thus an *INNER JOIN* is performed in the *queryset*, without the need to be performed individually in the serializer.
48+
In the `Employee` entity *view* we use `select_related()` passing the *FK* field to `Company`, thus an *INNER JOIN* is performed in the *queryset*, without the need to be performed individually in the serializer.
4949

5050
```python
5151
# views.py
@@ -54,15 +54,15 @@ class EmployeeViewSet(ModelViewSet):
5454
queryset = Employee.objects.select_related('company').order_by('pk')
5555
```
5656

57-
### With `prefetch_related()` we can do this when we have bigger relationships.
57+
With `prefetch_related()` we can do this when we have bigger relationships.
5858

59-
**In this case, `employee_set` (or the label defined in FK `related_name`) was passed as a parameter, listing the `Employees` of each `Company`.**
59+
In this case, `employee_set` (or the label defined in FK `related_name`) was passed as a parameter, listing the `Employees` of each `Company`.
6060

6161
```python
6262
queryset = Company.objects.prefetch_related('employee_set').order_by('pk')
6363
```
6464

65-
### Practical Example:
65+
**Practical Example:**
6666

6767
```python
6868
queryset = Order.objects.select_related(
@@ -78,17 +78,17 @@ queryset = Order.objects.select_related(
7878
.order_by('pk')
7979
```
8080

81-
**In the `Order` entity we are performing the *JOIN* with its foreign keys `['contract', 'interest', 'company', 'owner']`, and a `prefetch_related()` with several instances accessed through the `'__'` lookups of Django fields.**
81+
In the `Order` entity we are performing the *JOIN* with its foreign keys `['contract', 'interest', 'company', 'owner']`, and a `prefetch_related()` with several instances accessed through the `'__'` lookups of Django fields.
8282

83-
## 2. Avoiding loops and using methods like `aggregate()` and `update()`
83+
### 2. Avoiding loops and using methods like `aggregate()` and `update()`
8484

8585
We can avoid building loops using some alternatives, depending on the context.
8686

87-
### `aggregate()`
87+
**`aggregate()`**
8888

89-
**Inserts a field into the *queryset* and finally returns a dictionary `(dict)`.**
89+
Inserts a field into the *queryset* and finally returns a dictionary `(dict)`.
9090

91-
### Example:
91+
**Example:**
9292

9393
- Using `loop`
9494

@@ -110,9 +110,9 @@ We can avoid building loops using some alternatives, depending on the context.
110110
total_price = items.get('total_price', 0)
111111
```
112112

113-
### Both ways are iterating over the objects from Item entity and adding their price field, however using `aggregate` we are performing a more performant operation due to several Django reasons and also database optimizations.
113+
Both ways are iterating over the objects from Item entity and adding their price field, however using `aggregate` we are performing a more performant operation due to several Django reasons and also database optimizations.
114114

115-
### Practical Example:
115+
**Practical Example:**
116116

117117
```python
118118
# serializers.py
@@ -132,13 +132,13 @@ def get_contract_price(self, obj):
132132
return price
133133
```
134134

135-
**Here we are filtering a set of objects, then we are aggregating in the new field `total_price` the values ​from `price` field that is present in the primary key object of the `item` field. We perform aggregation with the `Sum()` operator and the `F()` operator, `F()` converts a field to be used in operations.**
135+
Here we are filtering a set of objects, then we are aggregating in the new field `total_price` the values ​from `price` field that is present in the primary key object of the `item` field. We perform aggregation with the `Sum()` operator and the `F()` operator, `F()` converts a field to be used in operations.
136136

137-
### `update()`
137+
**`update()`**
138138

139-
### In the same way that `aggregate` is more performant than loops, making some changes in objects using `update()` becomes more performant than changing directly from object's fields.
139+
In the same way that `aggregate` is more performant than loops, making some changes in objects using `update()` becomes more performant than changing directly from object's fields.
140140

141-
### Example:
141+
**Example:**
142142

143143
- Accessing fields
144144

@@ -168,13 +168,13 @@ items.filter(pk__in=[15, 16, 17]).update(name='Teste')
168168
items.filter(category='technology').update(category='tech')
169169
```
170170

171-
### Both ways are updating the item's `name` field with `pk=15`, but the second becomes more performant for bulk updates or when we don't need to directly access the field. The first mode is more necessary when we need to perform some calc or logic.
171+
Both ways are updating the item's `name` field with `pk=15`, but the second becomes more performant for bulk updates or when we don't need to directly access the field. The first mode is more necessary when we need to perform some calc or logic.
172172

173-
## 3. Creating a `serializer` for each specific context
173+
### 3. Creating a `serializer` for each specific context
174174

175-
**If a `view` will not use all the fields from a model or you need to *serialize* an object within another `serializer`, and these fields require some effort to be *serialized*, it is worth creating a `serializer ` model-specific ` view `, using only what you will need.**
175+
If a `view` will not use all the fields from a model or you need to *serialize* an object within another `serializer`, and these fields require some effort to be *serialized*, it is worth creating a `serializer ` model-specific ` view `, using only what you will need.
176176

177-
### Example:
177+
**Example:**
178178

179179
```python
180180
class ProductSerializer(serializers.ModelSerializer):
@@ -223,4 +223,4 @@ class ComplexProductSerializer(serializers.ModelSerializer):
223223
]
224224
```
225225

226-
### `Product` contains several serializers with clearly defined objectives, it is noticeable that the last `(ComplexProductSerializer)` generates a high volume of data, making it less performant, so in a situation where I only need the basics, I can use an existing one or create a new one with the necessary fields.
226+
`Product` contains several serializers with clearly defined objectives, it is noticeable that the last `(ComplexProductSerializer)` generates a high volume of data, making it less performant, so in a situation where I only need the basics, I can use an existing one or create a new one with the necessary fields.

0 commit comments

Comments
 (0)